क्या मैं कोई परिणाम वापस करने के लिए WP_Query को मजबूर कर सकता हूं?


23

मैं एक वेबसाइट पर खोज सुविधा के साथ काम कर रहा हूं जो उपयोगकर्ताओं को बहुत अधिक पोस्ट मेटा के माध्यम से खोजने की अनुमति देता है। एक विशिष्ट खोज पैटर्न है, जिसके लिए मैं जबरन कोई परिणाम नहीं देना चाहूंगा। WP_Query तकनीकी रूप से डेटाबेस में परिणाम प्राप्त करेगा, लेकिन मैं इसे किसी भी तरह से ओवरराइड करना चाहूंगा कि इसे if( $example->have_posts() )विफल करने के लिए ट्रिगर करने के लिए कोई परिणाम वापस करने के लिए मजबूर न करें ।

क्या कोई ऐसा पैरामीटर है जिसे मैं WP_Query को पास कर सकता हूं जैसे 'force_no_results' => trueकि यह कोई परिणाम नहीं देने के लिए मजबूर करेगा?


1
ऐसा लगता है जैसे आप पहले से निर्धारित कार्यान्वयन के लिए पूछ रहे हैं, बजाय यह पूछने के कि रूट समस्या को कैसे हल किया जाए। लाइनों के बीच पढ़ना, मुझे लगता है कि आपको वास्तव में क्या पूछना चाहिए: मैं एक विशिष्ट खोज पैटर्न को कैसे अनुपयुक्त बना सकता हूं? WP_Query()कोई परिणाम न मिलने के कारण या उस प्रश्न का उत्तर देने का सबसे अच्छा तरीका नहीं हो सकता है। यह उपयोगी भी हो सकता है यदि आप उस खोज पैटर्न का वर्णन करेंगे जो आप निर्विवाद होना चाहते हैं। खोज पैटर्न जानने से फेरेट को हल करने में मदद मिल सकती है।
चिप बेनेट

जवाबों:


28

प्रयत्न

'post__in' => array(0)

सरल और सटीक।


मेरा पहला विचार था - यह कहीं गलत होगा, लेकिन संबंधित कोड को स्किम करने से यह वास्तव में अच्छी तरह से काम करना चाहिए। :)
दुर्लभ

5
शून्य बहुत महत्वपूर्ण है क्योंकि सिर्फ एक खाली सरणी हाल के पदों को वापस कर देगी।
मार्क कप्लून

धन्यवाद! यह मेरे लिए एक बग को हल कर दिया क्योंकि post__inजब एक खाली सरणी पास हुई तो पोस्ट वापस कर रहा था ... array(0)बहुत अच्छा काम करता है! यह अजीब है लेकिन यह वास्तव में WP कोर में बग के रूप में सामने आए एक मुद्दे का पता लगा सकता है लेकिन तब इसे छोड़ दिया गया था, क्योंकि बहुत सारे थीम / प्लगइन डेवलपर्स ने इसके चारों ओर कार्यक्षमता का निर्माण किया था -_- core.trac.wordpress.org/ टिकट /
28099

3

संक्षेप में शॉर्ट सर्किट का कोई साफ / स्पष्ट तरीका नहीं है WP_Query

यदि यह मुख्य क्वेरी है तो आप कुछ बाहर काम कर सकते हैं WP->parse_request(), वहाँ अपेक्षाकृत हाल ही में (3.5) do_parse_requestफ़िल्टर लगता है।

लेकिन WP_Queryखुद के लिए गंदे हैक्स आमतौर पर क्रम में होते हैं, जैसे कि फिल्टर के AND 1=0माध्यम से जोड़कर शॉर्ट-एसक्यूएल क्वेरी को सर्कुलेट करना posts_whereआदि।


2
जानकारी के लिए धन्यवाद। यह एक माध्यमिक लूप btw था। और मैं अभी एक गंदा हैक कर रहा था जैसे "post_type" => "break_loop"कि एक गैर-मौजूद पोस्ट प्रकार है।
ब्रायन

2

