PDO和sqlite的一点体会

用php写了一个小工具,顺便体验了下PDO和sqlite,一个是php5自带的数据库层,一个是简易的文件型数据库,没什么章法,简单记录在这里。

  • 配合pdo使用,只用安装php5-sqlite即可,php5-sqlite3这个extension可能是单独的sqlite支持,就是类似mysql,有专门的sqlite_connect函数。
  • 系统中也可以安装单独的sqlite3(不带3的是sqlite2),采用类似mysql的shell方式管理库文件。
  • 通过PDO好像无法查询数据库的结构等信息,只能操作DML。
  • 不知道pdo使用sybase(dblib)的时候是否能在sql中使用limit,以及使用了是否有效,要到hardy 8.04 php5-sybase才支持pdo,到时候再试验。
  • Bug: rowCount()无法工作于pdo_sqlite数据库,其他一些函数也有小问题,官方文档的user comment中有说到。
  • PDO的exec方法可以一次执行多条sql,但不返回结果,而query则只能执行一条,返回结果信息。
  • 使用PDO的prepare和PDOStatement的execute不仅有助于加速同一sql不同参数的调用速度,还有助于防止sql注入攻击。
  • prepare的:name不能是表名,大概只能是where中的变值,prepare中的字符型:name不需要带上引号,这一点很方便。

总体感觉,PDO还没有AdoDb方便,大概是用熟了的感觉,但功能上的确要少一些。sqlite数据库表现不错,但由于数据类型、结构、功能相对简单,还是主要用在小型、简单一点的应用里更合适。

Update @ 2008-03-23

来一个使用PDO调sqlite库的例子:

try {
    $db = new PDO("sqlite:/path/to/db/file", null, null, array(PDO::ATTR_PERSISTENT => true));
} catch (PDOException $ex) {
    die("[Error] " . $ex->getMessage() . "\n");
}

// Useless but carefully is better, set encoding.
// Sqlite always use utf-8 internaly, UTF-8 is also it's default value.
$db->query('PRAGMA encoding = "UTF-8"');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Begin query
$stmt = $db->query("PRAGMA table_info({$tbl})");
// PHP bug: rowCount() not work with pdo_sqlite
if (0 == count($stmt->fetchAll())) {
    // Table not exists or have no columns
    ......

另外在使用ADODB的时候,它默认好像并不直接支持sqlite3,而是sqlite2(ADODB版本为V5.04 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com)),所以只能通过pdo来实现(即ADODB中使用的数据库类型为pdo),可pdo在这个版本的ADODB中支持也不是很全面,drivers目录下甚至没有adodb-pdo_sqlite.inc.php文件(网上搜了一下,这个文件似乎在某些地方有),所以,只能这样用了:

//ADODB设定
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;

try
{
    $conn = &ADONewConnection('pdo');
    @$conn->Connect('sqlite://path/to/db/file');
}
catch (Exception $e)
{
    adodb_backtrace($e->getTrace());
    exit();
}

// Check create table, adodb&sqlite3 not work very well, MetaTables() un-usable
//$rs = $conn->MetaTables();
$rs = $conn->Execute("SELECT name FROM sqlite_master WHERE type='table' AND name='my_table_name'");
if (1 > $rs->RecordCount())
{
    // Table does not exists
    ......

Connect前面的@如果去掉,会有Notice错误出现:

Notice: Undefined property:  ADODB_pdo_base::$_genIDSQL in /home/fwolf/dev/php_includes/adodb5/drivers/adodb-pdo.inc.php on line 106

Notice: Undefined property:  ADODB_pdo_base::$_dropSeqSQL in /home/fwolf/dev/php_includes/adodb5/drivers/adodb-pdo.inc.php on line 108

所以,只能说是ADODB对sqlite3的兼容性还不是很好。