2014-10-22 14 views
8

używam laravel 4 i utworzyły następujące zapytanie:Ucieczka ciąg do użytku w MySQL pełnotekstowego wyszukiwania

if(Input::get('keyword')) { 
    $keyword = Input::get('keyword'); 
    $search = DB::connection()->getPdo()->quote($keyword); 
    $query->whereRaw("MATCH(resources.name, resources.description, resources.website, resources.additional_info) AGAINST(? IN BOOLEAN MODE)", 
     array($search) 
    ); 
} 

Ta kwerenda działa poprawnie w warunkach normalnego użytkowania, jednak, jeśli użytkownik wprowadzi ciąg takich jak ++ , generowany jest błąd. Patrząc na MySQl docs, są pewne słowa kluczowe, takie jak + i -, które mają określone cele. Czy istnieje funkcja, która uniknie tych typów znaków specjalnych z ciągu znaków, aby można go było zastosować w wyszukiwaniu pełnotekstowym, jak wyżej, bez powodowania błędów?

Oto przykład błędu, który jest wyrzucany:

{"error":{"type":"Illuminate\\Database\\QueryException","message":"SQLSTATE[42000]: Syntax error or access violation: 1064 syntax error, unexpected '+' (SQL: select * from `resources` where `duplicate` = 0 and MATCH(resources.name, resources.description, resources.website, resources.additional_info) AGAINST('c++' IN BOOLEAN MODE))","file":"\/var\/www\/html\/[...]\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Connection.php","line":555}} 

Solutions Próbowałem:

$search = str_ireplace(['+', '-'], ' ', $keyword); 

$search = filter_var($keyword, FILTER_SANITIZE_STRING); 

$search = DB::connection()->getPdo()->quote($keyword); 

Jestem zakładając, będę musiał użyć wyrażenia regularnego. Jakie jest najlepsze podejście?

+0

Będziesz chciał uciec z tego zamiast usunąć. – rmobis

+0

Dobrze, byłoby lepiej. Czy są jakieś funkcje, które nie zawierają znaków specjalnych, takich jak '+' i '-'? – chipit24

+0

Ale jeśli te znaki specjalne są chronione, czy będą przydatne w wyszukiwaniu? – chipit24

Odpowiedz

32

Tylko słowa i operatory mają znaczenie w trybie wyszukiwania Boolean. Operatorzy są: +, -, > <, (), ~, *, ", @distance. Po pewnym badaniu znalazłem, jakie są znaki: Wielkie litery, Małe litery, Cyfra (cyfra) i _. Myślę, że możesz użyć jednego z dwóch podejść:

  1. Zastąp wszystkie spacje bez słów spacjami (preferuję to podejście). Można to osiągnąć z regex:

    $search = preg_replace('/[^\p{L}\p{N}_]+/u', ' ', $keyword); 
    
  2. zamienić znaki-operatorów ze spacjami:

    $search = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $keyword); 
    

Tylko słowa są indeksowane przez wyszukiwarkę pełnego tekstu i mogą być przeszukiwane. Znaki niebędące słowami nie są indeksowane, więc nie ma sensu pozostawić ich w ciągu wyszukiwania.

Odniesienia:

Powiązane problemy