$ GLOBALS ['wp_the_query'] so với toàn cầu $ wp_query


16

Sự khác biệt giữa $GLOBALS['wp_the_query']và là global $wp_querygì?

Tại sao thích cái này hơn cái kia?


2
Tôi sẽ nói global $wp_querychỉ để trả lời câu hỏi của bạn trong một dòng!
Sumit

Sự khác biệt là gì?
Nathan Powell

Câu trả lời:


27

Bạn đã bỏ lỡ một , $GLOBALS['wp_query']. Đối với tất cả các mục đích , $GLOBALS['wp_query'] === $wp_query. $GLOBALS['wp_query']tuy nhiên tốt hơn cho khả năng đọc và nên được sử dụng thay vì $wp_query, NHƯNG, đó vẫn là sở thích cá nhân

Bây giờ, trong một thế giới hoàn hảo, nơi kỳ lân thống trị thế giới $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query,. Theo mặc định, điều này là đúng. Nếu chúng ta nhìn vào nơi các quả cầu này được đặt ( wp-settings.php), bạn sẽ thấy đối tượng truy vấn chính được lưu trữ $GLOBALS['wp_the_query']$GLOBALS['wp_query']chỉ là một bản sao của$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'];

Lý do để làm theo cách này, là vì WordPress đã thấy sự xuất hiện của query_postsphiên bản 1.5.

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

Như bạn có thể thấy, query_postsđặt đối tượng truy vấn chính thành chạy truy vấn tùy chỉnh hiện tại. Điều này phá vỡ tính toàn vẹn của đối tượng truy vấn chính, cung cấp cho bạn dữ liệu không chính xác, do đó, mọi thứ liên quan đến đối tượng truy vấn chính đều bị hỏng do dữ liệu sai.

Một cách để chống lại điều này là tạo một toàn cầu khác để lưu trữ đối tượng truy vấn chính, $GLOBALS['wp_the_query']được giới thiệu trong phiên bản 2.0.0. Toàn cầu mới này giữ đối tượng truy vấn chính và $GLOBALS['wp_query']chỉ là một bản sao. Thông qua wp_reset_query(), bây giờ chúng ta có thể đặt $GLOBALS['wp_query']lại về đối tượng truy vấn chính ban đầu để khôi phục tính toàn vẹn của nó.

Nhưng đây không phải là một thế giới hoàn hảo, và chính query_postslà ác quỷ. Mặc dù hàng ngàn cảnh báo, mọi người vẫn sử dụng query_posts. Ngoài việc phá vỡ truy vấn chính, nó chạy lại truy vấn chính, làm cho nó chậm hơn nhiều so với truy vấn tùy chỉnh thông thường WP_Query. Nhiều người cũng không thiết lập lại query_poststruy vấn wp_reset_query()khi hoàn thành, điều này query_poststhậm chí còn tệ hơn.

Bởi vì chúng tôi không thể làm bất cứ điều gì về điều đó và không thể ngăn chặn các plugin và chủ đề sử dụng query_postsvà chúng tôi không bao giờ có thể biết liệu query_poststruy vấn có được đặt lại hay không wp_reset_query(), chúng tôi cần một bản sao đáng tin cậy hơn của đối tượng truy vấn chính mà chúng tôi biết sẽ cung cấp cho chúng tôi độ tin cậy 99.99999%, chính xác dữ liệu. Đó là nơi $GLOBALS['wp_the_query']hữu ích vì không có mã liên quan đến WordPress nào có thể thay đổi giá trị của nó ( ngoại trừ thông qua các bộ lọc và hành động bên trong WP_Querychính nó ).

Bằng chứng nhanh, chạy như sau

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'] );

và kiểm tra kết quả. $GLOBALS['wp_the_query']không thay đổi, và $GLOBALS['wp_query']có. Vậy cái nào đáng tin cậy hơn?

