Я хотел бы ограничить поиск символами, используемыми на английском языке + цифры. Причина в том, что, глядя на самые медленные запросы в журнале mysql, которые я нашел больше всего, они приходят из запросов на арабские, русские и китайские символы, поэтому я хотел бы пропустить их и вместо этого отобразить сообщение об ошибке.
9
Ответы:
Это решение фильтрует строки поиска путем применения регулярного выражения, которое соответствует только символам из сценариев Common и Latin Unicode.
Сопоставление латинских символов с регулярными выражениями
Я только что заболел умом в переполнении стека . Как выясняется, регулярные выражения имеют механизм для сопоставления целых категорий Юникода, включая значения для указания целых «сценариев» Юникода , каждый из которых соответствует группам символов, используемых в разных системах письма.
Это делается с помощью
\p
метасимвола, за которым следует идентификатор категории Юникод в фигурных скобках - так что[\p{Common}\p{Latin}]
соответствует одному символу в латинских или общих сценариях - это включает знаки препинания, цифры и прочие символы.Как указывает @Paul «Sparrow Hawk» Бирон ,
u
флаг модификатора шаблона должен быть установлен в конце регулярного выражения, чтобы функции PHPRE PHP обрабатывали строку-тему какUTF-8
кодировку Unicode.Все вместе, то шаблон
будет соответствовать всей строке, состоящей из одного или нескольких символов в латинском и общем Unicode-скриптах.
Фильтрация строки поиска
Хорошее место , чтобы перехватить строку поиска является действие , как это срабатывает непосредственно перед WordPress выполняет запрос. С большей осторожностью это также может быть достигнуто с помощью фильтра .
pre_get_posts
request
Отвечая на запрещенные поиски
После того, как будет определено, что строка поиска содержит нелатинские символы, вы можете использовать ее
WP_Query::set()
для изменения запроса, изменив его именованные переменные запроса - таким образом влияя на SQL-запрос, который WordPress впоследствии создает и выполняет.Наиболее важные переменные запроса, вероятно, следующие:
s
переменная запроса, соответствующая строке поиска. Установка этого параметраnull
или пустой строки (''
) приведет к тому, что WordPress больше не будет обрабатывать запрос как поиск - часто это приводит к тому, что шаблон архива отображает все сообщения или первую страницу сайта, в зависимости от значений других запрос вари.' '
Однако, если задать для него один пробел ( ), WordPress распознает его как поиск и попытается отобразитьsearch.php
шаблон.page_id
может использоваться для направления пользователя на определенную страницу по вашему выбору.post__in
Можно ограничить запрос конкретным выбором сообщений. Устанавливая его в массив с невозможным идентификатором записи, он может служить мерой, гарантирующей, что запрос не даст абсолютно ничего .Принимая во внимание вышесказанное, вы можете сделать следующее, чтобы ответить на неправильный поиск, загрузив
search.php
шаблон без результатов:Отображение ошибки
То, как вы на самом деле отображаете сообщение об ошибке, сильно зависит от вашего приложения и возможностей вашей темы - есть много способов, которыми это можно сделать. Если ваша тема вызывает
get_search_form()
в своем шаблоне поиска, простейшим решением, вероятно, является использование ловушкиpre_get_search_form
действий для вывода вашей ошибки непосредственно над формой поиска:Некоторые другие возможности для отображения сообщения об ошибке включают в себя:
wp_enqueue_script
ловушку с$priority
большим, чем тот, который ставит в очередь этот JavaScript, и используйтеwp_localize_script()
для установки этой переменной, чтобы включить ваше сообщение об ошибке.wp_redirect()
для отправки пользователя по выбранному вами URL-адресу (этот метод требует дополнительной загрузки страницы).s
переменную запроса''
вместо' '
и используйтеpage_id
вместоpost__in
, чтобы вернуть страницу по вашему выбору.loop_start
ловушку, чтобыWP_Post
вставить поддельный объект, содержащий вашу ошибку, в результаты запроса - это, безусловно, уродливый хак, который может не соответствовать вашей конкретной теме, но имеет потенциально желательный побочный эффект - подавление сообщения «Нет результатов».template_include
ловушку фильтра, чтобы заменить шаблон поиска на собственный в вашей теме или плагине, который отображает вашу ошибку.Не изучая обсуждаемую тему, сложно определить, по какому маршруту следует идти.
источник
Вы могли бы сделать это, вставив функцию проверки в PHP, чтобы проверить ввод с помощью регулярного выражения, такого как
^[a-zA-Z0-9,.!?' ]*
Так это будет выглядеть так:
RexEx я использовал для всех персонажей
A-Z
,a-z
,0-9
, а также,
,.
,!
,?
,'
,"
, и(пробел).
источник
РЕДАКТИРОВАТЬ: Это решение не рекомендуется
Одним из способов предотвращения поиска с использованием нелатинских алфавитов является использование функции PHP
mb_detect_encoding()
для проверки соответствия строки поиска одной из пользовательских выборок кодировок символов. Хорошее место , чтобы сделать это действие , как он стреляет прямо перед запрос выполняется.pre_get_posts
То, что вы фактически делаете после того, как определили, что поиск использует недопустимую кодировку, действительно зависит от приложения. Здесь я установил поисковый запрос на один пробел, чтобы гарантировать, что WordPress все еще интерпретирует запрос как поиск и, таким образом, все еще загружает
search.php
шаблон (и не направляет пользователя на первую страницу, как это происходит, когда строка поиска пустая строка). Я также принимаю дополнительные меры предосторожности при установке'post__in'
массива с невозможным идентификатором записи, чтобы гарантировать, что абсолютно ничего не будет возвращено .С другой стороны, вы можете рассмотреть возможность установки строки поиска
null
и настройкиpage_id
, чтобы направить пользователя на страницу с вашим пользовательским сообщением об ошибке.Выбор кодировки
Я написал тест покрытия, сравнивающий несколько фиктивных строк в разных алфавитах со всеми кодировками по умолчанию, поддерживаемыми PHP . Он не идеален ни с одной натяжкой (я понятия не имею, насколько реалистичны мои фиктивные строки, и кажется, что он задыхается от японского обнаружения), но это несколько полезно для определения кандидатов. Вы можете увидеть это в действии здесь .
После изучения потенциальных кодировок символов, отмеченных этим тестом, кажется, что
Windows-1252
это идеальный выбор для ваших нужд, охватывающий латинский алфавит, а также акценты для распространенных латинских языков.Выбор
ISO-8859
наборов символов должен быть другим жизнеспособным выбором, однако по причинам, которые я не могу обернуть головой,mb_
функции, кажется, не различаютISO-8859
различные наборы символов, несмотря на перечисление их в качестве отдельных кодировок.Чтобы разрешить некоторые другие общие символы, вы также можете рассмотреть возможность добавления
HTML-ENTITIES
.источник
ISO-8859
кодировки .Как я пытался объяснить @MichaelRogers, когда он отправил похожий вопрос несколько дней назад, знание набора символов (или сценария), используемого в строке, НЕ достаточно для определения языка этой строки.
Таким образом, хотя метод, описанный @bosco , удалит строки из русского языка и т. Д. (С двумя приведенными ниже исправлениями), он НЕ ограничит ваш поиск английским языком.
Чтобы увидеть это, попробуйте:
[ примечание: 2 исправления, упомянутые выше к тому, что предоставил @bosco:
/u
модификатор (требуется для обработки шаблона и субъекта в кодировке UTF-8, см. PHP: Модификаторы шаблонов Regex ]который будет производить:
[ примечание: я говорю по-английски, по-французски и немного по-немецки (и немного с Lorem ipsum :-), но полагаюсь на Google Translate для арабского, русского и китайского]
Как видите, использование латинского скрипта НЕ гарантирует, что у вас есть английский.
В StackOverflow есть несколько потоков (например, « Определить язык из строки в PHP» ), которые предоставляют дополнительную информацию по этому вопросу.
источник