xsuchy09/e_pdostatement

默认 PDOStatement 类的替代品,允许开发者查看参数化查询的插值版本

3.0.0 2019-08-21 19:15 UTC

This package is auto-updated.

Last update: 2024-09-22 06:02:00 UTC


README

扩展默认的 PHP PDOStatement 类,提供生成参数化查询带参数注入的版本的能力。

结果通常适用于日志记录、调试和性能分析。

查看 变更日志

用法

PHP 的 PDO 是处理数据库通信的改进方式,但是在声明参数插值后无法查看服务器上将要执行的查询的完整版本可能会令人沮丧。

获取插值查询的常见方法涉及使用外部函数或扩展本地的 PDOStatement 对象,并添加新方法来完成此操作。

E_PDOStatement (Enhanced PDOStatement) 项目旨在解决这个问题,无需修改工作流程即可生成结果查询字符串。生成的查询字符串可以在新的 EPDOStatement 对象上作为新的 fullQuery 属性访问

$content    = $_POST['content'];
$title      = $_POST['title'];
$date       = date('Y-m-d');

$query      = 'INSERT INTO posts SET content = :content, title = :title, date = :date';
$stmt       = $pdo->prepare($query);

$stmt->bindParam(':content', $content, PDO::PARAM_STR);
$stmt->bindParam(':title'  , $title  , PDO::PARAM_STR);
$stmt->bindParam(':date'   , $date   , PDO::PARAM_STR);

$stmt->execute();

echo $stmt->fullQuery;

结果将是(在 MySQL 数据库上)

INSERT INTO posts SET content = 'There are several reasons you shouldn\'t do that, including [...]', title = 'Why You Shouldn\'t Do That', date = '2016-05-13'

当正确配置时,插值值将被适当地转义,以便生成的字符串适用于日志文件、备份等。

E_PDOStatement 支持 pre-execution 绑定到命名和 ? 风格参数标记

$query      = 'INSERT INTO posts SET content = ?, title = ?, date = ?';
...

$stmt->bindParam(1, $content, PDO::PARAM_STR);
$stmt->bindParam(2, $title  , PDO::PARAM_STR);
$stmt->bindParam(3, $date   , PDO::PARAM_STR);

以及作为 $stmt->execute() 方法的输入参数提供的未命名参数

$query      = 'INSERT INTO posts SET content = ?, title = ?, date = ?';

...

$params     = [$content, $title, $date];

$stmt->execute($params);

也可以将命名 $key => $value 对作为 $stmt->execute() 方法的输入参数提供

$query      = 'INSERT INTO posts SET content = :content, title = :title, date = :date';

...

$params     = array(
    ':content' => $content, 
    ':title'   => $title, 
    ':date'    => $date, 
);

$stmt->execute($params);

您还可以在不执行查询的情况下生成完整的查询字符串

$content    = $_POST['content'];
$title      = $_POST['title'];
$date       = date('Y-m-d');

$query      = 'INSERT INTO posts SET content = :content, title = :title, date = :date';
$stmt       = $pdo->prepare($query);

$stmt->bindParam(':content', $content, PDO::PARAM_STR);
$stmt->bindParam(':title'  , $title  , PDO::PARAM_STR);
$stmt->bindParam(':date'   , $date   , PDO::PARAM_STR);

$fullQuery  = $stmt->interpolateQuery();

$content    = $_POST['content'];
$title      = $_POST['title'];
$date       = date('Y-m-d');

$query      = 'INSERT INTO posts SET content = ?, title = ?, date = ?';
$stmt       = $pdo->prepare($query);

$params     = [
    $content, 
    $title, 
    $date
];

$fullQuery  = $stmt->interpolateQuery($params);

安装

首选方法:使用 composer 安装

PHP 7.2+

"require" : {
	"xsuchy09/e_pdostatement" : "3.*"
}

PHP < 7.2

"require" : {
	"xsuchy09/e_pdostatement" : "2.*"
}

或者,您可以简单地下载项目,将其放置在应用程序目录的合适位置,并根据需要将其包含到项目中。

配置

EPDOStatement 类扩展了本地的 \PDOStatement 对象,因此必须配置 PDO 对象以使用扩展定义

require_once 'path/to/vendor/autoload.php';

/**
 * -- OR --
 *
 * require_once 'EPDOStatement.php';
 */

$dsn        = 'mysql:host=localhost;dbname=myDatabase';
$pdo        = new PDO($dsn, $dbUsername, $dbPassword);

$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['EPDOStatement\EPDOStatement', [$pdo]]);
//$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('EPDOStatement\EPDOStatement', array($pdo))); // older php versions

这就完成了。

理想情况下,您的项目应该有一个 PDO 抽象/包装类,允许您仅在单个位置实现此修改。如果您没有这样的便利,已经证明通过扩展 \PDO 类并在 PDO 的构造函数中设置 ATTR_STATEMENT_CLASS 属性可以实现成功。

联系我

有许多论坛帖子与这类功能相关或请求此类功能,因此希望某处有人会发现它有帮助。如果它对您有帮助,当然欢迎发表评论。

欢迎提交错误报告、新功能请求和拉取请求。这个项目是为了帮助我们的专业团队解决问题而创建的,因此它是围绕我们的特定工作流程设计的。如果您发现它不起作用,请告诉我,我会很高兴探索是否能够帮助您。

E_mysqli

E_PDOStatement 现在有一个姐妹项目,旨在为使用 mysqli 扩展的 PHP 开发者提供相同的功能。

E_mysqli