php pdo update 变量,PHP PDO准备重复变量

小编典典

简单的答案是:您不能。PDO对准备好的语句使用了抽象,这有一定的局限性。不幸的是,这是一个问题,您必须使用类似的方法来解决

$query = "UPDATE users SET firstname = :name1 WHERE firstname = :name2";

$stmt = $dbh -> prepare($query);

$stmt -> execute(array(":name1" => "Jackie", ":name2" => "Jackie"));

在某些情况下,例如使用某些版本的PDO /

MySQL驱动程序模拟准备好的语句,则支持重复的命名参数;但是,这不应该依赖,因为它很脆弱(例如,升级可能需要更多的工作)。

如果要支持命名参数的多个外观,则始终可以扩展PDO和PDOStatement(通过经典继承或按组成),也可以仅扩展PDOStatement,然后通过设置PDO::ATTR_STATEMENT_CLASS属性将类设置为语句类。扩展的PDOStatement(或PDO::prepare)可以提取命名的参数,查找重复项并自动生成替换项。它还将记录这些重复项。当绑定和执行方法传递一个命名参数时,它将测试该参数是否重复并将该值绑定到每个替换参数。

注意:以下示例未经测试,并且可能存在错误(一些与语句解析有关的错误在代码注释中注明)。

class PDO_multiNamed extends PDO {

function prepare($stmt) {

$params = array_count_values($this->_extractNamedParams());

# get just named parameters that are repeated

$repeated = array_filter($params, function ($count) { return $count > 1; });

# start suffixes at 0

$suffixes = array_map(function ($x) {return 0;}, $repeated);

/* Replace repeated named parameters. Doesn't properly parse statement,

* so may replacement portions of the string that it shouldn't. Proper

* implementation left as an exercise for the reader.

*

* $param only contains identifier characters, so no need to escape it

*/

$stmt = preg_replace_callback(

'/(?:' . implode('|', array_keys($repeated)) . ')(?=\W)/',

function ($matches) use (&$suffixes) {

return $matches[0] . '_' . $suffixes[$matches[0]]++;

}, $stmt);

$this->prepare($stmt,

array(

PDO::ATTR_STATEMENT_CLASS => array('PDOStatement_multiNamed', array($repeated)))

);

}

protected function _extractNamedParams() {

/* Not actually sufficient to parse named parameters, but it's a start.

* Proper implementation left as an exercise.

*/

preg_match_all('/:\w+/', $stmt, $params);

return $params[0];

}

}

class PDOStatement_multiNamed extends PDOStatement {

protected $_namedRepeats;

function __construct($repeated) {

# PDOStatement::__construct doesn't like to be called.

//parent::__construct();

$this->_namedRepeats = $repeated;

}

/* 0 may not be an appropriate default for $length, but an examination of

* ext/pdo/pdo_stmt.c suggests it should work. Alternatively, leave off the

* last two arguments and rely on PHP's implicit variadic function feature.

*/

function bindParam($param, &$var, $data_type=PDO::PARAM_STR, $length=0, $driver_options=array()) {

return $this->_bind(__FUNCTION__, $param, func_get_args());

}

function bindValue($param, $var, $data_type=PDO::PARAM_STR) {

return $this->_bind(__FUNCTION__, $param, func_get_args());

}

function execute($input_parameters=NULL) {

if ($input_parameters) {

$params = array();

# could be replaced by array_map_concat, if it existed

foreach ($input_parameters as $name => $val) {

if (isset($this->_namedRepeats[$param])) {

for ($i=0; $i < $this->_namedRepeats[$param], ++$i) {

$params["{$name}_{$i}"] = $val;

}

} else {

$params[$name] = $val;

}

}

return parent::execute($params);

} else {

return parent::execute();

}

}

protected function _bind($method, $param, $args) {

if (isset($this->_namedRepeats[$param])) {

$result = TRUE;

for ($i=0; $i < $this->_namedRepeats[$param], ++$i) {

$args[0] = "{$param}_{$i}";

# should this return early if the call fails?

$result &= call_user_func_array("parent::$method", $args);

}

return $result;

} else {

return call_user_func_array("parent::$method", $args);

}

}

}

2020-05-29

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值