ปัญหาเมื่อพยายามใช้ IN() ใน wpdb

ฉันมีสิ่งนี้:

$villes = '"paris","fes","rabat"';
$sql    = 'SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN(%s)';
$query  = $wpdb->prepare($sql, $villes);

เมื่อฉันทำ echo $query; ฉันจะได้รับ:

SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN('\"CHAPELLE VIVIERS \",\"LE MANS \",\"QUEND\"')

ปัญหาที่ฉันมีคือ $wpdb เพิ่ม ' ใน IN('...')

ใครสามารถช่วยได้ ขอบคุณ


person mgraph    schedule 17.05.2012    source แหล่งที่มา


คำตอบ (4)


ลองใช้รหัสนี้ (แก้ไขแล้ว):

// Create an array of the values to use in the list
$villes = array("paris", "fes", "rabat");    

// Generate the SQL statement.
// The number of %s items is based on the length of the $villes array
$sql = "
  SELECT DISTINCT telecopie
  FROM `comptage_fax`
  WHERE `ville` IN(".implode(', ', array_fill(0, count($villes), '%s')).")
";

// Call $wpdb->prepare passing the values of the array as separate arguments
$query = call_user_func_array(array($wpdb, 'prepare'), array_merge(array($sql), $villes));

echo $query;
person DaveRandom    schedule 17.05.2012
comment
โปรดทราบว่านี่อาจเป็นแนวทางที่ซับซ้อนเกินไป แต่จะทำให้คุณได้เปรียบในการเปลี่ยนแปลงเนื้อหาของอาร์เรย์ และโค้ดจะปรับเปลี่ยนตามนั้นโดยไม่มีการแก้ไขใดๆ ดังนั้น คุณสามารถเติม $villes ด้วย 30 เมือง แทนที่จะเป็นเพียง 3 เมือง และเมืองจะยังคงใช้งานได้ - person DaveRandom; 17.05.2012
comment
อาจต้องการพิจารณาเพิ่มสิ่งนี้ลงใน codex หรือส่งแพตช์ไปยังคอร์ที่จะอนุญาตให้คุณใช้วิธีนี้สำหรับคำสั่ง IN - person Nick Budden; 26.03.2013
comment
ฉันจะเพิ่มคำสั่ง AND ใกล้กับพื้นที่ WHERE ได้อย่างไร WHERE ville IN(.implode(', ', array_fill(0, count($villes), '%s')).) AND table_name.name = '%s' - person Faysal Haque; 12.03.2015
comment
ขอบคุณสำหรับรหัสของคุณมันช่วยฉันได้ในสิ่งที่ฉันต้องการ :) นี่คือวิธีแก้ปัญหาของฉัน: stackoverflow.com/a/29000133/1993427 - person Faysal Haque; 12.03.2015
comment
ตอนนี้คุณสามารถใช้ส่วนขยายเพื่อทำให้โค้ดดูสะอาดตาขึ้นเล็กน้อย หากอาร์เรย์ของคุณคือรายการสุดท้ายใน $prepare: $wpdb->prepare($sql,...$ville); - person Aaron Harun; 19.05.2017
comment
ประกาศเกี่ยวกับ PHP: wpdb::prepare ถูกเรียก ‹strong›incorrectly‹/strong› ประเภทค่าที่ไม่รองรับ (อาร์เรย์) โปรดดู ‹a href=wordpress.org/support/article/debugging-in -wordpress/ ใน WordPress‹/a› สำหรับข้อมูลเพิ่มเติม (ข้อความนี้ถูกเพิ่มในเวอร์ชัน 4.8.2) ใน E:\XAMPP\htdocs\mr-assistant\wp-includes\functions.php ออนไลน์ 5167 - person Shapon Pal; 20.07.2020

WordPress มีฟังก์ชันสำหรับจุดประสงค์นี้อยู่แล้ว โปรดดูที่ esc_sql() นี่คือคำจำกัดความของฟังก์ชันนี้:

หนีข้อมูลเพื่อใช้ในการสืบค้น MySQL โดยปกติคุณควรเตรียมคำสั่งโดยใช้ wpdb::prepare() บางครั้งการหลบหนีเฉพาะจุดก็จำเป็นหรือมีประโยชน์ ตัวอย่างหนึ่งคือการเตรียมอาร์เรย์เพื่อใช้ในส่วนคำสั่ง IN

คุณสามารถใช้มันเช่นนี้:

$villes = ["paris", "fes", "rabat"];
$villes = array_map(function($v) {
    return "'" . esc_sql($v) . "'";
}, $villes);
$villes = implode(',', $villes);
$query = "SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN (" . $villes . ")"
person Turgut Sarıçam    schedule 16.04.2016
comment
ฉันชอบคำตอบนี้มากกว่าคำตอบที่ยอมรับเนื่องจากความเรียบง่าย - person Greeso; 21.03.2017
comment
ฉันชอบอันนี้ ใช้ประโยชน์จากฟังก์ชัน WordPress ได้เป็นอย่างดี - person shariqkhan; 14.12.2020

ฟังก์ชัน:

function escape_array($arr){
    global $wpdb;
    $escaped = array();
    foreach($arr as $k => $v){
        if(is_numeric($v))
            $escaped[] = $wpdb->prepare('%d', $v);
        else
            $escaped[] = $wpdb->prepare('%s', $v);
    }
    return implode(',', $escaped);
}

การใช้งาน:

$arr = array('foo', 'bar', 1, 2, 'foo"bar', "bar'foo");

$query = "SELECT values
FROM table
WHERE column NOT IN (" . escape_array($arr) . ")";

echo $query;

ผลลัพธ์:

SELECT values
FROM table
WHERE column NOT IN ('foo','bar',1,2,'foo\"bar','bar\'foo')

อาจมีประสิทธิภาพมากขึ้นหรือไม่ก็ได้ แต่สามารถนำกลับมาใช้ใหม่ได้

person Greenzilla    schedule 03.06.2015

ฟังก์ชัน prepare ยังใช้ array เป็นพารามิเตอร์ตัวที่สองด้วย

คุณสามารถลองแปลง $villes ดังนี้:

ปัจจุบัน

<?php
$villes = '"paris","fes","rabat"';
?

เปลี่ยนเป็น

<?php
$villes = array("paris","fes","rabat");
?>

ตอนนี้ลองส่ง $villes ไปยังฟังก์ชั่นเตรียมและดูว่าได้ผลหรือไม่ หวังว่ามันจะช่วยได้

person web-nomad    schedule 17.05.2012
comment
ฉันลองแล้ว แต่มันผ่านเฉพาะองค์ประกอบแรกของอาร์เรย์เท่านั้น - person mgraph; 17.05.2012