这是我对Kohana 3的更新方法。
public function update($type, $id, $updates) {
$info = $this->getInfo($type);
$dbTable = $info['table'];
$updatesKeysToValues = array();
var_dump($updates);
foreach($updates as $key => $value) {
// if the value is null or the key isnt set for this, don't update!
if ($value === null OR ! isset($info['columnsToUpdateData'][$key])) continue;
$updatesKeyToValues[] = "`$key` = :$key";
}
$updatesKeyToValues = implode(', ', $updatesKeyToValues);
$query = 'UPDATE `' . $dbTable . '` SET ' . $updatesKeyToValues . ' WHERE id = :id LIMIT 1' ;
echo $query;
$dbQuery = DB::query(Database::UPDATE, $query);
foreach($updates as $key => $value) {
echo "$key === $value\n<br>";
$dbQuery->bind(':' . $key, $value);
}
$success = $dbQuery->bind(':id', $id)
->execute();
var_dump($success);
}
在每个var_dump()
和echo
期间数据都很好。没有什么可以暗示为什么会发生这种情况。
基本上我正在做的是从配置中获取此表的数据,构建一个带有命名参数的查询字符串,循环并定义命名参数然后执行。而不是工作,我最终得到所有字段相同(似乎是最后一个数组值)。
我似乎无法弄明白,是吗?非常感谢你的时间。
更新
我只是想一想,查询中的param名称中的下划线是否有效?
另一个更新
以下是echo $query
UPDATE `personnel` SET `first_name` = :first_name, `last_name` = :last_name, `email` = :email WHERE id = :id LIMIT 1
我也研究了将多个参数绑定到查询的方法。我以前从未在循环中完成它,但我认为它会起作用。在Kohana 2.x中,我总是使用$bindings[] = 'tom@jones.com'
等,但据我所知,新的Kohana不接受数组。
最终更新
谢谢大家,我认为它是通过引用传递的。我通过将其设置为$updates[$key]
看起来我也可以使用param()
方法而不是绑定。 View source
答案 0 :(得分:4)
bind函数使用引用你的$ value
public function bind($param, & $var)
{
// Bind a value to a variable
$this->_parameters[$param] =& $var;
return $this;
}
似乎在测试中起作用的东西
$a = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6);
$v = array();
$t = array();
$i = 0;
foreach($a as $key => $value)
{
$t[] = $key;
$v[] = &$t[$i];
$i++;
}
print_r($v);
结果如下: http://www.antiyes.com/test/hmm.php
你认为$ key&amp;
中的$ value$dbQuery->bind(':' . $key, $value);
正在通过引用传递?
下面没有工作
这一行
$updatesKeyToValues[] = "`$key` = :$key";
你可以把它改成:
$updatesKeyToValues[] = "`" . $key ."` = " . ":" . $key;
看看会发生什么?
答案 1 :(得分:4)
我不知道你在这里使用什么数据访问层,但我猜这个:
foreach($updates as $key => $value) {
$dbQuery->bind(':' . $key, $value);
}
可能会做一些非常具有欺骗性的事情:通过引用获取参数。
那么会发生什么事情,因为$value
是一个真正的变量,bind()
函数接收对它的引用,并记住它是这个变量 - 不变量的当前值 - 它将绑定到给定参数。然后你转到下一轮foreach
循环,我们遇到了类似C语言的经典循环问题:你没有得到$key
和$value
的新实例,您实际上正在更改现有的变量,就像标准的for ($i= 0...
循环一样。
那么,当需要进行查询时,参数:a
是什么?它是$value
的当前值,是循环中的最后一个值。什么参数:b
?相同。等等。
我知道一些PHP参数化接口会这样做(mysqli,我认为?),但一般来说,通过引用接收参数是IMO极有可能导致这样的不良行为,我当然认为它完全不适合参数绑定像这样的界面。
ETA:只是查看了你发布给John评论的链接中的query.php。是。叹。它通过参考获取参数。多可怕啊。
答案 2 :(得分:0)
为什么不使用查询构建器?
这只是一个快速猜测,因为我没有足够的时间自己使用查询构建器。
$query = DB::update();
$query->set($updates);
// etc
查看源代码,我确定您可以弄清楚查询构建器的工作原理:)