【问题标题】:MySQL_ to PDO comparison tableMySQL 到 PDO 比较表
【发布时间】:2016-07-04 13:51:33
【问题描述】:

在我最近的 SO 上瘾中,我意识到很多人继续使用 MySQL 原始驱动程序命令。

网上有很多很好的教程,但是有一个比较表可以帮助转换旧项目?

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    MySQL_PDO对比表的原始驱动

    简介:

    此表并非旨在作为 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_CLASSPDO::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_方式:

    $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_方式:

    $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_方式:

    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_方式:

    $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 / PDOStatement 命令:

    【讨论】:

    • 耶稣...很好的答案
    • 在 21 分钟内输入了相当多的内容。
    • @DanAbrey 是的,其实我已经筋疲力尽了……:P
    • mysql_list_processes - “PDO 版本”将直接为 SELECT PROCESSLIST。使用 FULL 获取查询详情:SELECT FULL PROCESSLIST
    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 2012-06-21
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多