問題描述
我想將搜尋限制在英語+數字上使用的字元。原因是檢視最慢的查詢 mysql 日誌我發現大多數來自阿拉伯,俄羅斯和漢字的搜尋,所以我想跳過它們並顯示一個錯誤資訊。
最佳解決方案
此解決方案透過應用正規表示式來過濾搜尋字串,該正規表示式僅匹配 Common 和 Latin Unicode 指令碼中的字元。
匹配拉丁字元與正規表示式
我只是 had my mind blown over at Stack Overflow 。事實證明,正規表示式具有匹配整個 Unicode 類別的 a mechanism,包括用於指定整個 Unicode “scripts” 的值,每個對應於不同寫入系統中使用的字元組。
這是透過使用 p meta-character,後跟大括號中的 Unicode 類別識別符號完成的,因此 [p{Common}p{Latin}]與 Latin or Common scripts 中的單個字元匹配 – 其中包括標點符號,數字和雜項符號。
作為 @Paul ‘Sparrow Hawk’ Biron points out,u pattern modifier flag 應設定在正規表示式的末尾,以便 PHP 的 PCRE 功能將主題字串視為 UTF-8 Unicode 編碼。
所有在一起的模式
/^[p{Latin}p{Common}]+$/u
將匹配由拉丁文和通用 Unicode 指令碼中的一個或多個字元組成的整個字串。
過濾搜尋字串
攔截搜尋字串的好地方是在 WordPress 執行查詢之前立即觸發的 pre_get_posts 操作。更加小心,這也可以使用 request 濾波器完成。
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[p{Latin}p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
// If execution reaches this point, the search string contains non-Latin characters
//TODO: Handle non-Latin search strings
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
響應不允許的搜尋
一旦確定一個搜尋字串包含 non-Latin 字元,您可以使用 WP_Query::set()來修改查詢,透過更改它的名稱為 query vars – 從而影響 WordPress 後續編寫和執行的 SQL 查詢。
最相關的查詢變數大概如下:
-
s是與搜尋字串對應的查詢變數。將其設定為null或空字串 ('') 將導致 WordPress 不再將查詢視為搜尋 – 通常會導致存檔模板顯示站點的所有帖子或 front-page,具體取決於其他的值查詢變數。然而,將其設定為單個空格 (' ') 將導致 WordPress 將其識別為搜尋,從而嘗試顯示search.php模板。 -
page_id可用於將使用者引導到您選擇的特定頁面。 -
post__in可以將查詢限制為特定的帖子選擇。透過將其設定為具有不可能的帖子 ID 的陣列,it can serve as a measure to ensure that the query returns absolutely nothing 。
考慮到上述情況,您可以執行以下操作,以便透過載入 search.php 模板來響應不正確的搜尋結果:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[p{Latin}p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
顯示錯誤
實際顯示錯誤訊息的方式在很大程度上取決於您的應用程式和主題的能力 – 有很多方法可以完成。如果您的主題在其搜尋模板中呼叫 get_search_form(),則最簡單的解決方案可能是使用 pre_get_search_form 動作鉤子在搜尋表單上方輸出錯誤:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[p{Latin}p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
add_action( 'pre_get_search_form', 'wpse261038_display_search_error' );
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
function wpse261038_display_search_error() {
echo '<div class="notice notice-error"><p>Your search could not be completed as it contains characters from non-Latin alphabets.<p></div>';
}
顯示錯誤訊息的其他一些可能性包括:
-
如果您的站點使用可以顯示 「flash」 或 「modal」 訊息的 JavaScript(或者您自己新增這些功能),則新增一個邏輯來在設定特定變數時顯示 page-load 上的訊息,然後新增一個
wp_enqueue_script鉤子一個大於排列該 JavaScript 的$priority,並使用wp_localize_script()將該變數設定為包含錯誤訊息。 -
使用
wp_redirect()將使用者傳送到您選擇的 URL(此方法需要額外的頁面載入) 。 -
設定一個 PHP 變數或呼叫一個方法,它將通知您的主題/外掛有關錯誤,以便它可以在適當的時候顯示。
-
將
s查詢變數設定為''而不是' ',並使用page_id代替post__in,以返回您選擇的頁面。 -
使用
loop_start鉤子將含有錯誤的假WP_Post物件注入到查詢結果中 – 這絕對是一個醜陋的駭客,可能不符合您的特定主題,但它具有抑制”No Results” 訊息的潛在可能的副作用。 -
使用
template_include過濾器掛鉤,在您的主題或外掛中顯示您的錯誤,使用自定義的模板交換搜尋模板。
沒有檢查有關的主題,很難確定你應該採用哪條路線。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。