2011-07-27 3 views
0

PHP와 PDO로 간단한 전체 텍스트 검색을 작성하려고합니다. 가장 좋은 방법은 SQL과 PDO를 통해 DB를 검색하는 것입니다. 이 this 스크립트를 찾았지만 이전 MySQL 확장입니다. 이 기능 마녀는 검색 일치를 계산해야한다고 썼지 만 SQL은 작동하지 않습니다. 이 같은 들어오는 검색 문자열의 모습 :PHP와 PDO를 사용한 SQL 전체 텍스트 검색

array('queryString' => $value); 

가 있어야한다 : 23+more+people

function checkSearchResult ($searchterm) { 
    //globals 
    global $lang; global $dbh_pdo; global $db_prefix; 
    $searchterm = trim($searchterm); 
    $searchterm = explode('+', $searchterm); 
    foreach ($searchterm as $value) { 
     $sql = "SELECT COUNT(*), MATCH (article_title_".$lang.", article_text_".$lang.") AGINST (':queryString') AS score FROM ".$db_prefix."_base WHERE MATCH (article_title_".$lang.", article_text_".$lang.") AGAINST ('+:queryString')"; 
     $sth = $dbh_pdo->prepare($sql); 
     $sql_data = array('queryString' => $value); 
     $sth->execute($sql_data); 
     echo $sth->queryString; 
     $row = $sth->fetchColumn(); 
     if ($row < 1) { 
      $sql = "SELECT * FROM article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString"; 
      $sth = $dbh_pdo->prepare($sql); 
      $sql_data = array('queryString' => $value); 
      $sth->execute($sql_data); 
      $row = $sth->fetchColumn(); 
     } 
    } 
    //$row stays empty - no idea what is wrong 
    if ($row > 1) { 
     return true; 
    } 
    else { 
     return false; 
    } 
} 

답변

2

당신이 $sql_data 배열을 준비 할 때 콜론 매개 변수 이름을 접두사 필요가

array(':queryString' => $value); 

첫 번째 SELECT에는 AGAINST 대신 AGINST이 있습니다.

두 번째 SELECTFROMWHERE 절 뒤에 테이블 이름이 누락 된 것으로 보입니다. LIKE 매개 변수의 형식이 잘못되었습니다. 그것은해야 뭔가 같은 :

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE '%:queryString%' OR aricle_text_".$lang." LIKE '%:queryString%'"; 

업데이트 1 >>

하지 모두SELECT 문의 경우, 각 매개 변수에 대한 고유 식별자를 필요로하고, LIKE 와일드 카드 값에 배치해야 그 진술. 그래서 두 번째 문장은 다음과 같아야합니다

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString2"; 

queryString1queryString2을 따옴표 또는 % 와일드 카드없이. 당신은 너무 당신의 배열을 업데이트해야합니다 :

$sql_data = array(':queryString1' => "%$value%", ':queryString2' => "%$value%"); 

가 같은 값으로 여러 매개 변수를 사용하는 방법에 대한 자세한 내용은 PDOStatement->execute매개 변수 섹션을 참조하십시오. 이 때문에 명명 된 매개 변수 대신 물음표를 자리 표시 자로 사용하는 경향이 있습니다. 나는 그것이 더 간단하고 깔끔하다는 것을 알았지 만 그것은 선택의 문제이다. 업데이트 1

내가 처음 SELECT 쿼리를 찾지 못한 경우라고 생각했을 나는이 두 번째 SELECT가 무엇인지 잘 모르겠습니다의

sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE ? OR aricle_text_".$lang." LIKE ?"; 

$sql_data = array("%$value%", "%$value%"); 

< < 종료 : 예를 들어, 두 번째 값도 찾지 못합니다. 하지만 MySQL 전체 텍스트 검색을 많이하지 않았으므로 뭔가가 누락되었을 수 있습니다.

어쨌든 SQL과 오류를 신중하게 확인해야합니다.언급이 >>

