query - php mysql配置




为什么我不应该在PHP中使用mysql_*函数? (10)

便于使用

已经提到了分析和综合原因。 对于新手来说,停止使用过时的mysql_函数是一个更重要的动机。

当代数据库API 更易于使用。

它主要是可以简化代码的绑定参数 。 通过share ,向PDO的过渡并非过分艰巨。

一次重写更大的代码库需要时间。 Raison d'être为这个中间选择:

等效的pdo_ *函数代替mysql_ *

使用<pdo_mysql.php>您可以轻松地从旧的mysql_函数切换。 它添加了pdo_函数包装器来替换它们的mysql_副本。

  1. 只需include_once( <pdo_mysql.php> ); 在每个必须与数据库交互的调用脚本中。

  2. 任何地方删除mysql_函数前缀并将其替换为pdo_

    • mysql_ connect()成为pdo_ connect()
    • mysql_ query()成为pdo_ query()
    • mysql_ num_rows()变为pdo_ num_rows()
    • mysql_ insert_id()变成insert_id()
    • mysql_ fetch_array()成为pdo_ fetch_array()
    • mysql_ fetch_assoc()成为pdo_ fetch_assoc()
    • mysql_ real_escape_string()成为pdo_ real_escape_string()
    • 等等...

  3. 您的代码将起作用,但大多数看起来仍然相同:

    include_once("pdo_mysql.php"); 
    
    pdo_connect("localhost", "usrABC", "pw1234567");
    pdo_select_db("test");
    
    $result = pdo_query("SELECT title, html FROM pages");  
    
    while ($row = pdo_fetch_assoc($result)) {
        print "$row[title] - $row[html]";
    }
    

Etvoilà。
您的代码正在使用 PDO。
现在是时候实际利用它了。

绑定参数可以很容易使用

你只需要一个不那么笨拙的API。

pdo_query()为绑定参数添加了非常容易的支持。 转换旧代码很简单:

将变量移出SQL字符串。

  • 将它们作为逗号分隔的函数参数添加到pdo_query()
  • 问号? 作为变量之前的占位符。
  • 摆脱以前包含字符串值/变量的'单引号。

对于更长的代码,优势变得更加明显。

通常,字符串变量不仅仅插入到SQL中,而是与之间的转义调用连接起来。

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title='" . pdo_real_escape_string($title) . "' OR id='".
   pdo_real_escape_string($title) . "' AND user <> '" .
   pdo_real_escape_string($root) . "' ORDER BY date")

? 应用占位符你不必为此烦恼:

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title=? OR id=? AND user<>? ORDER BY date", $title, $id, $root)

请记住,pdo_ *仍然允许或者
只是不要转义变量并将其绑定在同一个查询中。

  • 占位符功能由其后面的真实PDO提供。
  • 因此也允许:named稍后:named占位符列表。

更重要的是,您可以在任何查询后安全地传递$ _REQUEST []变量。 当提交的<form>字段与数据库结构完全匹配时,它甚至更短:

pdo_query("INSERT INTO pages VALUES (?,?,?,?,?)", $_POST);

这么简单。 但是,让我们回到一些更多的重写建议和技术原因,为什么你可能想要摆脱mysql_和逃避。

修复或删除任何oldschool sanitize()函数

将所有mysql_调用转换为带有绑定参数的pdo_query ,删除所有冗余的pdo_real_escape_string调用。

特别是你应该修改任何sanitizecleanfilterThisclean_data函数,如日期教程以一种形式或另一种形式所宣传:

function sanitize($str) {
   return trim(strip_tags(htmlentities(pdo_real_escape_string($str))));
}

