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

2022-08-31 01:17:17

来自 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);

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

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

我希望这不是MySQLi开发人员的“我们懒惰和不想”的情况。我相信一定有一个很好的理由,我正在寻找这个理由,或者一种寻找这个理由的方法。未在 MySQLi 扩展库中实现命名参数的原因。


答案 1

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

  1. 它是“有意的”(我松散地使用这个术语)与包装器一起使用,并且
  2. 它是对应的,,确实如此 - 并且重新发明轮子是没有意义的PDO

详细阐述第 1 点:,尽管与 相比它有很多缺点,但它很容易与一个好的包装器相提并论 - 也就是说,命名参数(以及其他参数)由包装器而不是它本身支持。这是设计使然,原因只有一个:mysqliPDOmysqli

  1. Mysqli被设计为一个快速灵活的库。

如果开发人员将更多功能合并到基础库中,则与直觉相反,它变得不那么灵活,并且需要更长的加载/执行时间。

两者都与PHP 5一起发布(我相信PDO版本为5.3),因此旨在用于不同的用途。mysqlipdo

您想要更快的执行时间吗?无需包装即可使用。您想要命名参数吗?使用或构建包装器来处理此类操作 - 但请注意,这将阻碍您的执行时间。mysqliPDOmysqli


答案 2

传统上,MySQLi是MySQL API的一个非常薄的包装器。它不会自行添加任何内容,这是有原因的:如果您想到它,添加命名占位符等功能将需要SQL查询解析的整个利维坦。当然,这不是数据库API的工作。就像在另一个答案中所说的那样,API不是DAL或DBAL;它们用于不同的目的。

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

简而言之,这不是关于“懒惰”;它是关于遵循规范。


推荐