在PDO中使用bindParam或bindValue时,“绑定”究竟存储在PDOStatement对象中的什么位置?是否可以显示此设置的属性/引用/等?
我试图了解这些和其他PDOStatement方法在PDOStatement对象中存储/定位数据的位置(如果甚至可以通过PDOStatement方法设置数据之外访问它)。
(我想这个问题也扩展到其他PDO / PDOStatement方法,很好奇事物的存储位置,例如是否存储在属性中或其他什么)
最佳答案
准备好的语句要么是协议功能(例如mysql),要么将在后台的C库中运行。这意味着解析语句的工作不是由PDO代码完成的。它是由数据库服务器或C库(如libsqlite)完成的。由于PDO不会自行解析该语句,而只是将其传递给较低级别的组件,因此无法获得参数信息。
因此,使用纯PHP不可能在使用PDOStatement对象的查询中将关联占位符=>替换为值。这是设计使然的声明。
一种解决方法是扩展PDOStatement
并添加一种方法,该方法用参数占位符替换为当前查询字符串中的值。我在下面准备了一个例子。请注意,此示例不是防弹的,因为即使出现在带引号的字符串中,它也会替换:bar
。但是对于内部使用而言,到目前为止,这样的解决方案对我来说做得很好。
自定义语句类:
class MyStatement extends PDOStatement
{
protected $params;
protected $pdo;
protected function __construct($pdo) {
$this->pdo = $pdo;
}
public function execute($params = null) {
$this->params = $params;
return parent::execute($params);
}
public function printQuery(){
$_params = $this->params;
$sql = $this->queryString;
foreach($this->params as $key => $value) {
$_value = is_null($value) ?
'NULL' : '\'' . $value . '\'';
$sql = str_replace(':'. $key, $_value, $sql);
}
return $sql;
}
}
You need a modified PDO:
class MyPDO extends PDO
{
public function __construct($dsn, $username="", $password="", $driver_options=array()) {
parent::__construct($dsn, $username, $password, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_STATEMENT_CLASS => array('MyStatement', array($this))
));
}
}
测试代码:
$pdo = new MyPDO('mysql:host=localhost;dbname=test', 'root', '******');
// preapre stupid query
$stmt = $pdo->prepare('SELECT FROM `foo` WHERE name = :bar');
try {
// execute stmt
$stmt->execute(array('bar' => 'hek2mgl'));
} catch (PDOException $e) {
echo $stmt->printQuery();
}
关于php - bindParam在哪里存储绑定(bind)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17710627/