这里最明显的错误是缺乏文档。 更重要的是,过滤顺序完全错误。

  • 正确的顺序是:不赞成使用stripslashes作为最里面的调用,然后trim ,然后使用strip_tags ,输出上下文的htmlentities ,最后只有_escape_string作为其应用程序应该直接在SQL _escape_string

  • 但是第一步就是摆脱_real_escape_string调用。

  • 如果您的数据库和应用程序流期望HTML上下文安全的字符串,您可能必须暂时保留其余的sanitize()函数。 添加一条注释,它仅适用于今后的HTML转义。

  • 字符串/值处理委托给PDO及其参数化语句。

  • 如果在您的清理功能中提到了stripslashes() ,则可能表示更高级别的疏忽。

    关于magic_quotes的历史记录。 该功能已被正确弃用。 然而,它经常被错误地描述为失败的安全功能。 但是magic_quotes也是一个失败的安全功能,因为网球作为营养来源失败了。 这根本不是他们的目的。

    PHP2 / FI中的原始实现明确地引入了它,只是“ 引号将被自动转义,从而更容易将表单数据直接传递给msql查询 ”。 值得注意的是,与mSQL一起使用是非常安全的,因为它只支持ASCII。
    然后PHP3 / Zend为MySQL重新引入了magic_quotes并错误地记录了它。 但最初它只是一个便利功能 ,不打算安全。

准备好的陈述有何不同

当您将字符串变量加密到SQL查询中时,它不会让您更加复杂。 MySQL再次分离代码和数据也是一项无关紧要的工作。

SQL注入只是在数据流入代码上下文时。 数据库服务器以后不能发现PHP最初在查询子句之间粘合变量的位置。

使用绑定参数,可以在PHP代码中分隔SQL代码和SQL上下文值。 但它不会在幕后再次混乱(除了PDO :: EMULATE_PREPARES)。 您的数据库接收未变量的SQL命令和1:1变量值。

虽然这个答案强调你应该关心删除mysql_的可读性优势。 由于这种可见和技术数据/代码分离,偶尔也会有性能优势(重复INSERT只有不同的值)。

请注意,参数绑定仍然不是针对所有 SQL注入的神奇的一站式解决方案。 它处理数据/值的最常见用途。 但是不能将列名称/表标识符列入白名单,有助于动态子句构造,或者只是简单的数组值列表。

混合PDO使用

这些pdo_*包装函数构成了一个编码友好的止损API。 (如果不是特殊功能签名转换,那么MYSQLI几乎就是MYSQLI )。 它们在大多数时候也暴露了真正的PDO。
重写不必停止使用新的pdo_函数名称。 您可以逐个将每个pdo_query()转换为普通的$ pdo-> prepare() - > execute()调用。

不过,最好再次开始简化。 例如,获取的常见结果:

