Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用MySQL绑定参数的正确方法";在;Yii2中的语法?_Php_Mysql_Yii_Yii2 - Fatal编程技术网

Php 使用MySQL绑定参数的正确方法";在;Yii2中的语法?

Php 使用MySQL绑定参数的正确方法";在;Yii2中的语法?,php,mysql,yii,yii2,Php,Mysql,Yii,Yii2,好的,我使用的是Yii2,我熟悉在使用mysql查询时准备/绑定数据,例如: $sql = $this->db->createCommand("UPDATE some_table SET something='foo' WHERE some_id=:some_id"); $sql->bindValue(':some_id', $some_id); 但是当值可能包含多个值时,例如在中使用MySQL语法时,该怎么办 例如: $sql = $this->db->crea

好的,我使用的是
Yii2
,我熟悉在使用mysql查询时准备/绑定数据,例如:

$sql = $this->db->createCommand("UPDATE some_table SET something='foo' WHERE some_id=:some_id");
$sql->bindValue(':some_id', $some_id);
但是当值可能包含多个值时,例如在中使用
MySQL
语法
时,该怎么办

例如:

$sql = $this->db->createCommand("UPDATE some_table SET something='foo' WHERE some_id IN (:parents)");
$sql->bindValue(':parents', $parents);
现在,据我所知,只有当
$parents
var只有一个值时,上述方法才能很好地工作;但是如果它有多个值,比如
1,2,3
,那么当您真正想要
'1'、'2'、'3'
1,2,3
时,就会得到类似
'1,2,3'
的结果


正确的方法是什么?

Yii2的DB函数基于
PDO
。 根据的手册,不支持来自
Array
type的值。(第三个参数-
数据类型

解决方案是在查询之前创建一个字符串,该字符串适合于
子句中的
,并将其绑定为字符串

比如:

$parents = "1,2,3";
/*
Or in case you already have an array of the desirable ids:
$parents_array = array(1,2,3);
$parents = implode(",",$parents_array);
*/

$sql = $this->db->createCommand("UPDATE some_table SET something='foo' WHERE some_id IN (:parents)");
$sql->bindValue(':parents', $parents); 
编辑

占位符似乎被内爆数组替换为一个字符串值
'1,2,3'
,而不是
'1'、'2'、'3'
(因为它是单个占位符)

为了解决这个问题,我建议使用多个
占位符。 因此,与(:parents)
中的
不同,您将在(?,,,,,,,…)中使用
,因为我们已经有了一个排列的数组-我们可以使用
count($array)
来知道需要放置多少占位符

//$parents = array(1,2,3);
$placeholders = str_repeat('?,', count($parents) - 1). '?';
$sql = $this->db->createCommand("UPDATE some_table SET something='foo' WHERE some_id IN (".$placeholders.")");

foreach($parents as $i => $parent){
 $sql->bindValue($i+1, $parent);  
}
请注意bindValue的第一个参数的传递值; 手册中提到的是
$i+1
,而不是
$i
,原因如下:

对于使用问号占位符的准备好的语句,这将 是参数的1索引位置

有关更多信息和替代解决方案,请查看以下答案:

就这么做吧

$parents = implode("','", $parrent_array);
$sql->bindValue(':parents', $parents);

可能应该这样做。

我最后是这样做的:

$parents_safe = '';
$parents_sep = explode(',', $parents);

foreach ($parents_sep as $parent) {
    $parents_safe .= $this->db->quoteValue($parent) . ',';
}

$parents_safe = rtrim($parents_safe, ',');

其中,
$this->db
Yii::$app->db
的一个实例,您只需使用Yii的QueryBuilder函数,一切都将自动处理。试试这个:

$params = [];
$sql = \Yii::$app->db->getQueryBuilder()->update('some_table', ['something' => 'foo'], ['some_id' => [1, 2, 3]], $params);
结果是:

string(78) "UPDATE `some_table` SET `something`=:qp0 WHERE `some_id` IN (:qp1, :qp2, :qp3)"
array(4) { [":qp0"]=> string(3) "foo" [":qp1"]=> int(1) [":qp2"]=> int(2) [":qp3"]=> int(3) } 

我找到了这个解决办法

$params = [];
$sql = \Yii::$app->db->getQueryBuilder()->buildCondition(['IN', 'some_id', $ids], $params);
//$sql = some_id NOT IN (:qp0, :qp1, :qp2)
//$params = [':qp0'=>1, ':qp1'=>2, ':qp2'=>3]
$this->db->createCommand("UPDATE some_table SET something='foo' WHERE $sql", $params);

如果数据可信,那么这一解决方案非常有效:

$db = Yii::$app->db;
$ids = "'" . implode("','", $ids_array) . "'";
$result = $db->createCommand("
    UPDATE some_table SET something='foo' WHERE some_id IN ($ids)
")->queryColumn();

如果有人需要解决Yii1的问题:

$db=\Yii::app()->db;
$inCondition=$db
->getCommandBuilder()
->createInCondition('some_table','some_id',$parents);
$command=$db
->createCommand(“updatesome_table SET something=:foo WHERE$inCondition”);
$command->bindValue(':foo',foo');
$command->execute();

@saty在键入之前,请务必阅读手册,而不是就您不知道的主题提供建议。这可能与我的问题重复。谢谢Brett,这不会导致值被尝试为
'1,2,3'
?@Brett它将是
1,2,3
而不是
'1,2,3'
,查询将work@Bsienn使用
bindValue
绑定不会导致引用值吗?@OfirBaruch好吧,我想这会解决可信数据的问题,但如果在
中的
中使用用户提供的数据,则不建议使用此方法;我想我更多的是寻找一个更健壮的解决方案,而不仅仅是针对这种特殊情况的解决方案。我刚刚测试过,我是对的,使用这种方法最终导致
'1,2,3'
,但没有正常工作。要使其工作,它将依赖于类似
'1','2',的值,“3”
。如果我需要实现一些条件,如某些\u id不在(1、2、3)中以及某些\u字段=2@Rjazhenka类似于
['and'、['not'、['some\u id'=>[1,2,3]]、['some\u field'=>2].
。请参阅规范。如果您刚从受信任的位置恢复了原始数据,我同意仅使用原始数据。如果数据在字符串末尾包含
或”`,则此方法将不起作用。除了整数,我不会用它来表示任何东西。