2012-03-02 25 views
8

tôi có dưới đây trường hợp của php:Cách liên kết các tham số mảng trong khung công tác YII?

$inputs = "1,2,3,4,5"; 
$sql = "SELECT * FROM obj WHERE id IN(:input)"; 

tôi đã sử dụng yii cung cấp chức năng db:

$commond = Yii::app()->db->createCommand($sql); 
$commond->bindValue(":input", $inputs , PDO::PARAM_STR); 

nhưng kết quả truy vấn trong đúng, vì vậy nếu điều này làm thế nào tôi có thể làm gì?

+2

Câu trả lời của Uday Sawant là một cách giải quyết tốt. Mã của bạn ở trên sẽ thực sự dẫn đến câu lệnh SQL này: 'SELECT * FROM obj WHERE id IN ('1,2,3,4,5')'. Lưu ý rằng giá trị của '$ input' là một ** chuỗi đơn **. Đó là những gì làm cho kết quả không chính xác. Nếu bạn thực sự phải sử dụng 'bindValue', bạn sẽ phải xây dựng SQL từ các mảng như [this here] (http://stackoverflow.com/questions/6071619/pdo-bind-unknown-number-of-parameters). – Shiki

Trả lời

7

cho bây giờ sử dụng nó như thế này

$command = Yii::app()->db->createCommand() 
    ->select() 
    ->from('tableName') 
    ->where(array('in', 'id', explode(',', $inputs))); 

tôi sẽ cố gắng liên lạc lại với $command->bindValue() phương pháp.

+0

Cảm ơn bạn đã hỗ trợ! – Cherry

1

Sử dụng chuỗi phương pháp của Yii trong CDbCommand để tạo truy vấn của bạn (như trong câu trả lời của Uday Sawant) thường là một lựa chọn tốt. Nếu cần phải xây dựng các truy vấn từng phần không phải là lý tưởng, một lựa chọn tốt là để san bằng mảng lại các thông số, do đó bạn không bảo vệ SQL injection bỏ qua, như vậy:

$sql = "SELECT * FROM obj WHERE id IN (:id_array) AND other_field = :other_value"; 
$args = array(
    'id_array' => array(1, 2, 3, 4, 5), 
    'other_value' => 12, 
); 

// Flatten array arguments into multiple parameters, 
// replacing with parameter lists in the SQL 
$newArgs = array(); 
$replace = array(); 
foreach($args as $oldKey => $input) { 
    if(!is_array($input)) { 
    $newArgs[$oldKey] = $args[$oldKey]; 
    continue; 
    } 

    $replace[':'.$oldKey] = array(); 
    foreach($input as $i => $value) { 
    $replace[':'.$oldKey][] = ':'.$oldKey.$i; 
    $newArgs[$oldKey.$i] = $value; 
    } 
    $replace[':'.$oldKey] = implode(', ', $replace[':'.$oldKey]); 
} 
$sql = strtr($sql, $replace); 

$query = Yii::app()->db->createCommand($sql); 
$query->params = $newArgs; 
$query->queryAll(); 

Trong ví dụ này, sql thức và lập luận là:

SELECT * FROM obj WHERE id IN (:id_array0, :id_array1, :id_array2, :id_array3, :id_array4) AND other_field = :other_value 
array(
    'id_array0' => 1, 
    'id_array1' => 2, 
    'id_array2' => 3, 
    'id_array3' => 4, 
    'id_array4' => 5, 
    'other_value' => 12, 
) 

Trong các dự án sử dụng SQL thô là tiêu chuẩn ưa thích, lợi ích lớn nhất là bạn có thể gộp chức năng này thành tiện ích và sử dụng lại nó cho bất kỳ truy vấn nào. Đó là một sự xấu hổ Yii không tự động mở rộng các đối số mảng theo cách này, nhưng bạn cũng có thể tự thêm hỗ trợ này vào các dự án trực tiếp sử dụng PDO.

6

Sau khi gặp vấn đề này một vài lần trong dự án của tôi, tôi đã đi lên với Yii làm việc xung quanh bằng cách sử dụng CDbCriteria mà là một chút hacky, nhưng cung cấp cho an ninh của phù hợp với số param.

Khi áp dụng cho ví dụ của bạn mã của tôi sẽ là:

$inputs = array(1,2,3,4,5); 
$criteria = new CDbCriteria(); 
$criteria->addInCondition('id',$inputs); 

$sql = 'SELECT * FROM obj WHERE '.$criteria->condition; 
$command = Yii::app()->db->createCommand($sql); 
$results = $command->queryAll(true, $criteria->params); 

CẬP NHẬT

Có thực sự là một cách sạch hơn để làm điều này được xây dựng vào Yii:

$results = Yii::app()->db->createCommand() 
    ->select() 
    ->from('obj') 
    ->where(['in', 'id', $inputs]) 
    ->queryAll(); 

Xem Docs

Các vấn đề liên quan