2012-05-08 12 views
5

tôi cần phải thực hiện một truy vấn đơn giảnLàm thế nào để sử dụng chuẩn bị phát biểu trong các truy vấn với một định tại khoản trong PHP

$array_of_ids = array(); 
//poulate $array_of_ids, they don't come from another db but from Facebook 
//so i can't use a subquery for the IN clause 
$wpdb->prepare("SELECT id from table where id IN (%d, %d)", $array_of_ids [0], $array_of_ids [1]); 

Câu hỏi đặt ra là, nếu tôi có 200 phần tử trong mảng, cách chính xác để xử lý là những gì Tôi có phải tự xây dựng truy vấn với 200 %d không? Tôi cần truy vấn này vì tôi phải "đồng bộ" cơ sở dữ liệu của tôi với dữ liệu facebook và tôi phải kiểm tra xem người dùng có trong db có mặt không, cập nhật những người có mặt, chèn người dùng mới và xóa những người không phải là bạn của tôi.

+0

Xem nếu [câu hỏi này] [1] không trả lời câu hỏi của bạn [1]: http://stackoverflow.com/questions/327274/mysql-prepared-statements-with-a-variable-size-variable-list –

Trả lời

3

Nếu bạn biết chắc chắn rằng các phần tử mảng là số:

$wpdb->prepare("SELECT id FROM table WHERE id IN (" 
    . implode(',',$array_of_ids) . ")"); 

Nếu không, bạn có thể sử dụng các hình thức vsprintf của prepare để vượt qua trong mảng các tham số:

$wpdb->prepare("SELECT id FROM table WHERE id IN (" 
    . str_repeat("%d,", count($array_of_ids)-1) . "%d)" , $array_of_ids); 
+3

Kinda đánh bại toàn bộ mục đích của trạng thái đã chuẩn bị ments ở đó, notcha. – cHao

+0

Bạn có thể thực hiện một 'implode (',', array_map ('intval', $ array_of_ids))' để đảm bảo rằng chúng, trên thực tế, là số. –

+0

Điểm công bằng; cũng cho thấy một cách tiếp cận thay thế trong câu trả lời sửa đổi của tôi. – eggyal

0

Vâng, sql động là cách ở đây. May mắn thay, số nguyên là dễ dàng để không vít lên với.

$vals = array_filter(array_map('intval', $vals)); 

đảm bảo bạn có ít nhất một giá trị và sau đó kích hoạt. Không cần cho một tuyên bố chuẩn bị ở đây, chỉ cần thực hiện sql.

1

Tôi không chắc chắn rằng đây là một cách tiếp cận tốt, nhưng bạn có thể làm điều đó theo cách này:

$sql = "SELECT id from table where id IN (" 
    . implode(',', array_fill(0, count($array_of_ids), "%d")) 
    . ")"; 

call_user_func_array(array($wpdb, 'prepare'), $array_of_ids); 

này xây dựng một chuỗi với số lượng thích hợp của %d, sau đó sử dụng để làm call_user_func_array nó tự động.

Điều đó nói rằng, tôi không chắc chắn đây thực sự là một trường hợp mà các báo cáo chuẩn bị có giá trị phức tạp, được cho là dễ dàng để khử trùng các số nguyên.

+0

array_map() thực hiện thủ thuật độc đáo, nhưng nếu tôi sử dụng bản đồ mảng theo cách đó tôi có thể dễ dàng bỏ qua câu lệnh đã chuẩn bị :) –

-1

Bạn có thể làm điều này:

$query = $wpdb->prepare("SELECT id from table where id IN :param"); 
$query->bindParam("param", "(".implode(',', array_map('intval', $array_of_ids)).")"); 
+1

Chắc chắn ' array_map ('intval', ...) 'đảm bảo an toàn từ SQL injection? – eggyal

+0

có bạn là đúng;) –

+0

Dường như với tôi rằng nếu bạn ràng buộc 'param', nó sẽ được SQL thoát, được trích dẫn, và được coi như một chuỗi ... không phải là một danh sách các công cụ. Trừ khi MySQL thực hiện một số phép thuật để diễn giải chuỗi như danh sách, điều này có thể sẽ không hoạt động. – cHao

0

Vì đây không có câu trả lời được chấp nhận nhưng tôi sẽ đi với cách tiếp cận của tôi với array_filter

$array_of_ids = array(0,1,1,2,3,5,8,13); 

echo "SELECT id from table where id IN (".implode(',', array_filter($array_of_ids,'is_int')).")"; 

chí đầu ra

SELECT id from table where id IN (0,1,1,2,3,5,8,13) 

khi

$array_of_ids = array('zero',1,true,2,3,5,8,'thirteen'); 

echo "SELECT id from table where id IN (".implode(',', array_filter($array_of_ids,'is_int')).")"; 

chí đầu ra

SELECT id from table where id IN (1,2,3,5,8) 

Xin lưu ý rằng is_int không làm việc với $ _GET biến để sử dụng is_numeric thay

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