Basit cevap şudur: Yapamazsınız. PDO, bazı sınırlamaları olan hazırlanmış ifadeler için bir soyutlama kullanır. Ne yazık ki bu işe-etrafında bir şeyler kullanarak bu tür tekrarlanan adlı parametreler desteklenir PDO/MySQL sürücüsünün bazı sürümlerinde taklit hazırlanmış tablolar gibi belirli durumlarda,
$query = "UPDATE users SET firstname = :name1 WHERE firstname = :name2";
$stmt = $dbh -> prepare($query);
$stmt -> execute(array(":name1" => "Jackie", ":name2" => "Jackie"));
gibi var biridir; bununla birlikte, bu durum gevrek olduğu için (örneğin yükseltmelerin daha fazla iş gerektirmesini sağlayabilir) güvenilmemelidir.
adlandırılmış bir parametrenin birden görünüşleri desteklemek istiyorsanız
, her zaman
extend PDO and PDOStatement (klasik miras yoluyla veya niteliği ile), ya da sadece PDOStatement ve
PDO::ATTR_STATEMENT_CLASS
niteliğini ayarlayarak açıklamada sınıfı olarak sınıfınızı ayarlayabilirsiniz. Genişletilmiş PDOStatement (veya
PDO::prepare
), adlandırılmış parametreleri ayıklayabilir, tekrarları arayabilir ve otomatik olarak değiştirmeler oluşturabilir. Ayrıca bu kopyaları da kaydeder. Bağlama ve yürütme yöntemleri, adlandırılmış bir parametreyi geçtiğinde, parametrenin yinelenip yinelenmediğini test eder ve her bir değiştirme parametresine değeri bağlar.
Not: Aşağıdaki örnek test edilmemiştir ve büyük olasılıkla hatalar vardır (kod açıklamalarında bazı ifadelerin ayrıştırılmasıyla ilişkilidir).
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);
}
}
}
asla ettik:
Sonra bu şekilde kullanabilirsiniz: Ben geçici bir çözüm olarak yardımcı aşağıdaki kullanılan bu yüzden sendikalar sürü ve yinelenen params bir sürü oldukça karmaşık dinamik sorgu var Aynı listede bir 'DUPLICATE KEY UPDATE' deyiminde yinelenen herhangi bir sorun vardı ... – jeroen
Aslında PDO sürücüsüne biraz bağlı, çalışmaya güvenmemelisiniz. – johannes
İlginç, her zaman benim için çalıştı. Bu konuda herhangi bir belge biliyor musunuz? – jeroen