कुछ 404 पर लूप खाली क्यों नहीं है?


10

मैं एक अजीब मुद्दे पर आया था।

मान लें कि आप एक यादृच्छिक url तक पहुँचते हैं, तीन या अधिक गहरे स्तर:

http://example.com/a/b/c
http://example.com/a/b/c/d
...

तो is_404()है true। अब तक सब ठीक है। लेकिन किसी न किसी कारण से अंतिम पदों की पूर्ति हो जाती है।

$wp_query->request

है

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
    FROM wp_posts 
    WHERE 1=1 
        AND wp_posts.post_type = 'post' 
        AND (
            wp_posts.post_status    = 'publish' 
            OR wp_posts.post_status = 'private'
            ) 
    ORDER BY wp_posts.post_date DESC 
    LIMIT 0, 5

जो तब निश्चित रूप से have_posts()वापसी करता है trueऔर इसी तरह। क्या कोई इसे समझा सकता है?

मुझे अब तक क्या पता चला है:

इसका कारण यह है कि केवल तीन या उससे अधिक स्तरों पर गहरी किक होती है, इससे पहले WP पोस्ट और अटैचमेंट की तलाश करता है जिसके परिणामस्वरूप किसी न किसी तरह का व्यवहार होता है।

ऐसा लगता है कि भले ही WP अनुरोध को एक बिंदु पर 404 के रूप में पहचानता है, फिर यह सबसे हालिया पोस्ट प्राप्त करता है। @Kaiser और @GM की मदद से मैंने इसे कहीं से नीचे ट्रैक किया है /wp-includes/class-wp.php:608


यदि आप पेज का कोड नहीं जोड़ते हैं, तो आपकी मदद करना मुश्किल होगा
टॉम कॉट

3
यह मेरे कोड के लिए विशिष्ट नहीं है। सभी डिफ़ॉल्ट विषयों के साथ एक ब्रांड के नए स्थापित पर इस तरह व्यवहार करता है।
क्राफ्टर

क्या आप कम से कम एक विषय को नाम दे सकते हैं, मेरे कस्टम विषय में काम नहीं कर रहा है? क्या आप विशिष्ट मापदंडों का उपयोग कर रहे हैं? क्या आपने स्लग को बदल दिया है? WP के कौन से संस्करण का उपयोग कर रहे हैं?
टॉमस कॉट

वास्तव में कोई भी। लेकिन अगर आप चाहें तो ट्वेंटी इलेवन का प्रयास करें।
क्राफ्टर

सभी सवालों के लिए खेद है, मुझे लगा कि पोस्ट दिखा रहे थे।
टॉमस कॉट

जवाबों:


9

आपको आश्चर्य हो सकता है, लेकिन वहाँ कुछ भी अजीब नहीं है।

सबसे पहले आइए स्पष्ट करें कि वर्डप्रेस में जब आप एक फ्रंटएंड URL पर जाते हैं तो आप एक क्वेरी ट्रिगर करते हैं। हमेशा।

यह क्वेरी सिर्फ एक मानक है WP_Query, ठीक उसी तरह जैसे कि लोग चलते हैं:

$query = new WP_Query( $args );

केवल एक अंतर है: $argsवर्डप्रेस द्वारा WP::parse_request()विधि का उपयोग करके चर उत्पन्न होते हैं । वह विधि जो करती है वह केवल URL को देखें, और नियमों को फिर से लिखें, और URL को तर्कों के एक सरणी में परिवर्तित करें।

लेकिन क्या होता है जब वह विधि ऐसा करने में सक्षम न हो क्योंकि URL गैर-वैध है? क्वेरी args इस तरह से एक सरणी है:

array( 'error' => '404' );

(स्रोत यहां और यहां )।

ताकि यह सरणी पास हो जाए WP_Query

अब करने की कोशिश करो:

$query = new WP_Query( array( 'error' => '404' ) );
var_dump( $query->request );

