$ GLOBALS ['wp_the_query'] กับ $ wp_query ทั่วโลก


16

ความแตกต่างระหว่าง$GLOBALS['wp_the_query']และglobal $wp_queryคืออะไร?

เหตุใดจึงเลือกใช้งานมากกว่ากัน


2
ฉันจะบอกglobal $wp_queryเพียงเพื่อตอบคำถามของคุณในบรรทัดเดียว!
สุมิตร

อะไรคือความแตกต่าง?
Nathan Powell

คำตอบ:


27

$GLOBALS['wp_query']คุณไม่ได้รับอย่างใดอย่างหนึ่ง $GLOBALS['wp_query'] === $wp_queryเพื่อวัตถุประสงค์ทั้งหมด $GLOBALS['wp_query']จะดีกว่าสำหรับการอ่าน แต่ควรใช้แทน$wp_queryแต่ที่ยังคงความชอบส่วนบุคคล

ในโลกที่สมบูรณ์แบบที่ยูนิคอร์นครองโลก, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query. โดยค่าเริ่มต้นสิ่งนี้ควรเป็นจริง หากเราดูที่ตั้งค่า globals เหล่านี้ ( wp-settings.php) คุณจะเห็นวัตถุแบบสอบถามหลักถูกเก็บไว้ใน$GLOBALS['wp_the_query']และ$GLOBALS['wp_query']เป็นเพียงสำเนาที่ซ้ำกันของ$GLOBALS['wp_the_query']

/**
 * WordPress Query object
 * @global WP_Query $wp_the_query
 * @since 2.0.0
 */
$GLOBALS['wp_the_query'] = new WP_Query();
/**
 * Holds the reference to @see $wp_the_query
 * Use this global for WordPress queries
 * @global WP_Query $wp_query
 * @since 1.5.0
 */
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];

เหตุผลในการทำเช่นนี้เป็นเพราะ WordPress เห็นการมาถึงของquery_postsรุ่น 1.5

function query_posts($query) {
    $GLOBALS['wp_query'] = new WP_Query();
    return $GLOBALS['wp_query']->query($query);
}

อย่างที่คุณเห็นให้query_postsตั้งค่าวัตถุคิวรีหลักเป็นคิวรีแบบกำหนดเองปัจจุบันในปัจจุบัน สิ่งนี้จะทำลายความสมบูรณ์ของวัตถุแบบสอบถามหลักซึ่งทำให้คุณมีข้อมูลที่ไม่ถูกต้องดังนั้นสิ่งใดก็ตามที่อาศัยวัตถุแบบสอบถามหลักจะใช้งานไม่ได้เนื่องจากข้อมูลผิด

วิธีในการตอบโต้สิ่งนี้คือการสร้างอีกโกลบอลเพื่อจัดเก็บวัตถุคิวรีหลัก$GLOBALS['wp_the_query']ซึ่งถูกนำมาใช้ในเวอร์ชัน 2.0.0 ใหม่ทั่วโลกนี้ถือวัตถุแบบสอบถามหลักและ$GLOBALS['wp_query']เพียงแค่คัดลอก ผ่านwp_reset_query()ตอนนี้เราสามารถรีเซ็ต$GLOBALS['wp_query']กลับไปเป็นวัตถุแบบสอบถามหลักเดิมเพื่อคืนค่าความสมบูรณ์ของมัน

แต่นี่ไม่ใช่โลกที่สมบูรณ์แบบและquery_postsเป็นปีศาจตัวเอง query_postsแม้ว่าหลายพันคำเตือนคนยังคงใช้ นอกเหนือจากการแบ่งคิวรีหลักแล้วมันจะรันคิวรีหลักอีกครั้งทำให้ช้ากว่าการสืบค้นแบบกำหนดเองปกติWP_Queryมาก หลายคนยังไม่ได้รีเซ็ตคิวรีquery_postsด้วยwp_reset_query()เมื่อเสร็จแล้วซึ่งจะทำให้query_postsความชั่วร้ายยิ่งขึ้น

เนื่องจากเราไม่สามารถทำอะไรเกี่ยวกับสิ่งนั้นและไม่สามารถหยุดปลั๊กอินและชุดรูปแบบจากการใช้query_postsและเราไม่สามารถรู้ได้ว่ามีquery_postsการตั้งค่าการสืบค้นใหม่wp_reset_query()หรือไม่ดังนั้นเราจึงต้องการสำเนาของวัตถุแบบสอบถามหลักที่เชื่อถือได้มากขึ้น ข้อมูล. ที่ซึ่ง$GLOBALS['wp_the_query']มีประโยชน์เนื่องจากไม่มีรหัสที่เกี่ยวข้องกับ WordPress สามารถเปลี่ยนค่าได้ ( ยกเว้นผ่านตัวกรองและการกระทำภายในWP_Queryตัวเอง )

หลักฐานอย่างรวดเร็วเรียกใช้ต่อไปนี้

var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );

query_posts( 's=crap' );


var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );

