WordPress가 IN() 조건으로 준비한 문
다음과 같은 문자열에는 다음 세 가지 값이 있습니다.
$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\"')
이 문자열은 세 개의 개별 값으로 작성되지 않습니다.큰따옴표가 이스케이프된 하나의 문자열일 뿐입니다.
여러 값을 사용하여 WordPress에서 준비된 문장을 올바르게 구현하려면 어떻게 해야 합니까?
다음 코드를 사용해 보십시오.
// 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;
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 . ")"
기능:
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')
더 효율적일 수도 있고 그렇지 않을 수도 있지만 재사용할 수 있습니다.
여기 소독을 위한 저의 접근법이 있습니다.IN (...)
에 대한 가치관$wpdb
.
- 목록의 각 값을 전달하는 도우미 기능을 사용합니다.
$wpdb->prepare()
제대로 빠져나갈 수 있도록 하기 위해서요. - 준비된 값 목록은 를 통해 SQL 쿼리에 삽입됩니다.
sprintf()
.
도우미 기능:
// Helper function that returns a fully sanitized value list.
function _prepare_in ( $values ) {
return implode( ',', array_map( function ( $value ) {
global $wpdb;
// Use the official prepare() function to sanitize the value.
return $wpdb->prepare( '%s', $value );
}, $values ) );
};
사용 예:
// Sample 1 - note that we use "sprintf()" to build the SQL query!
$status_cond = sprintf(
'post_status IN (%s)',
_prepare_in( $status )
);
$posts = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE $status_cond;" );
// Sample 2:
$posts = $wpdb->get_col( sprintf( "
SELECT ID
FROM $wpdb->posts
WHERE post_status IN (%s) AND post_type IN (%s)
;",
_prepare_in( $status ),
_prepare_in( $post_types )
) );
배열에서 준비된 문장의 자리 표시자를 생성하는 작은 함수를 만들었습니다. 예를 들어 다음과 같습니다.(%s,%d,%f)
어레이의 각 항목에 따라 사용하는 플레이스 홀더를 정확하게 파악할 수 있습니다.
function generate_wpdb_prepare_placeholders_from_array( $array ) {
$placeholders = array_map( function ( $item ) {
return is_string( $item ) ? '%s' : ( is_float( $item ) ? '%f' : ( is_int( $item ) ? '%d' : '' ) );
}, $array );
return '(' . join( ',', $placeholders ) . ')';
}
질문의 예를 참고하여 먼저 값을 배열로 변환해야 합니다.
$villes = array( "paris", "fes", "rabat" );
$in_str = generate_wpdb_prepare_placeholders_from_array( $villes );
$sql = "SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN {$in_str}";
$query = $wpdb->prepare( $sql, $villes );
첫 번째는 배열에 알 수 없는 수의 값이 포함된 mysqli 준비된 문을 사용하는 최신 비 WordPress 기술 세트입니다.두 번째 스니펫은 WordPress와 동등한 것입니다.
인덱스된 입력 데이터 배열이 신뢰할 수 없으며 다음 위치에서 액세스할 수 있다고 가정합니다.$_GET['villes']
준비된 스테이트먼트는 최신 표준으로 프로 개발자들이 오래된/신뢰할 수 없는 이스케이프 기술보다 선호합니다.다음에 이어지는 스니펫은 다음 중 하나가 있는 행을 반환합니다.ville
값을 지정합니다.어레이가 선언되지 않았거나 비어 있으면 데이터베이스 테이블의 모든 행을 반환합니다.
기본 PHP 기술:
$sql = "SELECT DISTINCT telecopie FROM comptage_fax";
if (!empty($_GET['villes'])) {
$count = count($_GET['villes']);
$commaDelimitedPlaceholders = implode(',', array_fill(0, $count, '?'));
$stmt = $conn->prepare("$sql WHERE ville IN ($commaDelimitedPlaceholders)");
$stmt->bind_param(str_repeat('s', $count), ...$_GET['villes']);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $conn->query($sql);
}
이 시점에서, 다른 행에 액세스 할 수 있습니다.telecopie
단순한 관련 배열의 인덱스 배열을 반복하는 것과 같은 값(기술적으로는 반복 가능한 결과 집합 객체)foreach()
.
foreach ($result as $row) {
echo $row['telecopie'];
}
WordPress의 도우미 메서드를 사용하면 변수 바인딩 및 쿼리 실행이 다음과 같이 처리되므로 구문이 더 단순해집니다.get_results()
:
$sql = "SELECT DISTINCT telecopie FROM comptage_fax";
if (!empty($_GET['ville']) {
$commaDelimitedPlaceholders = implode(',', array_fill(0, count($_GET['ville']), '%s'));
$sql = $wpdb->prepare("$sql WHERE ville IN ($commaDelimitedPlaceholders)", $_GET['ville']);
}
$result = $wpdb->get_results($sql, ARRAY_A);
시점부터, 「 」는$result
의 인덱스 으로는 '어소시에이션 배열'이 입니다.★★★★★★★★★★★★★★★★★★,ARRAY_A
$result
첫 번째 네이티브 php 스니펫과 같은 결과 집합 개체가 아닙니다., 풀 인 루핑 언어 생성자를 모두 할 수 .array_
데이터상에서 기능합니다.
유용한 참고 자료:
- https://developer.wordpress.org/reference/classes/wpdb/prepare/
- https://developer.wordpress.org/reference/classes/wpdb/get_results/
이 함수는 또한array
두 번째 파라미터로 지정합니다.
해 보세요.$villes
음음음같 뭇매하다
현재의
<?php
$villes = '"paris","fes","rabat"';
?
로 변경하다
<?php
$villes = array("paris","fes","rabat");
?>
그럼 이번에는 ㅇㅇ, ㅇㅇㅇㅇ를 .$villes
펑크를 준비해서 동작하는지 확인합니다.도움이 됐으면 좋겠다.
언급URL : https://stackoverflow.com/questions/10634058/wordpress-prepared-statement-with-in-condition
'programing' 카테고리의 다른 글
Oracle이 존재하지 않는 테이블 또는 뷰를 알려주지 않는 이유는 무엇입니까? (0) | 2023.02.27 |
---|---|
DataTable을 다시 초기화할 수 없음 - 데이터 테이블의 동적 데이터 (0) | 2023.02.27 |
Angular에서의 ng-repeat 루프 내의 ng-model 바인딩JS (0) | 2023.02.27 |
C# Oracle 파라미터화된 쿼리 - 심각하고 위험한 버그! (0) | 2023.02.27 |
기능에 대한 Jest Spy (0) | 2023.02.27 |