【发布时间】:2016-07-04 13:51:33
【问题描述】:
在我最近的 SO 上瘾中,我意识到很多人继续使用 MySQL 原始驱动程序命令。
网上有很多很好的教程,但是有一个比较表可以帮助转换旧项目?
【问题讨论】:
在我最近的 SO 上瘾中,我意识到很多人继续使用 MySQL 原始驱动程序命令。
网上有很多很好的教程,但是有一个比较表可以帮助转换旧项目?
【问题讨论】:
简介:
此表并非旨在作为 PDO 的教程或指南,而是提供 MySQL_ 和 PDO 之间的对应关系。因此,如果没有 MySQL_ 对应关系,一些重要的 PDO 命令就会丢失。
在这些省略的命令中,有一个主要的 PDO 功能,prepared statements。我强烈建议使用它,即使仅在本指南中引用。
这是一个非常扩展的答案。我很抱歉拼写质量低(我不是英语)和错别字。我会在接下来的几天里尝试纠正和改进它。欢迎任何建议或贡献。
命名约定:
为避免误解,在此答案中我使用:
在 PDO 中,我们有两种主要的对象类型,PDOObject(PHP 和数据库服务器之间的连接)和 PDOStatement(准备好的语句,以及在语句执行后关联的结果集)。在这个答案中,变量名是:
$dbh,参考PDOobject;$stmt,请参阅 PDO 声明。
- mysql_connect - 打开与 MySQL 服务器的连接
- PDO::__construct - 创建一个表示与数据库的连接的 PDO 实例
MySQL_方式:
$con = mysql_connect( $dbHost, $dbUser, $dbPassword ) or die( mysql_error() );
PDO方式:
$dsn = "mysql:host={$dbHost};dbname={$dbName}";
$dbh = new PDO( $dsn, $dbUser, $dbPassword );
在 PDO 中,我们必须构造 Data Source Name 字符串 ($dsn),其中包括主机和数据库名称,然后我们可以使用定义的 DSN、用户名和用户密码。使用PDO我们直接在连接处选择数据库,不需要_select_db。
要在 PDO 中捕获错误,我们需要使用 try/catch 语法:
try
{
$dbh = new PDO( $dsn, $dbUser, $dbPassword );
}
catch( PDOException $exception )
{
echo $exception->getMessage();
}
- mysql_select_db - 选择一个 MySQL 数据库
- PDO::__construct - 创建一个表示与数据库的连接的 PDO 实例
MySQL_方式:
mysql_select_db( $dbName, [$con] ) or die( mysql_error() );
PDO方式:
/* See above, at mysql_connect vs PDO::__construct */
在 PDO 中,我们在连接命令中选择 DataBase。要更改它,我们必须打开一个新连接。
? 要在不同的数据库中执行查询而不创建新连接,在 PDO 中我们可以使用以下 MySQL 语法:
INSERT INTO databasename.tablename ...
SELECT FROM databasename.tablename ...
- mysql_query - 发送 MySQL 查询
- PDO::query - 执行 SQL 语句,将结果集作为 PDOStatement 对象返回
MySQL_方式:
$result = mysql_query( $query, [$dbh] ) or die( mysql_error() );
PDO方式:
$stmt = $dbh->query( $query ) or die( $dbh->errorInfo()[2] );
一个 PDO 查询返回一个 PDOStatement 对象。
? 通过 PDO,我们还可以使用 prepared statements,这是一种使用相同或不同参数多次执行查询、自动引用参数和防止 MySQL 注入的有用方法。
- mysql_fetch_row - 以枚举数组的形式获取结果行
- mysql_fetch_array - 以关联数组、数值数组或两者的形式获取结果行
- mysql_fetch_assoc - 获取结果行作为关联数组
- mysql_fetch_object - 获取结果行作为对象
- PDOStatement::fetch - 从结果集中获取下一行
- PDOStatement::fetchObject - 获取下一行并将其作为对象返回。
MySQL_方式:
$row = mysql_fetch_row( $result );
PDO方式:
$row = $stmt->fetch( PDO::FETCH_NUM );
要获取行,PDO 的命令比 MySQL_ 少,但它有越来越多的选项。默认情况下,以枚举而不是关联数组的形式获取结果(双倍结果),但指定获取模式(使用 PDO 常量)我们可以设置结果格式。
PDO 获取样式常量:
Constant Returned Format ··················· ································································· PDO::FETCH_ASSOC Associative array PDO::FETCH_BOTH Array indexed by both numeric and associative keys (default) PDO::FETCH_BOUND Boolean TRUE (and assigns columns values to variables to which they were bound with the PDOStatement::bindColumn() method) PDO::FETCH_LAZY combines PDO::FETCH_BOTH and PDO::FETCH_OBJ PDO::FETCH_NAMED same form as PDO::FETCH_ASSOC, but if there are multiple columns with same name, the value referred to by that key will be an array of all the values in the row that had that column name PDO::FETCH_NUM Enumerated array PDO::FETCH_OBJ Anonymous object with column names as property names也可用(请参阅Documentation 了解更多信息):
PDO::FETCH_CLASS、PDO::FETCH_INTO
我们可以使用常量作为->fetch() 命令的参数来设置获取方法(如上所示),或者直接在原始查询中设置默认获取方法:
$stmt = $dbh->query( $query, PDO::FETCH_OBJ ) or die( $dbh->errorInfo()[2] );
或者使用->setFetchMode()方法:
$stmt = $dbh->query( $query ) or die( $dbh->errorInfo()[2] );
$stmt->setFetchMode( PDO::FETCH_OBJ );
MySQL_/PDO Fetch 命令对比表:
MySQL_ PDO ································ ···················································· mysql_fetch_row $stmt->fetch( PDO::FETCH_NUM ); mysql_fetch_array $stmt->fetch( PDO::FETCH_BOTH ); mysql_fetch_assoc $stmt->fetch( PDO::FETCH_ASSOC ); mysql_fetch_object $stmt->fetch( PDO::FETCH_OBJ ); $stmt->fetchObject();
? 在 PDO 中,您还可以使用 ->fetchAll() 方法一次获取所有结果行:
$rows = $stmt->fetchAll(); /* Fetches all rows in FETCH_BOTH mode */
$rows = $stmt->fetchAll(PDO::FETCH_OBJ); /* Fetches all rows in FETCH_OBJ mode */
- mysql_num_rows - 获取结果中的行数
- mysql_affected_rows - 获取先前 MySQL 操作中受影响的行数
- PDOStatement::rowCount - 返回最后一条 SQL 语句影响的行数
MySQL_方式:
$totRows = mysql_num_rows( $result );
$totRows = affected_rows( $result );
PDO方式:
$totRows = $stmt->rowCount();
PDO使用单个命令返回总行数:在INSERT/UPDATE查询后使用时,返回受影响的行数,在SELECT查询后使用时,返回结果集中的行数。
- mysql_insert_id - 获取上次查询生成的 ID
- PDO::lastInsertId - 返回最后插入的行或序列值的 ID
MySQL_方式:
$id = mysql_insert_id()
PDO方式:
$id = $dbh->lastInsertId();
- mysql_result - 获取结果数据
- PDOStatement::fetchAll - 获取下一行并将其作为对象返回。
MySQL_方式:
$row = mysql_result( $result, $numRow );
$field = mysql_result( $result, $numRow, $numField );
PDO方式:
$rows = $stmt->fetchAll( FETCH_NUM );
$row = $rows[ $numRow ];
$field = $rows[ $numRow ][ $numField ];
此 MySQL_ 函数没有等效的 PDO。模拟mysql_result 的唯一方法是预取所有行,然后引用结果数组。当结果集中有很多行时,这不是一个好主意。
- mysql_escape_string - 转义字符串以在 mysql_query 中使用
- mysql_real_escape_string - 转义字符串中的特殊字符以在 SQL 语句中使用
- PDO::quote - 引用用于查询的字符串。
MySQL_方式:
$string = mysql_escape_string( $string );
PDO方式:
$string = $dbh->quote( $string );
PDO 的行为与 MySQL_ 的行为不同:
Original String MySQL_ Escaped String PDO Quoted String
················· ································ ································
Hello World Hello World 'Hello World'
'Hello World' \'Hello World\' '\'Hello World\''
"Hello World" \"Hello World\" '\"Hello World\"'
因此,在引用字符串之后,您必须在查询中使用它不带引号。即:
$string = $dbh->quote( '"Hello World"' );
$stmt = $dbh->query( "SELECT * FROM table WHERE field = $string" ) or die( $dbh->errorInfo()[2] );
? 考虑使用prepared statements,而不是引用字符串,这是一种有用的方法,可以使用相同或不同的参数多次执行查询,自动引用参数并防止 MySQL 注入。
- mysql_error - 返回先前 MySQL 操作的错误消息文本
- PDO::errorInfo - 获取与数据库句柄上的最后一个操作相关的扩展错误信息
- PDOStatement::errorInfo - 获取与语句句柄上的最后一个操作相关的扩展错误信息
MySQL_方式:
$errorMsg = mysql_error();
PDO方式:
$error = $dbh->errorInfo()[2];
$error = $stmt->errorInfo()[2];
PDO 和 PDOStatement ->errorInfo() 都返回一个具有这种形式的数组:
Key Value
······ ··············································································
0 SQLSTATE error code (a 5 characters identifier defined in the ANSI SQL std)
1 MySQL Driver specific error code
2 MySQL Driver specific error message
- mysql_errno - 返回之前 MySQL 操作的错误信息的数值
- PDO::errorCode - 获取与数据库句柄上的最后一个操作关联的 SQLSTATE
- PDOStatement::errorCode - 获取与语句句柄上的最后一个操作关联的 SQLSTATE
MySQL_方式:
$errorNum = mysql_errno();
PDO方式:
$errorNum = $dbh->errorCode();
$errorNum = $stmt->errorCode();
- mysql_close - 关闭 MySQL 连接
MySQL_方式:
mysql_close( $con );
PDO方式:
unset( $dbh );
此 MySQL_ 函数没有等效的 PDO。更分散的做法是什么都不做(php 本身在脚本末尾关闭连接)。或者,我们可以使用unset()。
以下命令是比较但不解释的。将来可以添加说明。
请不要参考此部分,直到此警报未被删除:
以下命令的等价性尚未经过测试,旨在作为草案。
- mysql_client_encoding - 返回字符集的名称
MySQL_方式:
$charSet = mysql_client_encoding();
PDO方式:
$stmt = $dbh->query( "SELECT COLLATION('foo')" );
来自“Get charset with mysql PDO”的解决方案
- mysql_create_db - 创建 MySQL 数据库
MySQL_方式:
$result = mysql_create_db( $databaseName );
PDO方式:
$result = $dbh->exec( "Create database {$databaseName}" );
- mysql_data_seek - 移动内部结果指针 [NT]
MySQL_方式:
mysql_data_seek( $result, $rowNumber );
$row = mysql_fetch_assoc( $result );
PDO方式:
$row = $stmt->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, $rowNumber );
来自“mysql_data_seek PDO equivalent”的解决方案
- mysql_db_name - 从对 mysql_list_dbs 的调用中检索数据库名称
MySQL_方式:
$result = mysql_list_dbs();
$dbName = mysql_db_name( $result, $numRow );
PDO方式:
$stmt = $dbh->query( "SHOW databases" );
$dbName = $stmt->fetchAll( PDO::FETCH_NUM )[$numRow][0];
- mysql_drop_db - 删除(删除)MySQL 数据库
MySQL_方式:
mysql_drop_db( $dbName ) or die( mysql_error() );
PDO方式:
$dbh->query( "DROP DATABASE $dbName" ) or die( $dbh->errorInfo()[2] );
- mysql_fetch_field - 从结果中获取列信息并作为对象返回
- PDOStatement::getColumnMeta - 返回结果集中列的元数据
MySQL_方式:
$meta = mysql_fetch_field( $result, $columnNum );
PDO方式:
$meta = (object) $stmt->getColumnMeta( $columnNum );
PDO 结果是一个关联数组,而不是 MySQL_ 返回的 Object。返回值也不同:
MySQL_ PDO Description
name name Column name
table table Name of the table the column belongs to (alias if one)
max_length len Maximum length of the column
not_null (use flags) 1 if the column cannot be NULL
primary_key (use flags) 1 if the column is a primary key
unique_key (use flags) 1 if the column is a unique key
multiple_key (use flags) 1 if the column is a non-unique key
numeric (use flags) 1 if the column is numeric
blob (use flags) 1 if the column is a BLOB
type native_type Column type / native_type: PHP native type
pdo_type Column tyoe as PDO::PARAM_* constants
unsigned (use flags) 1 if the column is unsigned
zerofill (use flags) 1 if the column is zero-filled
(various) flags Any flags set for this column
(no) precision Numeric precision of this column
- mysql_fetch_lengths - 获取结果中每个输出的长度
MySQL_方式:
$fieldLengths = mysql_fetch_lengths( $result );
PDO方式:
$row = $stmt->fetch( PDO::FETCH_NUM );
$fieldLengths = array_map( 'strlen', $row );
- mysql_field_flags - 获取结果中与指定字段关联的标志
MySQL_方式:
$fieldFlags = mysql_field_flags( $result, $columnNum );
PDO方式:
$fieldFlags = implode( ' ', $stmt->getColumnMeta( $columnNum )['flags'] );
注意:根据我的测试,PDO 不返回“auto_increment”标志(待验证)。
- mysql_field_len - 返回指定字段的长度
MySQL_方式:
$fieldLen = mysql_field_len( $result, $columnNum );
PDO方式:
$fieldFlags = $stmt->getColumnMeta( $columnNum )['len'];
- mysql_field_name - 获取结果中指定字段的名称
MySQL_方式:
$fieldName = mysql_field_name( $result, $columnNum );
PDO方式:
$fieldName = $stmt->getColumnMeta( $columnNum )['name'];
- mysql_field_seek - 将结果指针设置为指定的字段偏移量
MySQL_方式:
mysql_field_seek( $result, $columnNum );
PDO方式:
...
- mysql_field_table - 获取指定字段所在的表名
MySQL_方式:
$tableName = mysql_field_table( $result, $columnNum );
PDO方式:
$tableName = $stmt->getColumnMeta( $columnNum )['table'];
- mysql_field_type - 获取结果中指定字段的类型
MySQL_方式:
$fieldType = mysql_field_type( $result, $columnNum );
PDO方式:
$fieldType = $stmt->getColumnMeta( $columnNum )['table'];
注意:PDO 的语法与 MySQL_ 不同(即“INT24”与“int”、“VAR_STRING”与“string”)。
- mysql_free_result - 释放结果内存
- PDOStatement::closeCursor - 关闭游标,使语句能够再次执行。
MySQL_方式:
mysql_free_result( $result );
PDO方式:
$stmt->closeCursor();
注意:在这个答案中是临时关联的,但是这两个命令的作用不同。
- mysql_get_client_info - 获取 MySQL 客户端信息
- PDO::getAttribute - 检索数据库连接属性
MySQL_方式:
$clientInfo = mysql_get_client_info();
PDO方式:
$clientInfo = $dbh->getAttribute( PDO::ATTR_CLIENT_VERSION );
- mysql_get_host_info - 获取 MySQL 主机信息
- PDO::getAttribute - 检索数据库连接属性
MySQL_方式:
$hostInfo = mysql_get_host_info();
PDO方式:
$hostInfo = $dbh->getAttribute( PDO::ATTR_CONNECTION_STATUS );
- mysql_get_proto_info - 获取 MySQL 协议信息
MySQL_方式:
$protocolInfo = mysql_get_proto_info();
PDO方式:
...
- mysql_get_server_info - 获取 MySQL 服务器信息
- PDO::getAttribute - 检索数据库连接属性
MySQL_方式:
$serverVersion = mysql_get_server_info();
PDO方式:
$serverVersion = $dbh->getAttribute( PDO::ATTR_SERVER_VERSION );
- mysql_info - 获取有关最近查询的信息
MySQL_方式:
$lastQueryInfo = mysql_info();
PDO方式:
...
- mysql_list_dbs - 列出 MySQL 服务器上可用的数据库
MySQL_方式:
$result = mysql_list_dbs();
PDO方式:
$stmt = $dbh->query( "SHOW databases" );
$array = array_column( $stmt->fetchAll( PDO::FETCH_NUM ), 0 );
- mysql_list_fields - 列出 MySQL 表字段
MySQL_方式:
$listFields = mysql_list_fields( $dbName, $tableName );
PDO方式:
...
- mysql_list_processes - 列出 MySQL 进程
MySQL_方式:
$processes = mysql_list_processes();
PDO方式:
...
- mysql_list_tables - 列出 MySQL 数据库中的表
MySQL_方式:
$tableList = mysql_list_tables( $sbName );
PDO方式:
$tableList = $dbh->query( "SHOW TABLES FROM $dbName" );
- mysql_num_fields - 获取结果中的字段数
- PDOStatement::columnCount - 返回结果集中的列数
MySQL_方式:
$columnCount = mysql_num_fields( $result );
PDO方式:
$columnCount = $dbh->columnCount();
- mysql_pconnect - 打开与 MySQL 服务器的持久连接
MySQL_方式:
$con = mysql_pconnect( $dbHost, $dbUser, $dbPassword ) or die( mysql_error() );
PDO方式:
...
- mysql_ping - ping 服务器连接,如果没有连接则重新连接
MySQL_方式:
mysql_ping() or die( 'Lost MySQL Connection' );
PDO方式:
...
- mysql_set_charset - 设置客户端字符集
MySQL_方式:
mysql_set_charset( $charSet );
PDO方式:
/* At Connection Start: */
$dsn = "mysql:host={$dbHost};dbname={$dbName};charset={$charSet}";
$dbh = new PDO( $dsn, $dbUser, $dbPassword );
- mysql_stat - 获取当前系统状态
- PDO::getAttribute - 检索数据库连接属性
MySQL_方式:
$serverInfo = mysql_stat();
PDO方式:
$serverInfo = $dbh->getAttribute( PDO::ATTR_SERVER_INFO );
- mysql_tablename - 获取字段的表名
MySQL_方式:
$result = mysql_list_tables( $dbName );
$tableName = mysql_tablename( $result, $tableNum );
PDO方式:
$stmt = $dbh->query( "SHOW TABLES FROM test" )->fetchAll(PDO::FETCH_NUM);
$tableName = $stmt[1][0];
- mysql_thread_id - 返回当前线程 ID
MySQL_方式:
$threadId = mysql_thread_id();
PDO方式:
$threadId = $dbh->query( "SELECT CONNECTION_ID()" )->fetch()[0];
来自“Get PDO connection ID”的解决方案
- mysql_unbuffered_query - 向 MySQL 发送 SQL 查询,而不获取和缓冲结果行
- PDO::setAttribute - 设置语句属性
MySQL_方式:
$result = mysql_unbuffered_query( $query );
PDO方式:
$dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, False );
PDO::setAttribute — 设置属性
PDOStatement::bindColumn - 将列绑定到 PHP 变量
【讨论】:
mysql_list_processes - “PDO 版本”将直接为 SELECT PROCESSLIST。使用 FULL 获取查询详情:SELECT FULL PROCESSLIST