และตรวจสอบผลลัพธ์ $GLOBALS['wp_the_query']ไม่เปลี่ยนแปลงและ$GLOBALS['wp_query']มี ดังนั้นน่าเชื่อถือมากขึ้น?

บันทึกสุดท้าย$GLOBALS['wp_the_query']คือไม่wp_reset_query()เปลี่ยนสำหรับ wp_reset_query()ควรใช้กับเสมอquery_postsและไม่query_postsควรใช้

สรุป

หากคุณต้องการรหัสที่เชื่อถือได้ซึ่งเกือบจะไม่เคยล้มเหลวให้ใช้$GLOBALS['wp_the_query']ถ้าคุณเชื่อถือและเชื่อว่าปลั๊กอินและรหัสชุดรูปแบบและเชื่อว่าไม่มีใครใช้query_postsหรือใช้งานอย่างถูกต้องใช้$GLOBALS['wp_query']หรือ$wp_query

การแก้ไขที่สำคัญ

ด้วยการตอบคำถามในเว็บไซต์นี้เป็นเวลาสองสามปีที่ผ่านมาฉันเห็นผู้ใช้จำนวนมากที่ใช้$wp_queryเป็นตัวแปรโลคัล ต่อไปนี้การเพิ่มขึ้นของ vulnerabilty $wp_queryของ

อย่างเช่นบางคนถึงกับสิ่งนี้

$wp_query = new WP_Query( $args );

ซึ่งเป็นสาระสำคัญเหมือนกับสิ่งที่query_postsกำลังทำ


1
query_posts ()global $wp_queryการเปลี่ยนแปลง global $wp_the_queryถือการอ้างอิงถึงข้อความค้นหาหลัก
Evan Mattson

ความคิดเห็นของฉันไม่ได้มีไว้สำหรับการแก้ไขดังนั้นฉันจึงขอโทษถ้ามันเป็นเช่นนั้น ฉันเป็นเพียงการสรุป (TL; DR ถ้าคุณจะ) ในขณะที่ชี้ให้เห็นสิ่งที่ฉันเชื่อว่าเป็นหนึ่งในแง่มุมที่สำคัญที่สุดของ$wp_the_queryมันที่เกี่ยวข้องกับWP_Query::is_main_query()วิธีการที่ไม่ได้กล่าวถึง: D
Evan Mattson

@EvanMattson ขอโทษนะฉันเข้าใจผิดความคิดเห็นแรกของคุณ ;-) ใช่is_main_query()ซึ่งเป็นเสื้อคลุมสำหรับซึ่งการตรวจสอบวัตถุแบบสอบถามในปัจจุบันกับวัตถุแบบสอบถามหลักบันทึกไว้ในWP_Query::is_main_query() $GLOBALS['wp_the_query']สิ่งนี้ค่อนข้างสำคัญเมื่อคุณเรียกใช้pre_get_postsการกระทำและเพียงต้องการกำหนดเป้าหมายการสืบค้นหลัก ;-)
Pieter Goosen

คำตอบที่ทำได้ค่อนข้างดี! @EvanMattson ที่ควรได้รับการแก้ไข
ไกเซอร์

คุณสามารถรวมis_main_queryฟังก์ชั่นการพูดคุยในส่วน * สำคัญแก้ไขได้หรือไม่? ผมก็ใช้วันนี้และพบว่ามีประโยชน์อย่างเต็มที่ที่จะใช้ฟังก์ชั่นที่ตั้งแต่ผมกำลังมองไปที่pre_get_posts $wp_query
Nathan Powell


2

คำหลักทั่วโลกนำเข้าตัวแปรในขอบเขตท้องถิ่นในขณะที่ $ GLOBALS เพียงแค่ให้สิทธิ์คุณเข้าถึงตัวแปร

หากต้องการใช้อย่างละเอียดถ้าคุณใช้global $wp_the_query; คุณสามารถใช้$wp_the_queryภายในขอบเขตท้องถิ่นโดยไม่ต้องใช้คำว่าเป็นโกลบอลอีกครั้ง ดังนั้นโดยทั่วไปglobal $wp_the_queryสามารถเปรียบเทียบได้$wp_the_query = $GLOBALS['wp_the_query']

แก้ไข

ฉันอ่านผิด wp_query สำหรับ wp_the_query ดังนั้นคำตอบของฉันจึงไม่ใช่คำตอบที่สมบูรณ์สำหรับคำถาม แต่ยังคงให้ข้อมูลทั่วไปเกี่ยวกับความแตกต่างระหว่างglobal $variableและ$GLOBALS['variable']


โปรดแก้ไขไฟล์เพราะนี่ไม่ใช่คำตอบสำหรับคำถามเดิม เพียงแค่ FYI $GLOBALS['foo']อนุญาตให้แทนที่หรือยกเลิกการตั้งค่าตัวแปรได้เช่นกัน ดังนั้นจึงเป็นบิตมากกว่าสิ่งที่คุณอธิบายที่นี่
ไกเซอร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.