Temel soru
Üçlü içine edelim kazı: ::query_posts
, ::get_posts
ve class WP_Query
anlamak için ::query_posts
daha iyi.
WordPress'te veri almanın temel taşı WP_Query
sınıftır. Yöntemler Hem ::query_posts
ve ::get_posts
sınıf kullanan.
Sınıfın WP_Query
aynı ada sahip yöntemleri de içerdiğini unutmayın : WP_Query::query_posts
ve WP_Query::get_posts
ancak aslında sadece global yöntemleri düşünüyoruz, bu yüzden kafa karıştırmayın.
Anlamak WP_Query
Çağrılan sınıf WP_Query
2004 yılında yeniden tanıtıldı. 2004'te mevcut olan ☂ (şemsiye) işaretine sahip tüm alanlar. Daha sonra ek alanlar eklenmiştir.
İşte WP_Query
yapı:
class WP_Query (as in WordPress v4.7)
public $query; ☂
public $query_vars = array(); ☂
public $tax_query;
public $meta_query = false;
public $date_query = false;
public $queried_object; ☂
public $queried_object_id; ☂
public $request;
public $posts; ☂
public $post_count = 0; ☂
public $current_post = -1; ☂
public $in_the_loop = false;
public $post; ☂
public $comments;
public $comment_count = 0;
public $current_comment = -1;
public $comment;
public $found_posts = 0;
public $max_num_pages = 0;
public $max_num_comment_pages = 0;
public $is_single = false; ☂
public $is_preview = false; ☂
public $is_page = false; ☂
public $is_archive = false; ☂
public $is_date = false; ☂
public $is_year = false; ☂
public $is_month = false; ☂
public $is_day = false; ☂
public $is_time = false; ☂
public $is_author = false; ☂
public $is_category = false; ☂
public $is_tag = false;
public $is_tax = false;
public $is_search = false; ☂
public $is_feed = false; ☂
public $is_comment_feed = false;
public $is_trackback = false; ☂
public $is_home = false; ☂
public $is_404 = false; ☂
public $is_embed = false;
public $is_paged = false;
public $is_admin = false; ☂
public $is_attachment = false;
public $is_singular = false;
public $is_robots = false;
public $is_posts_page = false;
public $is_post_type_archive = false;
private $query_vars_hash = false;
private $query_vars_changed = true;
public $thumbnails_cached = false;
private $stopwords;
private $compat_fields = array('query_vars_hash', 'query_vars_changed');
private $compat_methods = array('init_query_flags', 'parse_tax_query');
private function init_query_flags()
WP_Query
İsviçre çakısıdır.
Hakkında bazı şeyler WP_Query
:
- geçtiğiniz argümanlar ile kontrol edebileceğiniz bir şey
- varsayılan olarak açgözlü
- döngü için maddeyi tutar
- x2 global alanına kaydedilir
- birincil veya ikincil olabilir
- yardımcı sınıfları kullanır
- kullanışlı bir
pre_get_posts
kancası var
- iç içe döngüler için bile desteği var
- SQL sorgu dizesini tutar
- sonuçların sayısını tutar
- sonuçları tutar
- olası tüm sorgu bağımsız değişkenlerinin listesini tutar
- şablon bayraklarını tutar
- ...
Tüm bunları açıklayamıyorum, ancak bunların bazıları zor, bu yüzden kısa ipuçları verelim.
WP_Query
geçtiğiniz argümanlar ile kontrol edebileceğiniz bir şeydir
The list of the arguments
---
attachment
attachment_id
author
author__in
author__not_in
author_name
cache_results
cat
category__and
category__in
category__not_in
category_name
comments_per_page
day
embed
error
feed
fields
hour
ignore_sticky_posts
lazy_load_term_meta
m
menu_order
meta_key
meta_value
minute
monthnum
name
no_found_rows
nopaging
order
p
page_id
paged
pagename
post__in
post__not_in
post_name__in
post_parent
post_parent__in
post_parent__not_in
post_type
posts_per_page
preview
s
second
sentence
static
subpost
subpost_id
suppress_filters
tag
tag__and
tag__in
tag__not_in
tag_id
tag_slug__and
tag_slug__in
tb
title
update_post_meta_cache
update_post_term_cache
w
year
WordPress sürüm 4.7'deki bu liste gelecekte kesinlikle değişecektir.
Bu WP_Query
, bağımsız değişkenlerden nesneyi oluşturan en az örnek olacaktır :
// WP_Query arguments
$args = array ( /* arguments*/ );
// creating the WP_Query object
$query = new WP_Query( $args );
// print full list of arguments WP_Query can take
print ( $query->query_vars );
WP_Query
açgözlü
get all you can
WordPress geliştiricileri , performans için iyi olduğu için mümkün olan tüm verileri erkenden almaya karar verdikleri fikri üzerine kuruldu . Bu nedenle, sorgu veritabanından 10 yazı aldığında varsayılan olarak, bu yazıların terimlerini ve meta verilerini ayrı sorgular yoluyla alır. Terimler ve meta veriler önbelleğe alınır (önceden getirilir).
Önbelleklemenin yalnızca tek bir istek ömrü için olduğunu unutmayın.
Eğer ayarlarsanız önbelleğe alma devre dışı bırakabilir update_post_meta_cache
ve update_post_term_cache
karşı false
ayarlarken WP_Query
argümanlar. Önbellek devre dışı bırakıldığında, veriler yalnızca istek üzerine veritabanından istenir.
WordPress bloglarının çoğunda önbellekleme iyi çalışır, ancak önbelleği devre dışı bırakabileceğiniz bazı durumlar vardır.
WP_Query
yardımcı sınıfları kullanır
WP_Query
Orada alanları işaretlediyseniz , şu üç tanesine sahipsiniz:
public $tax_query;
public $meta_query;
public $date_query;
Gelecekte yeni eklemeyi hayal edebilirsiniz.
WP_Query
Döngü maddesini tutar
Bu kodda:
$query = new WP_Query( $args )
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
WP_Query
yineleyebileceğiniz maddeye sahip olduğunu fark edebilirsiniz. Yardımcı yöntemler de var. Sadece while
döngüyü ayarladýn .
Not. for
ve while
döngüler semantik olarak eşdeğerdir.
WP_Query
birincil ve ikincil
WordPress'te bir birincil ve sıfır veya daha fazla ikincil sorgunuz vardır.
Birincil sorguya sahip olmak mümkün değildir, ancak bu makalenin kapsamı dışındadır.
Ana sorgu veya normal sorgu olarak bilinen birincil sorgu . İkincil sorgu , özel sorgu olarak da adlandırılır .
WordPress WP_Rewrite
, URL'ye dayalı sorgu bağımsız değişkenleri oluşturmak için sınıfı erken kullanır . Bu argümanlara dayanarak, küresel alanda iki özdeş nesneyi saklar. Bunların her ikisi de ana sorguyu tutacaktır.
global $wp_query @since WordPress 1.5
global $wp_the_query @since WordPress 2.1
Biz derken ana sorgu biz bu değişkenlerden düşünüyorum. Diğer sorgular ikincil veya özel olarak adlandırılabilir.
Kullanımı ya tamamen yasaldır global $wp_query
ya $GLOBALS['wp_query']
, ama ikinci gösterimi kullanarak çok daha dikkate değer olduğunu ve işlevlerin kapsamı içine ek bir satır yazarak kaydeder.
$GLOBALS['wp_query']
ve $GLOBALS['wp_the_query']
ayrı nesnelerdir. $GLOBALS['wp_the_query']
donmuş kalmalıdır.
WP_Query
kullanışlı pre_get_posts
kanca var.
Bu eylem kancası. Herhangi bir WP_Query
örnek için geçerli olacaktır . Buna şöyle diyorsunuz:
add_action( 'pre_get_posts', function($query){
if ( is_category() && $query->is_main_query() ) {
// set your improved arguments
$query->set( ... );
...
}
return $query;
});
Bu kanca harika ve herhangi bir sorgu bağımsız değişkenini değiştirebilir.
İşte okuyabileceğiniz şeyler :
Sorgu değişkeni nesnesi oluşturulduktan sonra, ancak gerçek sorgu çalıştırılmadan önce tetiklenir.
Yani bu kanca argüman yöneticisidir ancak yeni WP_Query
nesneler oluşturamaz . Bir birincil ve bir ikincil sorgunuz varsa, pre_get_posts
üçüncü sorguyu oluşturamazsınız. Veya sadece bir birinciliniz varsa, ikinciyi oluşturamaz.
Ana sorguyu değiştirmeniz gerektiğinde, sadece request
kanca kullanabilirsiniz .
WP_Query
iç içe halkaları destekler
Eklenti kullanıyorsanız ve şablondan eklenti işlevlerini çağırırsanız bu senaryo oluşabilir.
WordPress'in iç içe döngüler için bile yardımcı işlevlere sahip olduğu vitrin örneği:
global $id;
while ( have_posts() ) : the_post();
// the custom $query
$query = new WP_Query( array( 'posts_per_page' => 5 ) );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
echo '<li>Custom ' . $id . '. ' . get_the_title() . '</li>';
endwhile;
}
wp_reset_postdata();
echo '<li>Main Query ' . $id . '. ' . get_the_title() . '</li>';
endwhile;
Tema birimi test verilerini kurduğumdan çıktı şu şekilde olacak :
Custom 100. Template: Sticky
Custom 1. Hello world!
Custom 10. Markup: HTML Tags and Formatting
Custom 11. Markup: Image Alignment
Custom 12. Markup: Text Alignment
Custom 13. Markup: Title With Special Characters
Main Query 1. Hello world!
Özel $ sorgusunda 5 mesaj istediğim halde, yapışkan yazı devam edeceği için bana altı dönecek. wp_reset_postdata
Önceki örnekte hayır varsa , çıkış $GLOBALS['post']
geçersiz olacağından çıktı bu şekilde olacaktır.
Custom 1001. Template: Sticky
Custom 1. Hello world!
Custom 10. Markup: HTML Tags and Formatting
Custom 11. Markup: Image Alignment
Custom 12. Markup: Text Alignment
Custom 13. Markup: Title With Special Characters
Main Query 13. Markup: Title With Special Characters
WP_Query
vardır wp_reset_query
işlevi
Bu bir sıfırlama düğmesi gibidir. $GLOBALS['wp_the_query']
her zaman dondurulmalı ve eklentiler veya temalar asla değiştirilmemelidir.
İşte wp_reset_query
yapmanız gerekenler:
function wp_reset_query() {
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
wp_reset_postdata();
}
İle ilgili açıklamalar get_posts
get_posts
benziyor
File: /wp-includes/post.php
1661: function get_posts( $args = null ) {
1662: $defaults = array(
1663: 'numberposts' => 5,
1664: 'category' => 0, 'orderby' => 'date',
1665: 'order' => 'DESC', 'include' => array(),
1666: 'exclude' => array(), 'meta_key' => '',
1667: 'meta_value' =>'', 'post_type' => 'post',
1668: 'suppress_filters' => true
1669: );
... // do some argument parsing
1685: $r['ignore_sticky_posts'] = true;
1686: $r['no_found_rows'] = true;
1687:
1688: $get_posts = new WP_Query;
1689: return $get_posts->query($r);
Satır numaraları gelecekte değişebilir.
Bu sadece bir olan sarıcı etrafında WP_Query
o iadeler sorgu nesnesi mesajlar.
ignore_sticky_posts
Gerçek araçlarına seti yapışkan mesajlar sadece doğal bir konumda gösterilmesine olabilir. Ön kısımda yapışkan yazı olmayacak. Diğer no_found_rows
true olarak ayarlandığında, WordPress veritabanı API'sinin sayfa SQL_CALC_FOUND_ROWS
numaralandırma uygulamak için kullanılmayacağı, bulunan satırları yürütmek için veritabanındaki yükün azaltılacağı anlamına gelir sayısını .
Sayfalandırmaya ihtiyacınız olmadığında kullanışlıdır. Şimdi anlıyoruz ki bu sorgu ile bu fonksiyonu taklit edebiliriz:
$args = array ( 'ignore_sticky_posts' => true, 'no_found_rows' => true);
$query = new WP_Query( $args );
print( $query->request );
İlgili SQL isteği şöyledir:
SELECT 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, 10
Şu anda sahip olduklarımızı, önceki SQL isteğiyle karşılaştırın SQL_CALC_FOUND_ROWS
.
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, 10
Olmadan istek SQL_CALC_FOUND_ROWS
daha hızlı olacaktır.
İle ilgili açıklamalar query_posts
İpucu: İlk olarak 2004'te sadece vardı global $wp_query
. WordPress 2.1 sürümünden itibaren $wp_the_query
geldi. İpucu: $GLOBALS['wp_query']
ve $GLOBALS['wp_the_query']
ayrı nesnelerdir.
query_posts()
bir WP_Query
sargı. Ana WP_Query
nesneye başvuruyu döndürür ve aynı zamanda global $wp_query
.
File: /wp-includes/query.php
function query_posts($args) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
PHP4'te nesneler dahil her şey değere göre geçirildi. query_posts
şöyleydi:
File: /wp-includes/query.php (WordPress 3.1)
function &query_posts($args) {
unset($GLOBALS['wp_query']);
$GLOBALS['wp_query'] =& new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
Bir birincil ve bir ikincil sorgu içeren tipik senaryoda şu üç değişkene sahip olduğumuzu lütfen unutmayın:
$GLOBALS['wp_the_query']
$GLOBALS['wp_query'] // should be the copy of first one
$custom_query // secondary
Diyelim ki bu üçünün her biri 1M bellek alıyor. Toplam 3M bellek olacaktır. Eğer kullanırsak query_posts
, $GLOBALS['wp_query']
ayarlanmayacak ve yeniden yaratılacaktır.
PHP5 + $GLOBALS['wp_query']
nesneyi boşaltmak için akıllı olmalı , tıpkı PHP4'te olduğu gibiunset($GLOBALS['wp_query']);
function query_posts($args) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
Sonuç olarak query_posts
toplamda 2M bellek get_posts
tüketirken, 3M bellek tüketir.
query_posts
Gerçek nesneyi değil, nesneye bir referans döndürdüğümüzü unutmayın .
Gönderen php.net : bir PHP referans aynı değere yazma için iki farklı değişkenleri sağlayan bir diğer addır. PHP 5'ten itibaren, bir nesne değişkeni artık değer olarak nesnenin kendisini içermez. Yalnızca nesne erişimcilerinin gerçek nesneyi bulmasına izin veren bir nesne tanımlayıcı içerir. Bir nesne bağımsız değişkenle gönderildiğinde, döndürüldüğünde veya başka bir değişkene atandığında, farklı değişkenler takma ad değildir: tanımlayıcının aynı nesneyi işaret eden bir kopyasını tutarlar.
Ayrıca PHP5 + 'da assign (=) operatörü akıllıdır. Sert kopya değil, sığ kopya kullanır . Bu şekilde yazdığımızda $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
, veriler aynı nesne türünü paylaştığından tüm veriler değil, yalnızca veriler kopyalanacaktır.
İşte bir örnek
print( md5(serialize($GLOBALS['wp_the_query']) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
query_posts( '' );
print( md5(serialize($GLOBALS['wp_the_query']) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Sonuçlanacak:
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
d6db1c6bfddac328442e91b6059210b5
Sorguyu sıfırlamayı deneyin:
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
query_posts( '' );
wp_reset_query();
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Sonuçlanacak:
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
Kullansanız bile sorun yaratabilirsiniz WP_Query
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
global $wp_query;
$wp_query = new WP_Query( array( 'post_type' => 'post' ) );
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Tabii ki, çözüm wp_reset_query
işlevi tekrar kullanmak olacaktır .
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
global $wp_query;
$wp_query = new WP_Query( array( 'post_type' => 'post' ) );
wp_reset_query();
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Bu yüzden query_posts
bellek açısından daha iyi olabileceğini düşünüyorum . Ama her zaman wp_reset_query
hile yapmalısın .