क्या आप आश्चर्यचकित हैं कि क्वेरी ओपी में बिल्कुल एक है? मैं नहीं।

इसलिए,

  1. parse_request() एरर कुंजी के साथ एक सरणी बनाता है
  2. उस सरणी को पास कर दिया जाता है WP_Query, जो उसे चलाता है
  3. handle_404()क्वेरी के बाद चलता है , 'error'पैरामीटर को देखता है और is_404()सही पर सेट करता है

तो, have_post()और is_404()संबंधित नहीं हैं। समस्या यह है कि WP_Queryकुछ गलत होने पर क्वेरी को शॉर्ट-सर्किट करने के लिए कोई सिस्टम नहीं है, इसलिए जब ऑब्जेक्ट बनाया जाता है, तो उसके पास कुछ आर्गन पास करें और क्वेरी चलेगी ...

संपादित करें:

इस समस्या को दूर करने के 2 तरीके हैं:

  • एक 404.phpटेम्पलेट बनाएं ; वर्डप्रेस 404 URL पर लोड करेगा और वहां आपको जांचने की आवश्यकता नहीं हैhave_posts()
  • सेना $wp_query404 पर खाली होने के लिए, की तरह कुछ:

    add_action( 'wp', function() {
        global $wp_query;
        if ( $wp_query->is_404() ) {
            $wp_query->init();
            $wp_query->is_404 = true; // init() reset 404 too
        }
    } );

4
मैं यह जोड़ूंगा कि आमतौर पर ऐसा नहीं होने का कारण यह है कि 404 आमतौर पर क्वेरी का परिणाम है । लेकिन इस मामले में यह बेजोड़ पुनर्लेखन नियम ( $wp->matched_rule) का परिणाम है , लेकिन क्वेरी अभी भी गतियों से गुजर रही है क्योंकि यह उस पर ध्यान नहीं देता है।
रारस्ट

+1। हां, क्वेरी इस पर ध्यान नहीं देती है, और वर्तमान कोड के साथ यह ध्यान नहीं दे सकता है , क्योंकि इसे रोकने का कोई तरीका नहीं है। उदाहरण के रूप में जब एक गैर मान्य वर्गीकरण वर्डप्रेस सेट क्वेरी की जाती है WHERE 1=0एसक्यूएल में है क्योंकि यह क्वेरी ताकि वापसी कुछ भी नहीं ... @Rarst एक प्रश्न मजबूर नहीं रोक सकता
gmazzap

ठीक है अब मैं समझ गया। तो असली सवाल यह है कि नरक क्यों होता है WP_Query पदों को प्राप्त करने का एक डिफ़ॉल्ट क्वेरी मान लेता है जब कोई उचित तर्क पारित नहीं किया जाता है जब सिर्फ कुछ भी नहीं लौटने से अधिक समझ में आता है?
क्राफ्टर

2
@kraftner ने कहा कि वर्डप्रेस क्वेरी रन से बच नहीं सकता है, और जब कोई गूंजने योग्य तर्क नहीं हैं, तो 2 विकल्प हैं: एक क्वेरी चलाएं जो निश्चित रूप से कुछ भी नहीं लौटाता है (जैसे कि जब कोई गैर-वैध टैक्सोनोमी की पुष्टि होती है, तो ऊपर टिप्पणी देखें) या डिफ़ॉल्ट क्वेरी चलाएं । क्यों इस मामले WP दूसरे विकल्प को चुनते में एक क्यू कि कोर devs के लिए :) लिए कहा जाना चाहिए है
gmazzap

@ TomásCot ज़रूर लेकिन अगर यह विफल रहता है तो मैं चाहता हूँ कि यह वास्तव में विफल हो और पूरी तरह से असंबंधित कुछ वापस न करें। वैसे भी, अब चीजें साफ हो गई हैं और मुझे सिर्फ एक अतिरिक्त is_404()जांच करने की जरूरत है ।
क्राफ्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.