LIKE 문을 사용하여 PDO 매개 변수화 된 쿼리를 어떻게 생성합니까?


107

내 시도는 다음과 같습니다.

$query = $database->prepare('SELECT * FROM table WHERE column LIKE "?%"');

$query->execute(array('value'));

while ($results = $query->fetch()) 
{
    echo $results['column'];
}

답변:


124

내가 게시 한 직후에 그것을 알아 냈습니다.

$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->execute(array('value%'));

while ($results = $query->fetch())
{
    echo $results['column'];
}

1
@Andrew : 다중 like을 사용하면 어떨까요? 실행 배열은 어떻게 순서대로 실행되어야합니까?
logan 2014

감사. csharp + Mysql + ODBC에서 "select * from table where column like '%? %';"를 사용하여 행을 반환하지 않는 것과 유사한 문제가 발생했습니다. 하지만 내가 "select * from table where column like?;" 다음과 같이 매개 변수 문자열을 설정합니다. string frag = $ "% {searchFragment} %"; 그런 다음 매개 변수 값으로 frag를 사용하십시오. 이상한
sdjuan

2
PDO는 실행 호출에서 해당 %를 이스케이프해야합니다. Kaqai의 대답은 더 나은
피터 Bagnall

그것은 가치가 최고 것을주의 보인다 사용자 - 기여 노트PDOStatement :: bindParam 문서 페이지 를 바인딩하기 전에 변수에 백분율 기호 (들)을 추가 제공하는 다른 접근 방식을.
Dan Robinson

이 스레드 하단 근처에있는 Your Common Sense 페이지에서 가져온 gavin의 솔루션을 살펴보십시오. 단순한. 논리적.
RationalRabbit

85

명명 된 매개 변수를 사용 하는 경우 MySQL 데이터베이스에 부분 일치 를 사용하는 방법은 다음 LIKE과 같습니다.%

WHERE column_name LIKE CONCAT ( '%', : dangerousstring, '%')

여기서 명명 된 매개 변수는 :dangerousstring입니다.

즉, %사용자 입력이 아닌 분리 된 자체 쿼리에서 명시 적으로 이스케이프 처리되지 않은 기호를 사용합니다.

편집 : Oracle 데이터베이스의 연결 구문 은 연결 연산자 : ||를 사용하므로 간단히 다음 과 같이됩니다.

WHERE column_name LIKE '%'|| : 위험한 문자열 || '%'

@bobince 언급 그러나주의 사항이 있습니다 여기에 있음 :

어려움은 당신이 문자 그대로 허용 할 경우 제공 %또는 _이 와일드 카드 역할을하지 않고, 검색 문자열에서 문자를.

그래서 그것은 like와 parameterization을 결합 할 때주의해야 할 것입니다.


6
+1-플레이스 홀더가 대체 된 후 데이터베이스에서 모든 연결이 발생하기 때문에 이것은 나에게 좋은 접근 방식으로 보이며, 이름이 지정된 플레이스 홀더를 사용할 수 있음을 의미합니다. 위의 구문은 Oracle 용이며 MySQL에서는 구문이 LIKE CONCAT('%', :something, '%'). 참조 : stackoverflow.com/a/661207/201648
Aaron Newton

1
이것은 나를 위해 정확히 작동하지 않았지만 올바른 방향으로 나아갔습니다. 나는 그것이 작동하기 위해 '%': 뭔가 '%'처럼해야했습니다.
크리스토퍼 스 미트

나는 이것이 주제에서 벗어난 것을 알고 있지만이 구문을 사용하여 SQL 주입을 수행 할 수 있었던 이유는 무엇입니까?
Thiago Dias

이것은 나를 위해 작동하지 않았으며 SQL 명령으로 테스트하여 SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )오류가 발생했습니다.
Luzan Baral

@AaronNewton and it means named placeholders can be used. PHP에서 연결할 때 이름이 지정된 자리 표시 자 문제가되는 이유는 무엇입니까? 분명히 PHP에서 연결은 모든 데이터베이스에 대해 동일한 쿼리를 사용할 수 있기 때문에 이름이 지정된 위치와 위치를 모두 지원하며 이식성이 뛰어납니다. 많은 사람들이 생각하는 이유를 정말 이해하지 못하는 어떤 이름과 위치 자리의 차이는.
상식