$result = pdo_query("SELECT * FROM tbl");
while ($row = pdo_fetch_assoc($result)) {

可以只用foreach迭代替换:

foreach ($result as $row) {

或者更好的是直接和完整的数组检索:

$result->fetchAll();

在大多数情况下,您将获得比PDO或mysql_通常在查询失败后提供的更有用的警告。

其他选择

所以这有希望可视化一些实际的原因和一个值得mysql_途径。

只是切换到pdo并没有完全削减它。 pdo_query()也只是它的前端。

除非你还引入参数绑定或者可以利用更好的API中的其他内容,否则它是一个毫无意义的开关。 我希望它的描述足够简单,不会进一步阻碍新人的沮丧。 (教育通常比禁止更好。)

虽然它有资格获得最简单的可能工作类别,但它仍然是非常实验性的代码。 我只是在周末写的。 然而,有许多替代品。 只需google进行PHP数据库抽象并稍微浏览一下。 对于这样的任务,总会有很多优秀的库。

如果您想进一步简化数据库交互,像Paris/Idiorm这样的映射器值得一试。 就像没有人再使用JavaScript中的平淡DOM一样,你现在不必保持原始的数据库接口。

为什么不应该使用mysql_*函数的技术原因是什么? (例如mysql_query()mysql_connect()mysql_real_escape_string() )?

即使他们在我的网站上工作,为什么还要使用别的东西?

如果他们不在我的网站上工作,为什么我会收到错误

警告:mysql_connect():没有这样的文件或目录


MySQL扩展:

  • 不是在积极发展
  • 自PHP 5.5(2013年6月发布)起正式deprecated
  • 完全removed PHP 7.0(2015年12月发布)
    • 这意味着自2018年12月31日起 ,它将不存在于任何受支持的PHP版本中。 目前,它只获得安全更新。
  • 缺少OO界面
  • 不支持:
    • 非阻塞,异步查询
    • 准备语句或参数化查询
    • 存储过程
    • 多个陈述
    • 交易
    • “新”密码验证方法(MySQL 5.6中默认启用; 5.7中要求)
    • MySQL 5.1中的所有功能

由于它已被弃用,因此使用它会使您的代码不再适用于未来。

缺乏对预准备语句的支持尤其重要,因为它们提供了一种更清晰,更不易出错的转义和引用外部数据的方法,而不是通过单独的函数调用手动转义它。

请参阅SQL扩展的比较


不推荐使用mysql_ *函数(从PHP 5.5开始),因为开发了更好的函数和代码结构。该功能被弃用的事实意味着不再需要在性能和安全性方面进行改进,这意味着它不太适合未来

如果您需要更多理由:

  • mysql_ *函数不支持预处理语句。
  • mysql_ *函数不支持绑定参数。
  • mysql_ *函数缺乏面向对象编程的功能。
  • 这个清单继续......

我觉得上面的答案真的很冗长,总结一下:

mysqli扩展有许多好处,对mysql扩展的关键改进是:

  • 面向对象的接口
  • 支持准备好的陈述
  • 支持多种语句
  • 支持交易
  • 增强的调试功能
  • 嵌入式服务器支持

来源:MySQLi概述

正如上面的答案所解释的,mysql的替代品是mysqli和PDO(PHP数据对象)。

  • API支持服务器端准备语句:由MYSQLi和PDO支持
  • API支持客户端准备语句:仅由PDO支持
  • API支持存储过程:MySQLi和PDO
  • API支持多种语句和所有MySQL 4.1+功能 - 由MySQLi支持,主要由PDO支持

MySQLi和PDO都是在PHP 5.0中引入的,而MySQL则是在PHP 3.0之前引入的。值得注意的是,MySQL已包含在PHP5.x中,但在以后的版本中已弃用。


首先,让我们从我们给大家的标准评论开始:

share 。 它们不再维护, deprecated 。 看到红色的盒子 ? 转而学习预备语句 ,并使用PDOMySQLi - 本文将帮助您确定哪些。 如果您选择PDO, 这是一个很好的教程

让我们逐句逐句解释:

  • 它们不再维护,并且已被正式弃用

    这意味着PHP社区正在逐渐放弃对这些非常旧的功能的支持。 它们很可能不存在于PHP的未来(最新)版本中! 继续使用这些函数可能会破坏(不是那么)远期的代码。

    新! - deprecated ext / mysql现已deprecated

    较新的! 在PHP 7中删除了 ext / mysql。

  • 相反,你应该学习准备好的陈述

    mysql_*扩展不支持预处理语句 ,这是(除其他外)一个非常有效的SQL注入对策。 它修复了MySQL依赖应用程序中的一个非常严重的漏洞,它允许攻击者访问您的脚本并对您的数据库执行任何可能的查询

    有关更多信息,请参阅如何在PHP中阻止SQL注入?

  • 看红盒子?

    当你进入任何mysql函数手册页时,你会看到一个红色框,解释它不应再被使用了。

  • 使用PDO或MySQLi

    有更好,更强大和精心构建的替代品, PDO ,提供完整的OOP方法进行数据库交互,以及MySQLi ,这是MySQL特定的改进。


MySQL扩展是三者中最老的,是开发人员用来与MySQL通信的原始方式。由于PHP和MySQL的新版本都有所改进,因此现在不deprecated此扩展以支持其他mysqli_ PDO

  • mysqli_是用于处理MySQL数据库的“改进”扩展。它利用了较新版本的MySQL服务器中提供的功能,向开发人员公开了面向功能的界面和面向对象的界面,并且做了一些其他很好的事情。

  • PDO提供了一个API,它整合了以前分布在主要数据库访问扩展中的大部分功能,即MySQL,PostgreSQL,SQLite,MSSQL等。该接口公开了高级对象,程序员可以使用数据库连接,查询和结果集,低级驱动程序与数据库服务器执行通信和资源处理。许多讨论和工作正在进入PDO,它被认为是在现代专业代码中使用数据库的适当方法。


可以mysql_*使用mysqli或PDO 定义几乎所有函数。只需将它们包含在旧的PHP应用程序之上,它就可以在PHP7上运行。我的解决方案here

<?php

define('MYSQL_LINK', 'dbl');
$GLOBALS[MYSQL_LINK] = null;

function mysql_link($link=null) {
    return ($link === null) ? $GLOBALS[MYSQL_LINK] : $link;
}

function mysql_connect($host, $user, $pass) {
    $GLOBALS[MYSQL_LINK] = mysqli_connect($host, $user, $pass);
    return $GLOBALS[MYSQL_LINK];
}

function mysql_pconnect($host, $user, $pass) {
    return mysql_connect($host, $user, $pass);
}

function mysql_select_db($db, $link=null) {
    $link = mysql_link($link);
    return mysqli_select_db($link, $db);
}

function mysql_close($link=null) {
    $link = mysql_link($link);
    return mysqli_close($link);
}

function mysql_error($link=null) {
    $link = mysql_link($link);
    return mysqli_error($link);
}

function mysql_errno($link=null) {
    $link = mysql_link($link);
    return mysqli_errno($link);
}

function mysql_ping($link=null) {
    $link = mysql_link($link);
    return mysqli_ping($link);
}

function mysql_stat($link=null) {
    $link = mysql_link($link);
    return mysqli_stat($link);
}

function mysql_affected_rows($link=null) {
    $link = mysql_link($link);
    return mysqli_affected_rows($link);
}

function mysql_client_encoding($link=null) {
    $link = mysql_link($link);
    return mysqli_character_set_name($link);
}

function mysql_thread_id($link=null) {
    $link = mysql_link($link);
    return mysqli_thread_id($link);
}

function mysql_escape_string($string) {
    return mysql_real_escape_string($string);
}

function mysql_real_escape_string($string, $link=null) {
    $link = mysql_link($link);
    return mysqli_real_escape_string($link, $string);
}

function mysql_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql);
}

