Abgleich von “geschweiften” Anführungszeichen mit Standard-Anführungszeichen in der DB-Abfrage
Lesezeit: 5 Minuten
Henrik Petterson
Ich habe Text in gespeichert post_title Säule:
you’re
Mit dieser Abfrage:
function ma_post_title_filter($where, &$wp_query) {
global $wpdb;
if ( $search_term = $wp_query->get( 'ma_search_post_title' ) ) {
$search_term = sanitize_text_field($search_term);
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . $wpdb->esc_like( $search_term ) . '%\'';
}
return $where;
}
Wenn $search_term ist you’re, es funktioniert und findet die Spalte. Aber wenn es so ist you'refunktioniert es nicht (weil es ein anderes einfaches Anführungszeichen ist).
Wie kann ich die Abfrage so verbessern beides you’re und you're Übereinstimmungen mit you’re?
Was ich bisher probiert habe
Verwenden str_replace() an $search_term ersetzen ' mit ’. Beispiel: str_replace('\'','’',$wpdb->esc_like( $search_term ))… das Problem bei diesem Ansatz ist, dass wir niemals übereinstimmen, wenn die gespeicherte Spalte ist you're.
Tun AND REPLACE an '.$wpdb->posts.'.post_title ersetzen ' mit ’… scheint aber nicht zu funktionieren.
Mir ist bewusst, dass die ideale Lösung darin besteht, alle Datenbankinstanzen des einfachen Zitats auf ein Standardangebot anzupassen, aber dies ist in meinem Fall nicht möglich.
Was ist die richtige Lösung dafür?
Das Was ich bisher probiert habe Abschnitt ist schön. Sollte hier Standard sein. +1
– Gary Woods
21. November 2018 um 14:45 Uhr
Probs nicht geeignet, da man nicht weiß, ob das immer der Suchbegriff ist, also habe ich den Kommentar gelöscht 😉
– Adam
21. November 2018 um 14:48 Uhr
Hast du versucht zu ersetzen ’ mit ' da ist dein Muster '.post_title LIKE \'%'?
– forpas
21. November 2018 um 14:55 Uhr
@forpas Wann genau ersetzen? Bitte sehen Sie sich meine beiden Beispielansätze und Hinweise an, warum es nicht funktioniert hat. Vielen Dank.
– Henrik Petterson
21. November 2018 um 14:56 Uhr
Dein Muster ist folgendes: '.post_title LIKE \'%' was bedeutet, dass Sie versuchen, mit abzugleichen ', Rechts? Sie bewerben sich also str_replace('’', ''', $search_term).
– forpas
21. November 2018 um 15:07 Uhr
Mike32
Darauf wollte ich hinweisen % ist nicht der einzige Platzhalter, der verwendet werden kann LIKE Abfragen. Sie können den Unterstrich verwenden _ um auch ein einzelnes Zeichen anzuzeigen. Ein Ansatz könnte darin bestehen, jedes Satzzeichen in einer bestimmten Klasse durch einen Unterstrich zu ersetzen. Dies würde ermöglichen, dass “you’re” mit “you’re” übereinstimmt und umgekehrt. (Zugegeben, es würde auch “youvre” erlauben, zu passen!)
<?php
function ma_post_title_filter($where, &$wp_query) {
global $wpdb;
$punct = ["’", "‘", "”", "“"];
if ( $search_term = $wp_query->get( 'ma_search_post_title' ) ) {
// escape any % or _ characters
$search_term = $wpdb->esc_like($search_term);
// replace desired punctuation characters with _
$search_term = str_replace($punct, "_", $search_term);
// do final escaping for safe queries
$search_term = $wpdb->_real_escape($search_term);
// this looks much neater with string interpolation vs concatenation
$where .= " AND $wpdb->posts.post_title LIKE '%$search_term%'";
}
return $where;
}
Sie sollten beim Übergeben von Werten an a LIKE Klausel, verwenden wpdb::esc_like() um sicherzustellen, dass vom Benutzer bereitgestellte Prozentzeichen oder Unterstriche den Dingen nicht im Wege stehen. sanitize_text_field() soll vor der Ausgabe in HTML verwendet werden und tut nichts, um Text für eine Datenbankabfrage sicher zu machen. Das ist, was wpdb::_real_escape() ist für.
Vielen Dank für den hervorragenden Ansatz, aber es funktioniert nicht. Ist ein Tippfehler drin $where? Hier ist ein Beispielcode mit dem kannst du das testen. Ich denke, das Problem ist wahrscheinlich ein Tippfehler, da der Code selbst sehr logisch ist!
– Henrik Petterson
22. November 2018 um 10:42 Uhr
Entferne den $wpdb->real_escape($search_term); Teil scheinen zumindest die Ausführung des Codes zu ermöglichen. Aber $string_term = "you're";stimmt immer noch nicht mit einem Beitrag mit Titel überein you’re.
– Henrik Petterson
22. November 2018 um 10:51 Uhr
Ich habe keine Möglichkeit, dies zu testen, aber ich würde vorschlagen, es auszudrucken $search_term an verschiedenen Stellen durch den Code, und dasselbe tun, um zu sehen, was $where sieht aus wie.
OP sagte bereits, dass sie die vorhandenen Daten nicht ändern, aber verwenden können RLIKE ist eine gute Idee; Sie sollten Ihren Beitrag bearbeiten, um Ihren Code besser lesbar zu machen, und er sollte einige Upvotes erhalten.
– Mike32
21. November 2018 um 18:00 Uhr
Cid
Ich würde zweimal a verwenden LIKE -Anweisung, eine mit dem ursprünglichen Suchbegriff, die zweite mit einem Ersatz für die ' durch ’
Sie können parametrisierte Abfragen verwenden. Zum Beispiel mit wpdb::prepare() :
$searchTerm = "You're"; //Don't sanitize using a function, this will by done with parameters.
// query
$where .= ' AND ('. $wpdb->posts .'.post_title LIKE %s OR '. $wpdb->posts .'.post_title LIKE %s)'; //Notice the double %s
//I suppose $where contains your whole query
$sth = $wpdb->prepare($where, '%' . $searchTerm . '%', '%' . str_replace('’', '\'', $search_term) . '%'); //This will associate the %s (a string) in the query by the value indicated in the function
$wpdb->query($sth);
Das %s ist ein Platzhalter in der Abfrage, um anzuzeigen $wpdb->prepare() dass es an dieser Stelle eine Schnur geben wird.
Danke, aber können Sie Ihre Antwort freundlicherweise mit Beispielen bearbeiten, wie Sie meinen spezifischen Code an Ihren Ansatz anpassen können?
@GaryWoods danke, ich habe meine Antwort an diese Situation angepasst
– Cid
21. November 2018 um 15:07 Uhr
Ja, die Verwendung vorbereiteter Anweisungen ist immer der beste Ansatz, aber WordPress macht dies sehr schwierig. Die Funktion in der ursprünglichen Frage wird von WP dynamisch angewendet, wenn es sich um eine Suchanfrage handelt, sodass die eigentliche Ausführung an anderer Stelle erfolgt.
– Mike32
21. November 2018 um 17:49 Uhr
13507100cookie-checkAbgleich von “geschweiften” Anführungszeichen mit Standard-Anführungszeichen in der DB-Abfrageyes
Das Was ich bisher probiert habe Abschnitt ist schön. Sollte hier Standard sein. +1
– Gary Woods
21. November 2018 um 14:45 Uhr
Probs nicht geeignet, da man nicht weiß, ob das immer der Suchbegriff ist, also habe ich den Kommentar gelöscht 😉
– Adam
21. November 2018 um 14:48 Uhr
Hast du versucht zu ersetzen
’
mit'
da ist dein Muster'.post_title LIKE \'%'
?– forpas
21. November 2018 um 14:55 Uhr
@forpas Wann genau ersetzen? Bitte sehen Sie sich meine beiden Beispielansätze und Hinweise an, warum es nicht funktioniert hat. Vielen Dank.
– Henrik Petterson
21. November 2018 um 14:56 Uhr
Dein Muster ist folgendes:
'.post_title LIKE \'%'
was bedeutet, dass Sie versuchen, mit abzugleichen'
, Rechts? Sie bewerben sich alsostr_replace('’', ''', $search_term)
.– forpas
21. November 2018 um 15:07 Uhr