php_mysql、php_mysqli 与 pdo_mysql 的区别与选择
2012-10-05 18:50
811 查看
本文最后更新时间:2014-9-28
结论:
使用pdo、自动化SQL(db-sql-maker-php)、查询用PDO::query()、格式化用PDOStatement::fetchAll()。
php代码的可移植性——从mysql迁移到其他数据库(比如pgsql)时,php代码不用修改:
风格:
使用php_mysql、php_mysqli 还是 pdo?
官方文档:http://cn.php.net/manual/zh/mysqli.overview.php
php_mysql已经废弃,不再讨论。
从风格上看:
php_mysqli 可以oop,却不支持抛异常……这能算oop么……函数名使用下划线也不符合现在的书写规范。
所以使用PDO——简洁。
从可移植性上看:
如果是私有项目,只用mysql,以后绝对不会迁移到其他数据库,则可以使用php_mysqli。但前公司因为性能从jsp迁移到php,谁能保证以后不会换数据库呢?
如果是开源项目或者会被其他站长使用的项目,建议使用pdo。因为用pdo的函数操作数据库,与mysql还是pgsql无关。这样其他站长可以使用其他数据库。
pdo与php_mysqli的区别是:pdo提供通用的功能,这样才能支持各个不同的数据库,所以无法支持mysql特有的功能,比如多语句执行。但考虑到一般用不到特殊功能,所以影响不大。
pdo代码:
可以看出,使用pdo,如果数据库从mysql迁移到pgsql,只需要改dsn,而sql语法不同可以通过SQL Maker来自动生成。
注:PDO的出现是为了可移植,却把一个简单的dsn连接数据库做的都不一样,直接破坏了可移植性……让人很怀疑PDO的成熟度……
而如果使用php_mysqli,是无法迁移到php_pgsql的,因为函数完全不同。如下:
php_mysqli 与 pdo 性能对比:
todo
PDO使用说明:
PDO::prepare()
官方文档:http://www.php.net/manual/zh/pdo.prepare.php
适用:多次查询使用相同的条件字段和结果字段。这时候比PDO::query()性能高。
转义:value无需手动转义,PDO会自动进行转义,不用担心SQL注入。(开启query log可以看到语句的确已转义)
缺点:由于标识符(列名表名)是手写的SQL,要自己加引用符反勾号`。
PDO::prepare()模拟处理的时候不会通过数据库,所以不知道语法错误,不会返回错误或抛异常。什么时候是真处理,什么时候是模拟处理,官方手册中未找到说明。输入任意的SQL都不出错……所以目前不要指望prepare返回错误,PDOStatement::execute()时才会返回错误。http://www.php.net/manual/zh/pdo.prepare.php
PDO::query()
官方文档:http://www.php.net/manual/zh/pdo.query.php
适用:单次查询的语句。
PDOStatement::setFetchMode()
http://www.php.net/manual/zh/pdostatement.setfetchmode.php
http://www.php.net/manual/zh/pdo.constants.php
View Code
结果:
PDOStatement::fetch() 逐行读取
官方文档:http://www.php.net/manual/zh/pdostatement.fetch.php
PDOStatement::fetchAll() 格式化成:一个大数组
官方文档:http://www.php.net/manual/zh/pdostatement.fetchall.php
PDOStatement::fetchObject() 逐行读取,等于 PDOStatement::fetch() with PDO::FETCH_CLASS or PDO::FETCH_OBJ style。
官方文档:http://www.php.net/manual/zh/pdostatement.fetchobject.php
又是alias……这不是添乱吗!
注意:
PDO::errorCode()只返回数据库连接错误。PDOStatement::errorCode()返回sql执行错误。
官方文档:http://www.php.net/manual/zh/pdostatement.errorcode.php
参考资料:
http://board.phpbuilder.com/showthread.php?10379869-RESOLVED-PDO-prepare-can-anyone-suggest-query-prepare-statement-that-throws-exception
结论:
使用pdo、自动化SQL(db-sql-maker-php)、查询用PDO::query()、格式化用PDOStatement::fetchAll()。
php代码的可移植性——从mysql迁移到其他数据库(比如pgsql)时,php代码不用修改:
使用自动化SQL | 结果:php代码是否可移植 | |
php_mysqli | 是 | 否 |
php_mysqli | 否 | 否 |
pdo | 是 | 是 |
pdo | 否 | 否 |
书写风格 | 面向对象 | 抛异常 | |
php_mysqli | 函数名用下划线,比如fetch_all | 可以oop,也可以opp | 否,只能false |
pdo | 函数名用驼峰,比如fetchAll | oop | 可以throw,也可false或false加warnnig |
php_pgsql | 函数名用下划线,比如pg_fetch_all | opp | 否,只能false |
官方文档:http://cn.php.net/manual/zh/mysqli.overview.php
php_mysql已经废弃,不再讨论。
从风格上看:
php_mysqli 可以oop,却不支持抛异常……这能算oop么……函数名使用下划线也不符合现在的书写规范。
所以使用PDO——简洁。
从可移植性上看:
如果是私有项目,只用mysql,以后绝对不会迁移到其他数据库,则可以使用php_mysqli。但前公司因为性能从jsp迁移到php,谁能保证以后不会换数据库呢?
如果是开源项目或者会被其他站长使用的项目,建议使用pdo。因为用pdo的函数操作数据库,与mysql还是pgsql无关。这样其他站长可以使用其他数据库。
pdo与php_mysqli的区别是:pdo提供通用的功能,这样才能支持各个不同的数据库,所以无法支持mysql特有的功能,比如多语句执行。但考虑到一般用不到特殊功能,所以影响不大。
pdo代码:
<?php $dsn = 'mysql:dbname=test;host=localhost'; //mysql $user = 'root'; //mysql $password = '1'; //mysql $db = new PDO($dsn, $user, $password); //mysql $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = 'INSERT INTO `user` (`id`, `name`, `desc`) VALUES (\'2\',\'lucy\',\'hello\');'; //mysql $dsn = 'pgsql:host=localhost;port=5432;dbname=test;user=root;password=1'; //pgsql $db = new PDO($dsn); //pgsql $sql = 'INSERT INTO schema1.user ("id", "name", "desc") VALUES (\'2\',\'lucy\',\'hello\');'; //pgsql $stmt = $db->query($sql); //这以下mysql和pgsql是一样的了 $stmt->setFetchMode(PDO::FETCH_ASSOC); $r = $stmt->fetchAll(); ?>
可以看出,使用pdo,如果数据库从mysql迁移到pgsql,只需要改dsn,而sql语法不同可以通过SQL Maker来自动生成。
注:PDO的出现是为了可移植,却把一个简单的dsn连接数据库做的都不一样,直接破坏了可移植性……让人很怀疑PDO的成熟度……
而如果使用php_mysqli,是无法迁移到php_pgsql的,因为函数完全不同。如下:
<?php $mysqli = new mysqli('localhost', 'root', '1', 'test'); //$a = "hello world\fjim\n\r"; //$sql = 'INSERT INTO `user` (`id`, `name`, `desc`) VALUES (\'2\',\'lucy\',' . $mysqli->real_escape_string($a) . '\');'; $sql = 'SELECT `id`, `name`, `desc` FROM `user` LIMIT 2'; $r = $mysqli->query($sql); $arr = $r->fetch_all(); var_dump($arr); exit; ?> <?php $db = pg_connect("host=localhost port=5432 dbname=test user=root password=1"); //$a = "hello world\fjim\n\r"; //$sql = "INSERT INTO schema1.user VALUES ('2','lucy','". pg_escape_string($a) . '\');'; $sql = 'SELECT "id", "name", "desc" FROM schema1.user LIMIT 2'; $r = pg_query($db, $sql); $arr = pg_fetch_all($r); var_dump($arr); exit; ?>
php_mysqli 与 pdo 性能对比:
todo
PDO使用说明:
PDO::prepare()
官方文档:http://www.php.net/manual/zh/pdo.prepare.php
适用:多次查询使用相同的条件字段和结果字段。这时候比PDO::query()性能高。
转义:value无需手动转义,PDO会自动进行转义,不用担心SQL注入。(开启query log可以看到语句的确已转义)
缺点:由于标识符(列名表名)是手写的SQL,要自己加引用符反勾号`。
PDO::prepare()模拟处理的时候不会通过数据库,所以不知道语法错误,不会返回错误或抛异常。什么时候是真处理,什么时候是模拟处理,官方手册中未找到说明。输入任意的SQL都不出错……所以目前不要指望prepare返回错误,PDOStatement::execute()时才会返回错误。http://www.php.net/manual/zh/pdo.prepare.php
PDO::query()
官方文档:http://www.php.net/manual/zh/pdo.query.php
适用:单次查询的语句。
PDOStatement::setFetchMode()
http://www.php.net/manual/zh/pdostatement.setfetchmode.php
http://www.php.net/manual/zh/pdo.constants.php
View Code
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = '1'; $dbh = new PDO($dsn, $user, $password); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $dbh->query('SELECT `id`,`name` FROM user'); $stmt->setFetchMode(PDO::FETCH_KEY_PAIR); $r = $stmt->fetchAll(); var_dump($r); ?>
结果:
array(3) { [1]=> string(3) "jim" [2]=> string(4) "lucy" [3]=> string(2) "mm" }
PDOStatement::fetch() 逐行读取
官方文档:http://www.php.net/manual/zh/pdostatement.fetch.php
PDOStatement::fetchAll() 格式化成:一个大数组
官方文档:http://www.php.net/manual/zh/pdostatement.fetchall.php
PDOStatement::fetchObject() 逐行读取,等于 PDOStatement::fetch() with PDO::FETCH_CLASS or PDO::FETCH_OBJ style。
官方文档:http://www.php.net/manual/zh/pdostatement.fetchobject.php
又是alias……这不是添乱吗!
注意:
PDO::errorCode()只返回数据库连接错误。PDOStatement::errorCode()返回sql执行错误。
官方文档:http://www.php.net/manual/zh/pdostatement.errorcode.php
参考资料:
http://board.phpbuilder.com/showthread.php?10379869-RESOLVED-PDO-prepare-can-anyone-suggest-query-prepare-statement-that-throws-exception
相关文章推荐
- php_mysql、php_mysqli 与 pdo_mysql 的区别与选择
- php_mysql、php_mysqli 与 pdo_mysql 的区别与选择
- php_mysql、php_mysqli 与 pdo_mysql 的区别与选择
- php中mysql和mysqli 还有PDO关系区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PDO和MySQLi , MySQL区别与选择?
- php连接到MySQL数据库服务器时三种主要的API:mysql,mysqli,pdo区别及联系
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别【原创】
- mysqli、pdo_mysql和mysql之间的区别以及选择
- PHP连接Mysql常用API(mysql,mysqli,pdo)区别与联系
- php中三种处理mysql数据库的扩展库(mysql、mysqli、pdo)的区别?
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- PHP中MySQL、MySQLi和PDO的用法和区别
- php连接到MySQL数据库服务器时三种主要的API:mysql,mysqli,pdo区别及联系