Lưu ý cuối cùng, $GLOBALS['wp_the_query']KHÔNG một sự thay thế cho wp_reset_query(). wp_reset_query()nên luôn luôn được sử dụng với query_posts, và không bao giờquery_posts nên được sử dụng.

ĐỂ KẾT LUẬN

Nếu bạn cần mã đáng tin cậy mà hầu như sẽ không bao giờ thất bại, hãy sử dụng $GLOBALS['wp_the_query'], nếu bạn tin tưởng và tin rằng các plugin và mã chủ đề và tin rằng không ai sử dụng query_postshoặc sử dụng nó một cách chính xác, hãy sử dụng $GLOBALS['wp_query']hoặc$wp_query

EDIT QUAN TRỌNG

Trả lời các câu hỏi trên trang web này trong một vài năm, tôi thấy nhiều người dùng sử dụng $wp_querynhư một biến cục bộ, do đó cũng phá vỡ đối tượng truy vấn chính. Điều này càng làm tăng tính dễ bị tổn thương của $wp_query.

Ví dụ, một số người

$wp_query = new WP_Query( $args );

về bản chất nó giống hệt như những gì query_postsđang làm


1
query_posts () thay đổi global $wp_query. global $wp_the_querygiữ tham chiếu đến truy vấn chính
Evan Mattson

Nhận xét của tôi không nhằm mục đích chỉnh sửa, vì vậy tôi xin lỗi nếu có. Tôi chỉ đơn thuần là tóm tắt (TL; DR nếu bạn muốn) trong khi chỉ ra những gì tôi tin là một trong những khía cạnh quan trọng nhất $wp_the_querykhi nó liên quan đến WP_Query::is_main_query()phương pháp, không được đề cập: D
Evan Mattson

@EvanMattson Xin lỗi, tôi đã hiểu nhầm ý kiến ​​đầu tiên của bạn ;-). Có, is_main_query()đó là một trình bao bọc để WP_Query::is_main_query()kiểm tra đối tượng truy vấn hiện tại đối với đối tượng truy vấn chính được lưu trong $GLOBALS['wp_the_query']. Điều này khá quan trọng khi bạn chạy pre_get_postscác hành động và chỉ muốn nhắm mục tiêu truy vấn chính ;-)
Pieter Goosen

Câu trả lời được thực hiện khá tốt! @EvanMattson Đó phải là một chỉnh sửa .
kaiser

Bạn có thể bao gồm đề cập đến is_main_querychức năng trong phần * EDIT QUAN TRỌNG không? Tôi đã sử dụng pre_get_postsngày hôm nay và thấy nó hoàn toàn hữu ích để sử dụng chức năng đó kể từ khi tôi nhìn vào $wp_query.
Nathan Powell

2

Về cơ bản, một bản sao của bản kia. Kiểm tra wp-settings.php, dòng 292-305:

$GLOBALS['wp_the_query'] = new WP_Query();

$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];

2

Từ khóa toàn cầu nhập biến vào phạm vi cục bộ, trong khi $ GLOBALS chỉ cấp cho bạn quyền truy cập vào biến.

Để giải thích, nếu bạn sử dụng, global $wp_the_query; bạn có thể sử dụng $wp_the_querybên trong phạm vi cục bộ mà không cần sử dụng lại từ toàn cầu. Vì vậy, về cơ bản global $wp_the_querycó thể được so sánh với$wp_the_query = $GLOBALS['wp_the_query']

BIÊN TẬP

Tôi đã đọc sai wp_query cho wp_the_query vì vậy câu trả lời của tôi không phải là câu trả lời hoàn chỉnh cho câu hỏi nhưng vẫn cung cấp thông tin chung về sự khác biệt giữa global $variable$GLOBALS['variable']


Xin vui lòng, gửi một chỉnh sửa vì đây thực sự không phải là một câu trả lời cho câu hỏi ban đầu. Chỉ cần FYI $GLOBALS['foo']cho phép ghi đè hoặc bỏ đặt biến. Vì vậy, nó nhiều hơn một chút so với những gì bạn mô tả ở đây.
kaiser
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.