18
$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->bindValue(1, "%$value%", PDO::PARAM_STR);
$query->execute();

if (!$query->rowCount() == 0) 
{
    while ($results = $query->fetch()) 
    {
        echo $results['column'] . "<br />\n";
    }       
} 
else 
{
    echo 'Nothing found';
}

1
받아 들인 대답보다 이것을 사용하는 이점이 있습니까? 사용 bindValue은 주입 공격으로부터 보호 합니까 ? 받아 들여지는 대답은 기본적으로 ?검색 문자열을 %예전처럼 좋아 하도록 연결 하여 자리 표시자를 사용하는 값을 부정합니다 .
felwithe

$ query-> rowCount () == 0 전에 부정을 사용하는 요점은 무엇입니까? 이것이 실제로 의미가 있습니까?
ssi-anik

14

이것을 시도 할 수도 있습니다. 비슷한 문제에 직면했지만 연구 결과를 얻었습니다.

$query = $pdo_connection->prepare('SELECT * FROM table WHERE column LIKE :search');

$stmt= $pdo_connection->prepare($query);

$stmt->execute(array(':search' => '%'.$search_term.'%'));

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($result);

코드 블록에 코드를 삽입하도록 게시물을 편집했습니다 . 게시물 형식에 대한 자세한 내용은 stackoverflow.com/help/formatting 에서 읽을 수 있습니다 . 다른 사용자가 댓글을 남기지 않고 귀하의 답변에 반대 투표를 선택했기 때문에 반대 투표의 원인을 잘 모르겠습니다.
josliber

2
다시 말씀 드리지만 저는 귀하의 질문에 투표하지 않았습니다. 누군가 반대표를 던졌습니다.
josliber

3

이것은 작동합니다 :

search `table` where `column` like concat('%', :column, '%')

2

나는 PHP 망상 에서 이것을 얻었다

$search = "%$search%";
$stmt  = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
$stmt->execute([$search]);
$data = $stmt->fetchAll();

저에게는 매우 간단합니다. 그가 말했듯이 쿼리로 보내기 전에 "전체 리터럴을 먼저 준비"해야합니다.


0

PDO는 "%"를 이스케이프합니다 (SQL 주입으로 이어질 수 있음) : 이전 코드를 사용하면 부분 문자열과 일치하려고 할 때 원하는 결과를 얻을 수 있지만 방문자가 "%"문자를 입력하면 그렇지 않더라도 결과를 얻을 수 있습니다. t 데이터베이스에 저장된 모든 것이 있음 (SQL 주입이 발생할 수 있음)

동일한 결과로 많은 변형을 시도해 보았습니다. PDO가 "%"를 벗어나 원치 않는 / 원치 않는 검색 결과를 선도하고 있습니다.

나는 누군가가 주변에 단어를 발견하면 나눌 가치가 있었지만 그것을 공유하십시오


1
이 수동에서입니다 : us3.php.net/manual/en/pdo.prepared-statements.php 이 주제에 대한 다른 게시물은 다음과 같습니다 stackoverflow.com/questions/22030451/... 내가 owuld 정말에 대한 귀하의 의견을 알고 싶다 이 문제.
Ozkar R 2015

1
가능한 해결책 (테스트되지 않음) 다음 과 같이 CONCAT 사용 : $ sql =“SELECT item_title FROM item WHERE item_title LIKE CONCAT ( '%',?, '%') "; 참조 : blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
Ozkar R

3
PDO는 %를 이스케이프하지 않습니다. 잘못하는 것은 코드입니다. 솔루션에 대해서는 이미 여기에 제공된 답변
Your Common Sense

제안 해 주셔서 감사합니다. 어쨌든 테스트 된 코드는 SQL 주입을 피하기 위해 자리 표시자를 사용하는 매뉴얼의 코드 였지만 여전히 동일한 결과를 얻고 있습니다. 예제 # 6 자리 표시 자의 잘못된 사용은 내 코드가 아닌 위 코드를 사용하여 %를 이스케이프합니다. 저는 포럼을 처음 사용하고 댓글, 게시물 및 평판의 프로세스가 여기에서 어떻게 작동하는지 이해하지 못할 수 있습니다. 이전 댓글을 기반으로 다른 사람을 돕거나 댓글을 달려면 평판이 필요하기 때문에 다음 작업을 위해 염두에 두겠습니다. 감사.
Ozkar R
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.