WHERE 절을 사용하여 쿼리에 배열 전달하기
PHPWHERE 절을 사용하여 쿼리에 배열 전달하기
주어진 배열의 ID $ galleries = array (1,2,5) WHERE 절에서 배열 값을 사용하는 SQL 쿼리를 원합니다.
SELECT *
FROM galleries
WHERE id = /* values of array $galleries... eg. (1 || 2 || 5) */
MySQL과 함께 사용할이 쿼리 문자열을 어떻게 생성 할 수 있습니까?
해결법
-
==============================
1.
$ids = join("','",$galleries); $sql = "SELECT * FROM galleries WHERE id IN ('$ids')";
-
==============================
2.
PDO 사용 : [1]
$in = join(',', array_fill(0, count($ids), '?')); $select = <<<SQL SELECT * FROM galleries WHERE id IN ($in); SQL; $statement = $pdo->prepare($select); $statement->execute($ids);
MySQLi 사용하기 [2]
$in = join(',', array_fill(0, count($ids), '?')); $select = <<<SQL SELECT * FROM galleries WHERE id IN ($in); SQL; $statement = $mysqli->prepare($select); $statement->bind_param(str_repeat('i', count($ids)), ...$ids); $statement->execute(); $result = $statement->get_result();
설명:
일반적으로 다음과 같이 보입니다.
expr IN (value,...)
배열에서 () 안에 배치 할 수식을 만들 수 있습니다. 괄호 안에 적어도 하나의 값이 있어야합니다. 그렇지 않으면 MySQL은 오류를 반환합니다. 이것은 입력 배열에 적어도 하나의 값이 있는지 확인하는 것과 같습니다. SQL 삽입 공격을 방지하려면 먼저? 각 입력 항목에 대해 매개 변수가있는 쿼리를 만듭니다. 여기에 귀하의 ID를 포함하는 배열을 $ ids라고 가정합니다 :
$in = join(',', array_fill(0, count($ids), '?')); $select = <<<SQL SELECT * FROM galleries WHERE id IN ($in); SQL;
3 개의 항목 $ select의 입력 배열이 다음과 같이 나타납니다.
SELECT * FROM galleries WHERE id IN (?, ?, ?)
또 주목할 점은? 입력 배열의 각 항목에 대해 그런 다음 위에서 설명한대로 PDO 또는 MySQLi를 사용하여 쿼리를 준비하고 실행합니다.
바운드 매개 변수 때문에 문자열과 정수 사이에서 쉽게 변경할 수 있습니다. PDO의 경우 변경이 필요하지 않습니다. MySQLi 변경 str_repeat ( 'i', str_repeat ( 's', 문자열을 검사해야하는 경우.
[1] : 간결함을 위해 오류 검사를 생략했습니다. 각 데이터베이스 메서드에 대한 일반적인 오류를 확인하거나 예외를 throw하도록 DB 드라이버를 설정해야합니다.
[2] : PHP 5.6 이상이 필요합니다. 다시 한 번 간략하게 오류 검사를 생략했습니다.
-
==============================
3.
ints :
$query = "SELECT * FROM `$table` WHERE `$column` IN(".implode(',',$array).")";
문자열 :
$query = "SELECT * FROM `$table` WHERE `$column` IN('".implode("','",$array)."')";
-
==============================
4.
미리 입력 내용을 제대로 살균한다고 가정하면 ...
$matches = implode(',', $galleries);
그런 다음 쿼리를 조정하십시오.
SELECT * FROM galleries WHERE id IN ( $matches )
데이터 세트에 따라 적절하게 값을 인용하십시오.
-
==============================
5.
용도:
select id from galleries where id in (1, 2, 5);
각 루프에 대해 간단하게 작동합니다.
Flavius / AvatarKava의 방법이 더 좋지만 배열 값에 쉼표가 없는지 확인하십시오.
-
==============================
6.
Flavius Stef의 답은 intval ()을 사용하여 모든 ID가 int 값인지 확인할 수 있습니다.
$ids = join(',', array_map('intval', $galleries)); $sql = "SELECT * FROM galleries WHERE id IN ($ids)";
-
==============================
7.
이스케이프 기능이있는 MySQLi의 경우 :
$ids = array_map(function($a) use($mysqli) { return is_string($a) ? "'".$mysqli->real_escape_string($a)."'" : $a; }, $ids); $ids = join(',', $ids); $result = $mysqli->query("SELECT * FROM galleries WHERE id IN ($ids)");
준비된 진술서가있는 PDO의 경우 :
$qmarks = implode(',', array_fill(0, count($ids), '?')); $sth = $dbh->prepare("SELECT * FROM galleries WHERE id IN ($qmarks)"); $sth->execute($ids);
-
==============================
8.
SQL 인젝션 취약점과 빈 상태를 처리해야합니다. 나는 아래 둘을 다룰 것이다.
순수한 숫자 배열의 경우 적절한 유형 변환 즉 intval 또는 floatval 또는 doubleval을 각 요소 위에 사용하십시오. 원하는 경우 숫자 값에도 적용될 수있는 문자열 유형 mysqli_real_escape_string (). MySQL은 숫자와 날짜 변형을 문자열로 허용합니다.
쿼리에 전달하기 전에 값을 적절하게 이스케이프하려면 다음과 유사한 함수를 만듭니다.
function escape($string) { // Assuming $db is a link identifier returned by mysqli_connect() or mysqli_init() return mysqli_real_escape_string($db, $string); }
이러한 함수는 이미 응용 프로그램에서 이미 사용 가능할 수도 있고 이미 작성한 기능 일 수도 있습니다.
다음과 같이 문자열 배열을 살균하십시오.
$values = array_map('escape', $gallaries);
숫자 형 배열은 intval 또는 floatval 또는 doubleval을 대신 사용하여 위생 처리 될 수 있습니다 :
$values = array_map('intval', $gallaries);
마지막으로 쿼리 조건 작성
$where = count($values) ? "`id` = '" . implode("' OR `id` = '", $values) . "'" : 0;
또는
$where = count($values) ? "`id` IN ('" . implode("', '", $values) . "')" : 0;
$ gareries = array ();와 같이 배열도 때때로 비어있을 수 있기 때문에; 우리는 IN ()이 빈리스트를 허용하지 않는다는 것을 알아야한다. 대신 OR을 사용할 수도 있지만 문제는 여전히 남아 있습니다. 그래서 위의 검사 인 count ($ values)는 같은 것을 보장합니다.
마지막 쿼리에 추가하십시오.
$query = 'SELECT * FROM `galleries` WHERE ' . $where;
-
==============================
9.
안전한.
$galleries = array(1,2,5); array_walk($galleries , 'intval'); $ids = implode(',', $galleries); $sql = "SELECT * FROM galleries WHERE id IN ($ids)";
-
==============================
10.
입력 배열을 적절히 필터링하면이 "WHERE id IN"절을 사용할 수 있습니다. 이 같은:
$galleries = array(); foreach ($_REQUEST['gallery_id'] as $key => $val) { $galleries[$key] = filter_var($val, FILTER_SANITIZE_NUMBER_INT); }
아래 예와 같이 :
$galleryIds = implode(',', $galleries);
나는. 이제 안전하게 $ query = "SELECT * 갤러리에서 WHERE id IN ({$ galleryIds})";를 사용해야합니다.
-
==============================
11.
Col. Shrapnel의 PHP 용 SafeMySQL 라이브러리는 매개 변수가있는 쿼리에 유형 힌팅 된 자리 표시자를 제공하며 배열 작업을위한 편리한 자리 표시 자 두 개를 포함합니다. ? 자리 표시자는 배열을 쉼표로 구분 된 이스케이프 된 문자열 목록 *으로 확장합니다.
예 :
$someArray = [1, 2, 5]; $galleries = $db->getAll("SELECT * FROM galleries WHERE id IN (?a)", $someArray);
* MySQL이 자동 타입 강제 변환을 수행하기 때문에, SafeMySQL이 위의 id를 문자열로 변환하는 것은 중요하지 않습니다. 여전히 정확한 결과를 얻을 수 있습니다.
-
==============================
12.
테이블 텍스트 (T_ID (int), T_TEXT (텍스트)) 및 테이블 테스트 (id (int), var (varchar (255)))가있을 수 있습니다.
테스트 값 (1, '1,2,3')에 삽입; 다음은 테이블 텍스트에서 행을 출력합니다. T_ID IN (1,2,3) :
SELECT * FROM `texts` WHERE (SELECT FIND_IN_SET( T_ID, ( SELECT var FROM test WHERE id =1 ) ) AS tm) >0
이 방법을 사용하면 여분의 테이블없이 간단한 n2m 데이터베이스 관계를 관리하고 PHP 나 다른 프로그래밍 언어를 사용할 필요없이 SQL 만 사용할 수 있습니다.
-
==============================
13.
원래 질문은 숫자 배열과 관련이 있고 주어진 예제를 작동시킬 수없는 문자열 배열을 사용하고 있기 때문입니다.
각 문자열을 작은 따옴표로 묶어서 IN () 함수로 작업해야한다는 것을 알았습니다.
여기 내 해결책이있다.
foreach($status as $status_a) { $status_sql[] = '\''.$status_a.'\''; } $status = implode(',',$status_sql); $sql = mysql_query("SELECT * FROM table WHERE id IN ($status)");
보시다시피 첫 번째 함수는 각 배열 변수를 작은 따옴표 (\ ')로 묶은 다음 배열을 내삽합니다.
참고 : $ status에는 SQL 문에 작은 따옴표가 없습니다.
따옴표를 추가하는 것이 더 좋은 방법 일 수 있지만이 방법이 효과적입니다.
-
==============================
14.
IN 쿼리를 사용하는 것 외에도 IN 쿼리에 SQL 인젝션 취약점의 위험이 있으므로 두 가지 옵션이 있습니다. 루핑을 사용하여 원하는 정확한 데이터를 얻거나 OR 케이스와 함께 쿼리를 사용할 수 있습니다.
1. SELECT * FROM galleries WHERE id=1 or id=2 or id=5; 2. $ids = array(1, 2, 5); foreach ($ids as $id) { $data[] = SELECT * FROM galleries WHERE id= $id; }
-
==============================
15.
추가 예제 :
$galleryIds = [1, '2', 'Vitruvian Man']; $ids = array_filter($galleryIds, function($n){return (is_numeric($n));}); $ids = implode(', ', $ids); $sql = "SELECT * FROM galleries WHERE id IN ({$ids})"; // output: 'SELECT * FROM galleries WHERE id IN (1, 2)' $statement = $pdo->prepare($sql); $statement->execute();
-
==============================
16.
아래는 다른 데이터를 위해 명명 된 자리 표시자를 사용하여 PDO를 사용한 필자가 사용한 방법입니다. SQL 삽입을 극복하기 위해 배열을 필터링하여 정수 값만 허용하고 다른 모든 값은 거부합니다.
$owner_id = 123; $galleries = array(1,2,5,'abc'); $good_galleries = array_filter($chapter_arr, 'is_numeric'); $sql = "SELECT * FROM galleries WHERE owner=:OWNER_ID AND id IN ($good_galleries)"; $stmt = $dbh->prepare($sql); $stmt->execute(array( "OWNER_ID" => $owner_id, )); $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
==============================
17.
PDO가없는 안전한 방법 :
$ids = array_filter(array_unique(array_map('intval', (array)$ids))); if ($ids) { $query = 'SELECT * FROM `galleries` WHERE `id` IN ('.implode(',', $ids).');'; }
-
==============================
18.
SQL 삽입을 방지하는 기본 방법은 다음과 같습니다.
준비된 문과 매개 변수화 된 쿼리를 사용하는 것이 더 나은 방법이지만, 이스케이프 문자를 선택하면 아래 예를 시도 할 수 있습니다.
array_map을 사용하여 $ galleries의 각 요소에 작은 따옴표를 추가하여 쿼리를 생성 할 수 있습니다.
$galleries = array(1,2,5); $galleries_str = implode(', ', array_map(function(&$item){ return "'" .mysql_real_escape_string($item) . "'"; }, $galleries)); $sql = "SELECT * FROM gallery WHERE id IN (" . $galleries_str . ");";
생성 된 $ sql var은 다음과 같습니다.
SELECT * FROM gallery WHERE id IN ('1', '2', '5');
from https://stackoverflow.com/questions/907806/passing-an-array-to-a-query-using-a-where-clause by cc-by-sa and MIT lisence
'PHP' 카테고리의 다른 글
$ this 위에 자기를 사용할 때? (0) | 2018.09.03 |
---|---|
서 친절한 URL css img js 작동하지 않음 (0) | 2018.09.03 |
MySQLi에서 쿼리 오류를 예외로 변환 (0) | 2018.09.03 |
어떻게 PHP 응용 프로그램에서 멀티 스레딩을 사용할 수 있습니까? (0) | 2018.09.03 |
PHP + MySQL 트랜잭션 예제 (0) | 2018.09.03 |