function mysql_unbuffered_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql, MYSQLI_USE_RESULT);
}

function mysql_set_charset($charset, $link=null){
    $link = mysql_link($link);
    return mysqli_set_charset($link, $charset);
}

function mysql_get_host_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_host_info($link);
}

function mysql_get_proto_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_proto_info($link);
}
function mysql_get_server_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_server_info($link);
}

function mysql_info($link=null) {
    $link = mysql_link($link);
    return mysqli_info($link);
}

function mysql_get_client_info() {
    $link = mysql_link();
    return mysqli_get_client_info($link);
}

function mysql_create_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "CREATE DATABASE `$db`");
}

function mysql_drop_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "DROP DATABASE `$db`");
}

function mysql_list_dbs($link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, "SHOW DATABASES");
}

function mysql_list_fields($db, $table, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    $table = str_replace('`', '', mysqli_real_escape_string($link, $table));
    return mysqli_query($link, "SHOW COLUMNS FROM `$db`.`$table`");
}

function mysql_list_tables($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "SHOW TABLES FROM `$db`");
}

function mysql_db_query($db, $sql, $link=null) {
    $link = mysql_link($link);
    mysqli_select_db($link, $db);
    return mysqli_query($link, $sql);
}

function mysql_fetch_row($qlink) {
    return mysqli_fetch_row($qlink);
}

function mysql_fetch_assoc($qlink) {
    return mysqli_fetch_assoc($qlink);
}

function mysql_fetch_array($qlink, $result=MYSQLI_BOTH) {
    return mysqli_fetch_array($qlink, $result);
}

function mysql_fetch_lengths($qlink) {
    return mysqli_fetch_lengths($qlink);
}

function mysql_insert_id($qlink) {
    return mysqli_insert_id($qlink);
}

function mysql_num_rows($qlink) {
    return mysqli_num_rows($qlink);
}

function mysql_num_fields($qlink) {
    return mysqli_num_fields($qlink);
}

