为什么 MySQLi 库本身不支持命名参数?

Why doesn't MySQLi library natively support named parameters?

来自 http://php.net/manual/en/mysqli.quickstart.prepared-statements.php 的正确 MySQLi 参数化查询语法:

$stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)");
$stmt->bind_param("i", $id);

但绝不是这样的:

$stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (:id_value)");
$stmt->bind_param("i", "id_value", $id);

在我看来,named parameter 替换是在 API 级别实现的合理功能。我很惊讶 MySQLi 只在库中实现了 unnamed parameters

有正当理由吗?这对我来说没有意义,看看 PDO、DQL、ORM 如何在他们的查询中采用命名参数。

我希望 MySQLi 开发人员 "We were lazy & don't wanna" 不是这种情况。我相信一定有一个很好的理由,我正在寻找那个理由,或者寻找那个理由的方法。命名参数未在 MySQLi 扩展库中实现的原因。

MYSQLi 不支持命名参数主要有两个原因:

  1. 它是"intended"(我松散地使用这个术语)与包装器一起使用
  2. 它的对应物 PDO 确实如此 - 而且没有必要重新发明轮子

详细说明第 1 点:mysqli,尽管与 PDO 相比有许多缺点,但它很容易与一个好的包装器相比较——也就是说,命名参数(以及其他参数)由包装器而不是 mysqli 本身。这是设计使然,原因只有一个:

  1. Mysqli 旨在成为一个快速灵活的库。

如果开发人员将更多功能合并到基础库中,与直觉相反,它会变得不那么灵活并且需要更长的 load/execution 次。

mysqlipdo 都与 PHP 5 一起发布(我相信 PDO 是 5.3 版),因此适用于不同的用途。

您想要更快的执行时间?使用没有包装器的 mysqli。你想要命名参数?使用 PDO 或构建一个 mysqli 包装器来处理此类问题 - 但请注意,这会影响您的执行时间。

传统上,MySQLi 是 MySQL API. It doesn't add anything on its own and for a reason: adding such features as named placeholders will require, if you think of it, a whole leviathan of SQL query parsing. Definitely, it is not a job for a database API. Like it is said in the other answer, API is not a DAL or DBAL 的一个非常薄的包装器;它们用于不同的目的。

PDO 是一项伟大的壮举,您几乎不会在该语言中再次看到它,而 Wes Furlong 是一位天才,他几乎单枪匹马地完成了这项任务。但是,PDO 又是另外一回事了。它是一个数据库访问抽象层,要实现这个目标,您需要一个查询解析器,不管您喜欢与否。由于您已经有一个查询解析器并且其中一个驱动程序已经支持命名占位符,因此将它添加到所有受支持的驱动程序中是很自然的。如您所见,使用 MySQLi 就完全不同了。

简而言之,不是关于"laziness";这是关于遵循规范。