किसी क्वेरी पैरामीटर को अनपेक्षित मान पर सेट करने की समस्याएं 2 हैं:

  • क्वेरी चलेगी, इसलिए यदि आप पहले से ही जानते हैं कि कोई परिणाम नहीं होगा तो भुगतान करने के लिए थोड़ा प्रदर्शन मूल्य होगा
  • वर्डप्रेस क्वेरी में क्वेरी पर 19 अलग-अलग 'posts_*'फ़िल्टर हुक ( 'posts_where', 'post_join'इत्यादि) हैं, जो आप पर कार्रवाई करते हैं, इसलिए आप कभी भी यह सुनिश्चित नहीं कर सकते हैं कि यहां तक ​​कि अनजाने में परम क्वेरी सेट करना कोई परिणाम नहीं देता है, ORफ़िल्टर द्वारा लौटाए गए एक साधारण क्लॉज़ कुछ वापस करते हैं।

आपको यह सुनिश्चित करने के लिए थोड़ा सा हार्डकोर रूटीन की आवश्यकता है कि कोई क्वेरी वापस न आए और कोई (या बहुत ही न्यूनतम) प्रदर्शन समस्या न हो।

उस दिनचर्या को ट्रिगर करने के लिए, आप हर विधि का उपयोग कर सकते हैं, तकनीकी रूप से आप किसी भी तर्क को पारित कर सकते हैं WP_Query, ऐसी दलीलें जो मौजूद नहीं हैं।

तो अगर आपको कुछ पसंद है 'force_no_results' => true, तो आप इसका उपयोग कर सकते हैं:

$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );

और 'pre_get_posts'कड़ी मेहनत करते हुए कॉलबैक जोड़ें :

add_action( 'pre_get_posts', function( $q ) {
  if (array_key_exists('force_no_results', $q->query) && $q->query['force_no_results']) {
    $q->query = $q->query_vars = array();
    $added = array();
    $filters = array(
      'where', 'where_paged', 'join', 'join_paged', 'groupby', 'orderby', 'distinct',
      'limits', 'fields', 'request', 'clauses', 'where_request', 'groupby_request',
      'join_request', 'orderby_request', 'distinct_request','fields_request',
      'limits_request', 'clauses_request'
    );
    // remove all possible interfering filter and save for later restore
    foreach ( $filters as $f ) {
      if ( isset($GLOBALS['wp_filter']["posts_{$f}"]) ) {
        $added["posts_{$f}"] = $GLOBALS['wp_filter']["posts_{$f}"];
        unset($GLOBALS['wp_filter']["posts_{$f}"]);
      }
    }
    // be sure filters are not suppressed
    $q->set( 'suppress_filters', FALSE );
    $done = 0;
    // use a filter to return a non-sense request
    add_filter('posts_request', function( $r ) use( &$done ) {
      if ( $done === 0 ) { $done = 1;
        $r = "SELECT ID FROM {$GLOBALS['wpdb']->posts} WHERE 0 = 1";
      }
      return $r;
    });
    // restore any filter that was added and we removed
    add_filter('posts_results', function( $posts ) use( &$done, $added ) {
      if ( $done === 1 ) { $done = 2;
        foreach ( $added as $hook => $filters ) {
          $GLOBALS['wp_filter'][$hook] = $filters;
        }
      }
      return $posts;
    });
  }
}, PHP_INT_MAX );

यह कोड 'pre_get_posts'जितना संभव हो उतना देर से चलाया जाता है। यदि तर्क 'force_no_results' क्वेरी में मौजूद है, तो:

  1. पहले सभी संभावित फ़िल्टर निकालें जो क्वेरी में हस्तक्षेप कर सकते हैं, और उन्हें एक सहायक सरणी के अंदर संग्रहीत कर सकते हैं
  2. यह सुनिश्चित करने के बाद कि फ़िल्टर चालू हो गया, Adda फ़िल्टर जो इस तरह का अनुरोध वापस करता है: SELECT ID FROM wp_posts WHERE 0 = 1एक बार सभी फ़िल्टर हटा दिए जाने के बाद, इस क्वेरी को बदले जाने की कोई संभावना नहीं है और यह बहुत तेज़ है, और सुनिश्चित करने के लिए कोई परिणाम नहीं है
  3. इस क्वेरी के चलने के तुरंत बाद, सभी मूल फ़िल्टर (यदि कोई हो) बहाल किए गए हैं और बाद के सभी प्रश्न उम्मीद के मुताबिक काम करेंगे।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.