function mysql_data_seek($qlink, $row) {
    return mysqli_data_seek($qlink, $row);
}

function mysql_field_seek($qlink, $offset) {
    return mysqli_field_seek($qlink, $offset);
}

function mysql_fetch_object($qlink, $class="stdClass", array $params=null) {
    return ($params === null)
        ? mysqli_fetch_object($qlink, $class)
        : mysqli_fetch_object($qlink, $class, $params);
}

function mysql_db_name($qlink, $row, $field='Database') {
    mysqli_data_seek($qlink, $row);
    $db = mysqli_fetch_assoc($qlink);
    return $db[$field];
}

function mysql_fetch_field($qlink, $offset=null) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    return mysqli_fetch_field($qlink);
}

function mysql_result($qlink, $offset, $field=0) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    $row = mysqli_fetch_array($qlink);
    return (!is_array($row) || !isset($row[$field]))
        ? false
        : $row[$field];
}

function mysql_field_len($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->length : false;
}

function mysql_field_name($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgname) ? $field->name : $field->orgname;
}

function mysql_field_table($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgtable) ? $field->table : $field->orgtable;
}

function mysql_field_type($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->type : false;
}

function mysql_free_result($qlink) {
    try {
        mysqli_free_result($qlink);
    } catch (Exception $e) {
        return false;
    }
    return true;
}

因为(除其他原因外)确保输入数据被消毒要困难得多。如果您使用参数化查询,就像使用PDO或mysqli一样,您可以完全避免风险。

例如,有人可以用作用"enhzflep); drop table users"户名。旧函数将允许每个查询执行多个语句,因此类似讨厌的bugger可以删除整个表。

如果一个人使用mysqli的PDO,那么用户名将最终成为"enhzflep); drop table users"

bobby-tables.com


说到技术原因,只有少数,非常具体,很少使用。很可能你永远不会在生活中使用它们。
也许我太无知了,但我从未有机会使用它们之类的东西

  • 非阻塞,异步查询
  • 存储过程返回多个结果集
  • 加密(SSL)
  • 压缩

如果你需要它们 - 这些毫无疑问是技术上的原因,从mysql扩展转向更时尚和现代化的东西。

然而,也存在一些非技术性问题,这些问题可能会让您的体验更加艰难

  • 在现代PHP版本中进一步使用这些函数将引发弃用级别的通知。他们只是可以关闭。
  • 在遥远的未来,它们可能会从默认的PHP构建中删除。也没什么大不了的,因为mydsql ext将被转移到PECL中,每个主机都很乐意用它编译PHP,因为他们不想失去那些网站工作了几十年的客户。
  • 来自社区的强烈抵制。Еverytime你提到这些诚实的功能,你被告知他们是严格的禁忌。
  • 作为普通的PHP用户,很可能您使用这些功能的想法容易出错并且错误。正因为所有这些教程和手册教你错误的方法。不是功能本身 - 我必须强调它 - 但它们的使用方式。

后一个问题是一个问题。
但是,在我看来,提出的解决方案也不是更好。
在我看来,过于理想化的梦想是所有这些PHP用户将学习如何正确处理SQL查询。很可能他们只是机械地将mysql_ *改为mysqli_ *,让方法保持不变。特别是因为mysqli使准备好的语句使用令人难以置信的痛苦和麻烦。
更不用说本机预处理语句不足以防止 SQL注入,mysqli和PDO都没有提供解决方案。

所以,与其打击这种诚实的延伸,我宁愿采取错误的做法,并以正确的方式教育人们。

此外,有一些错误或非重要的原因,如

  • 不支持存储过程(我们使用mysql_query("CALL my_proc");了很长时间)
  • 不支持交易(与上述相同)
  • 不支持多个语句(谁需要它们?)
  • 不是在积极开发中(那么它会以什么方式影响?)
  • 缺少OO界面(创建一个是几个小时的事情)
  • 不支持Prepared Statements或Parametrized Queries

最后一个是有趣的一点。虽然mysql ext不支持本机预处理语句,但它们不是安全性所必需的。我们可以使用手动处理的占位符轻松伪造准备好的语句(就像PDO一样):