또 다른 지점의 가치

$sth->execute($sql_data); 
$arr = $sth->errorInfo(); 
print_r($arr); 

업데이트 : 당신은 PDOStatement->errorCode의 결과를 인쇄하여 오류 정보를 얻을 수있는 경우에만 사용하는 것이, 당신은 당신의 SQL 문에 변수를 보간하는 경우 있는지 확인 신뢰할 수있는 데이터. 즉, 테이블 또는 열 이름에 사용자가 제공 한 데이터를 사용하지 마십시오. 준비된 문을 사용하는 것은 좋지만 SQL 키워드, 테이블 이름 및 열 이름이 아닌 매개 변수 만 보호합니다. 따라서 :

"SELECT * FROM ".$db_prefix."_base" 

... 변수가 테이블 이름의 일부로 사용됩니다. 이 변수에 신뢰할 수있는 데이터가 포함되어 있는지 확인하십시오. 사용자 입력에서 오는 경우 먼저 허용 목록과 비교하여 확인하십시오.

업데이트 1의

< < 끝 당신은 MySQL Full-Text Search Functions하고 String Comparison Functions을 읽어야합니다. 기본 SQL 문을 작성하는 방법을 배워야합니다. 그렇지 않으면 단순한 검색 엔진조차 작성하는 것이 매우 어려울 것입니다.

PHP 사이트에는 PDO 예제가 많이 있습니다. 이 기능을 사용하는 방법에 대한 몇 가지 예가 들어있는 PDOStatement->execute 설명서부터 시작할 수 있습니다.

MySQL CLI 또는 심지어 PHPMyAdmin에 액세스 할 수 있으면 모든 PHP 혼란스러운 일없이 SQL을 시험해 볼 수 있습니다. PHP 응용 프로그램의 일부로 데이터베이스 개발 작업을 수행하려는 경우 PHP와 별개로 SQL을 테스트 할 수 있다는 것을 알게 될 것입니다.

+0

자세한 답변을 보내 주셔서 감사합니다. 그에 따라 SQL을 변경하고 MySQL 관련 MATCH 연산을 삭제했습니다. 나는로부터 SELECT COUNT (*) \t \t \t'에 SQL을 변경 ". $ db_prefix."_ 기본 \t \t \t article_content_title _ ". $ LANG." \t \t \t LIKE '% 쿼리 문자열 %' \t \t \t 또는 \t \t \t article_content_text _ "$ LANG.." \t \t \t LIKE '% : queryString %' '하지만'queryString '은 대체되지 않습니다. 위와 같은 코드이지만 지적한 구문 오류가 수정되었습니다. 왜 그런가? – wowpatrick

+0

@wowpatrick :'queryString'이 대체되지 않는다고 말할 때, 명령문을 echo 할 때 매개 변수 (': queryString' 부분)가 사용자가 제공 한 문자열로 대체되지 않았다는 것을 의미합니까? 그렇다면 준비된 명령문이 작동하는 방법입니다. 명령문과 매개 변수는 MySQL에 개별적으로 전송됩니다. 클라이언트 (이 경우 PHP)는 두 개를 결합하지 않습니다. 그것들은 개별적으로 보내지기 때문에, MySQL은 어떤 비트가 명령문이고 어떤 비트가 매개 변수인지 알고 있으므로 알아 내기 위해 구문 분석 할 필요가 없습니다. 이것이 SQL 주입에 대한 좋은 방어책 인 이유입니다. – Mike

+0

@wowpatrick : 결합 된 명령문을 보려면 [MySQL 일반 쿼리 로그] (http://dev.mysql.com/doc/refman/5.5/en/query-log.html)를 확인하십시오. 기본적으로 사용 중지되어 있으므로 문서를 먼저 읽고 사용 설정 방법을 확인하십시오. 또한 발생할 수있는 오류를 표시하기 위해 PHP 코드에 행을 추가 했습니까? – Mike