Chciałbym ograniczyć wyszukiwanie do znaków używanych w języku angielskim + cyfry. Powodem jest to, że patrząc na najwolniejsze zapytania w dzienniku mysql, które większość znalazłem, pochodzą z wyszukiwań znaków arabskich, rosyjskich i chińskich, więc chciałbym je pominąć i zamiast tego wyświetlić komunikat o błędzie.
9
Odpowiedzi:
To rozwiązanie filtruje ciągi wyszukiwania, stosując wyrażenie regularne, które pasuje tylko do znaków ze skryptów Unicode Common i Latin.
Dopasowywanie znaków łacińskich do wyrażeń regularnych
Właśnie przeleciał mi umysł w Stack Overflow . Jak się okazuje, wyrażenia regularne mają mechanizm dopasowywania całych kategorii Unicode, w tym wartości określających całe „skrypty” Unicode , z których każdy odpowiada grupom znaków używanych w różnych systemach pisania.
Odbywa się to za pomocą
\p
meta-znaku, po którym następuje nawias identyfikujący kategorię Unicode w nawiasach klamrowych - więc[\p{Common}\p{Latin}]
pasuje do pojedynczego znaku w skrypcie łacińskim lub wspólnym - obejmuje to znaki interpunkcyjne, cyfry i różne symbole.Jak wskazuje @Paul „Sparrow Hawk” Biron ,
u
flaga modyfikatora wzorca powinna być ustawiona na końcu wyrażenia regularnego, aby funkcje PCRE PHP mogły traktować ciąg znaków jakoUTF-8
kodowany w Unicode.Wszystko razem więc wzór
dopasuje cały ciąg złożony z jednego lub więcej znaków w skryptach Latin i Common Unicode.
Filtrowanie wyszukiwanego ciągu
Dobrym miejscem do przechwytywania ciąg wyszukiwania jest działanie jak pożary bezpośrednio przed WordPress wykonuje zapytanie. Z większą ostrożnością można to również osiągnąć za pomocą filtra .
pre_get_posts
request
Reagowanie na niedozwolone wyszukiwania
Po ustaleniu, że ciąg wyszukiwania zawiera znaki spoza alfabetu łacińskiego, możesz użyć go
WP_Query::set()
do zmodyfikowania zapytania poprzez zmianę jego nazwanych zmiennych zapytania - wpływając w ten sposób na zapytanie SQL, które WordPress następnie tworzy i wykonuje.Najbardziej odpowiednie zmienne zapytania są prawdopodobnie następujące:
s
jest zmienną zapytania odpowiadającą wyszukiwanemu ciągowi. Ustawienie go nanull
lub pusty ciąg znaków (''
) spowoduje, że WordPress przestanie traktować zapytanie jako wyszukiwanie - często powoduje to, że szablon archiwum wyświetla wszystkie posty lub stronę główną witryny, w zależności od wartości innych zapytania zmienne. Ustawienie go na pojedynczą spację (' '
) spowoduje jednak, że WordPress rozpozna go jako wyszukiwanie, a zatem spróbuje wyświetlićsearch.php
szablon.page_id
może zostać wykorzystany do przekierowania użytkownika na wybraną stronę.post__in
może ograniczyć zapytanie do określonego wyboru postów. Ustawienie go na tablicę z niemożliwym identyfikatorem postu może służyć jako miara zapewniająca, że zapytanie nie zwróci absolutnie niczego .Mając powyższe na uwadze, możesz wykonać następujące czynności, aby odpowiedzieć na złe wyszukiwanie, ładując
search.php
szablon bez wyników:Wyświetlanie błędu
Sposób, w jaki faktycznie wyświetlasz komunikat o błędzie, zależy w dużej mierze od Twojej aplikacji i możliwości motywu - można to zrobić na wiele sposobów. Jeśli motyw wywołuje się
get_search_form()
w szablonie wyszukiwania, najłatwiejszym rozwiązaniem jest prawdopodobnie użycie haka dopre_get_search_form
działania, aby wyświetlić błąd bezpośrednio nad formularzem wyszukiwania:Niektóre inne możliwości wyświetlania komunikatu o błędzie obejmują:
wp_enqueue_script
haczyk z$priority
większym niż ten, który kolejkuje ten JavaScript, i użyj,wp_localize_script()
aby ustawić tę zmienną tak, aby zawierała komunikat o błędzie.wp_redirect()
do wysyłania użytkownika na wybrany adres URL (ta metoda wymaga dodatkowego ładowania strony).s
zmienną zapytania na''
zamiast' '
i użyjpage_id
zamiastpost__in
, aby zwrócić wybraną stronę.loop_start
haka, aby wstrzyknąć fałszywyWP_Post
obiekt zawierający błąd do wyników zapytania - jest to zdecydowanie brzydki hack i może nie wyglądać dobrze z określonym motywem, ale ma potencjalnie pożądany efekt uboczny polegający na pomijaniu komunikatu „Brak wyników”.template_include
haka filtru, aby zamienić szablon wyszukiwania na niestandardowy w motywie lub wtyczce, który wyświetla błąd.Bez zbadania omawianego tematu trudno jest ustalić, którą trasę należy obrać.
źródło
Zrobiłbyś to, wprowadzając funkcję sprawdzania poprawności w PHP, aby przetestować dane wejściowe względem wyrażenia regularnego, takiego jak
^[a-zA-Z0-9,.!?' ]*
Więc wyglądałoby to tak:
RexEx użyłem dla wszystkich znaków
A-Z
,a-z
,0-9
jak również,
,.
,!
,?
,'
,"
, i(spacja).
źródło
EDYCJA: To rozwiązanie nie jest zalecane
Jednym ze sposobów zapobiegania wyszukiwaniu przy użyciu alfabetów innych niż łacińskie jest użycie funkcji PHP,
mb_detect_encoding()
aby sprawdzić, czy szukany ciąg znaków jest zgodny z jednym z niestandardowego wyboru kodowania znaków. Dobrym miejscem do tego jest działanie , jak pożary tuż przed wykonaniem zapytania.pre_get_posts
To, co faktycznie robisz po ustaleniu, że używasz nieprawidłowego kodowania, jest tak naprawdę specyficzne dla aplikacji. Tutaj ustawiłem zapytanie do pojedynczej spacji, aby upewnić się, że WordPress nadal interpretuje zapytanie jako wyszukiwanie, a tym samym nadal ładuje
search.php
szablon (i nie kieruje użytkownika do pierwszej strony, jak to się dzieje, gdy ciąg wyszukiwania jest pusty ciąg). Podejmuję również dodatkowe środki ostrożności ,'post__in'
aby ustawić tablicę z niemożliwym identyfikatorem postu, aby mieć pewność, że absolutnie nic nie zostanie zwrócone .Alternatywnie możesz rozważyć ustawienie ciągu wyszukiwania na
null
i ustawieniepage_id
, aby skierować użytkownika do strony z niestandardowym komunikatem o błędzie.Wybór kodowania
Napisałem test zasięgu porównujący niektóre fikcyjne łańcuchy w różnych alfabetach ze wszystkimi domyślnymi kodowaniami obsługiwanymi przez PHP . Nie jest idealny pod żadnym względem (nie mam pojęcia, jak realistyczne są moje smoczkie struny i wydaje się, że dusi się po japońskim wykryciu), ale jest nieco przydatny do określania kandydatów. Możesz to zobaczyć tutaj w akcji .
Po zbadaniu potencjalnych kodowań znaków oznaczonych przez ten test wydaje się, że
Windows-1252
jest to idealny wybór dla twoich potrzeb, obejmujący alfabet łaciński, a także akcenty dla popularnych języków łacińskich.Wybór
ISO-8859
zestawów znaków powinien być kolejnym wykonalnym wyborem, jednak z powodów, dla których nie mogę się obejść,mb_
funkcje nie wydają się rozróżniaćISO-8859
różnych zestawów znaków, mimo że wymieniają je jako osobne kodowania.Aby zezwolić na niektóre inne popularne znaki, możesz również rozważyć dodanie
HTML-ENTITIES
.źródło
ISO-8859
jest w stanie odróżnić kodowania .Jak próbowałem wyjaśnić @MichaelRogers, gdy kilka dni temu napisał podobne pytanie, znajomość zestawu znaków (lub skryptu) użytego w ciągu nie jest wystarczająca do wykrycia języka tego ciągu.
Tak więc, podczas gdy sposób szczegółowy przez @bosco będzie usunąć rosyjsku itd łańcuchy (z poprawkami 2 poniżej), będzie NIE ograniczyć swoje wyszukiwania na angielski.
Aby to zobaczyć, spróbuj:
[ Uwaga: 2 wyżej wymienione poprawki do tego, co podał @bosco to:
/u
modyfikator (wymagany do traktowania wzorca i tematu jako kodowanego w UTF-8, patrz PHP: Modyfikatory wzorca regex ]który wytworzy:
[ uwaga: mówię po angielsku, francusku i trochę po niemiecku (i trochę Lorem ipsum :-), ale polegałem na Tłumaczu Google dla języka arabskiego, rosyjskiego i chińskiego]
Jak widać, poleganie na sprawdzeniu skryptu łacińskiego NIE gwarantuje, że znasz angielski.
StackOverflow ma wiele wątków (np. Wykryj język z łańcucha znaków w PHP ), które dostarczają więcej informacji na ten temat.
źródło