function paraQuery()
{
    $args  = func_get_args();
    $query = array_shift($args);
    $query = str_replace("%s","'%s'",$query); 

    foreach ($args as $key => $val)
    {
        $args[$key] = mysql_real_escape_string($val);
    }

    $query  = vsprintf($query, $args);
    $result = mysql_query($query);
    if (!$result)
    {
        throw new Exception(mysql_error()." [$query]");
    }
    return $result;
}

$query  = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);

,一切都是参数化和安全的。

但好吧,如果您不喜欢手册中的红色框,会出现选择问题:mysqli或PDO?

嗯,答案如下:

  • 如果您了解使用数据库抽象层并寻找创建API 的必要性,那么mysqli是一个非常好的选择,因为它确实支持许多特定于mysql的功能。
  • 如果像绝大多数PHP人一样,你在应用程序代码中使用原始API调用(这实际上是错误的做法) - PDO是唯一的选择,因为这个扩展假装不只是API而是半DAL,仍然不完整,但提供了许多重要的功能,其中两个使得PDO与mysqli有着明显的区别:

    • 与mysqli不同,PDO可以按值绑定占位符,这使得动态构建的查询可行,而不需要几个非常混乱的代码屏幕。
    • 与mysqli不同,PDO总是可以在一个简单的常规数组中返回查询结果,而mysqli只能在mysqlnd安装上执行。

因此,如果您是普通的PHP用户并希望在使用本机预处理语句时节省大量的麻烦,那么再次使用PDO是唯一的选择。
然而,PDO也不是银弹,并且有其艰辛。
所以,我为PDO标签wiki中的所有常见陷阱和复杂案例编写了解决方案

然而,每个谈论扩展的人总是忽略了关于Mysqli和PDO 的两个重要事实

  1. 准备好的声明不是灵丹妙药。有动态标识符不能使用预准备语句绑定。存在具有未知数量的参数的动态查询,这使得查询构建成为困难的任务。

  2. mysqli_ *和PDO函数都不应该出现在应用程序代码中。 在它们和应用程序代码之间
    应该有一个抽象层,它将完成内部绑定,循环,错误处理等所有脏工作,使应用程序代码干净和清洁。特别是对于像动态查询构建这样的复杂情况。

所以,仅仅切换到PDO或mysqli是不够的。必须使用ORM,查询构建器或任何数据库抽象类,而不是在其代码中调用原始API函数。
相反 - 如果你的应用程序代码和mysql API之间有一个抽象层 - 实际上使用哪个引擎并不重要。您可以使用mysql ext直到它被弃用,然后轻松地将您的抽象类重写为另一个引擎,使所有应用程序代码保持不变。

以下是基于我的safemysql类的一些示例,以说明这样的抽象类应该如何:

$city_ids = array(1,2,3);
$cities   = $db->getCol("SELECT name FROM cities WHERE is IN(?a)", $city_ids);

将这一行与PDO所需的代码量进行比较。
然后与原始Mysqli预处理语句所需的疯狂数量的代码进行比较。请注意,错误处理,分析,查询日志已经内置并运行。

$insert = array('name' => 'John', 'surname' => "O'Hara");
$db->query("INSERT INTO users SET ?u", $insert);

将它与通常的PDO插入进行比较,当每个字段名称重复六到十次时 - 在所有这些众多的命名占位符,绑定和查询定义中。

另一个例子:

$data = $db->getAll("SELECT * FROM goods ORDER BY ?n", $_GET['order']);

你很难找到PDO处理这种实际案例的例子。
而且它太过于罗嗦而且很可能不安全。

所以,再一次 - 不仅仅是原始驱动程序应该是你的关注而是抽象类,不仅对初学者手册中的愚蠢例子有用,而且对解决任何现实生活中的问题都很有用。


这是因为与此类似的功能mysql_connect()mysql_query()类型是前一版本PHP即(PHP 4)的功能和现在不在使用中。

这些被替换为mysqli_connect()mysqli_query()类似于最新的PHP5。

这就是错误背后的原因。





database