2014-10-22 4 views
8

ich verwende Laravel 4 und haben die folgende Abfrage ein:Escape-Strings für die Verwendung in MySQL Volltextsuche

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) 
    ); 
} 

Diese Abfrage läuft gut bei normalem Gebrauch jedoch, wenn der Benutzer eine Zeichenfolge wie ++ eintritt , ein Fehler wird ausgelöst. Betrachtet man die MySQl docs, gibt es einige Schlüsselwörter, wie + und -, die bestimmte Zwecke haben. Gibt es eine Funktion, die diese Art von Sonderzeichen aus einer Zeichenfolge entfernt, so dass es in einer Volltextsuche wie oben verwendet werden kann, ohne irgendwelche Fehler zu werfen? Hier

ist ein Beispiel für einen Fehler, der ausgelöst wird:

{"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}} 

Lösungen Ich habe versucht:

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

$search = filter_var($keyword, FILTER_SANITIZE_STRING); 

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

Ich nehme ich muss Regex verwenden. Was ist der beste Ansatz hier?

+0

Sie möchten lieber entkommen als entfernen. – rmobis

+0

Richtig, das wäre besser. Gibt es Funktionen, die Sonderzeichen wie '+' und '-' entziehen? – chipit24

+0

Aber wenn diese Sonderzeichen maskiert sind, werden sie bei der Suche nützlich sein? – chipit24

Antwort

32

Im Booleschen Suchmodus haben nur die Wörter und Operatoren Bedeutung. Die Betreiber sind: +, -, > <, (), ~, *, ", @distance. Nach einigen Nachforschungen fand ich, welche Wortzeichen sind: Großbuchstaben, Kleinbuchstaben, Ziffer (Ziffer) und _. Ich denke, dass Sie eine von zwei Ansätze verwenden:

  1. Ersetzen Sie alle nicht Wort Zeichen mit Leerzeichen (ich ziehe diesen Ansatz). Dies kann mit regex erreicht werden:

    $search = preg_replace('/[^\p{L}\p{N}_]+/u', ' ', $keyword); 
    
  2. ersetzen Zeichen-Operatoren mit Leerzeichen:

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

Nur Wörter werden durch Volltext-Suchmaschine indiziert und können durchsucht werden. Nicht-Wortzeichen werden nicht indiziert, daher ist es nicht sinnvoll, sie in der Suchzeichenfolge zu belassen.

Referenzen: