私のホームページには、最後の5つのおすすめ投稿を表示しなければならないセクションがあります。注目投稿は、カスタムフィールドis_featuredを1に設定した投稿です。
私は2つの異なるタイプのコードで欲しいものを達成しました:
Wpdbを使う
<?php
$featuredPosts = $wpdb->get_results("
SELECT ID, post_title FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->postmeta.meta_key = 'is_featured'
ORDER BY ID DESC LIMIT 5
");
if ($featuredPosts)
{
$htmlOutput = '';
foreach ($featuredPosts as $featPost)
$htmlOutput .= '<br /><a href="'.get_permalink($featPost->ID).'">'.$featPost->post_title.'</a>';
}
echo $htmlOutput;
?>
"Query Monitor"プラグインによると、このクエリは0.1秒かかり、次のSQLを生成します。
SELECT ID, post_title
FROM wp_posts LEFT JOIN wp_postmeta ON(wp_posts.ID = wp_postmeta.post_id)
WHERE wp_postmeta.meta_key = 'is_featured'
ORDER BY ID DESC
LIMIT 5
Wordpressのネイティブコールを使う
<?php
$featuredPostsRevised = new WP_Query
(
array
(
'meta_query' => array
(
array
(
'key' => 'is_featured'
)
)
)
);
while($featuredPostsRevised->have_posts()) : $featuredPostsRevised->the_post();
?>
<br />
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
<?php
endwhile;
?>
"Query Monitor"プラグインによると、このクエリは0.2秒かかり、どういうわけか長いSQLを生成します。
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta
ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private')
AND (wp_postmeta.meta_key = 'is_featured' )
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
私の質問は:
wpdb
クエリをどのようにprepare()
することができますか?私は試したが、2番目のパラメータのために管理できませんでした。
Prepareを使用した後、セキュリティとパフォーマンスの観点から、wpdb
が本当に良い解決策であると私は思っていますか?
どうやってwpdbクエリをprepare()できますか?私は試したが、2番目のパラメータのために管理できませんでした。
prepare()
の動作は Codex で説明されています。プレースホルダとそのプレースホルダを置き換える追加の引数を持つクエリが必要です。プレースホルダがない(つまりクエリ内に可変部分がない)場合は、 esc_sql を使用してSQLインジェクションを回避できますが、これはクエリがユーザ入力を使用して構築されている場合にのみ意味があります。 OPのクエリは完全にハードコードされているので、prepare()
やesc_sql()
の必要はありません。
Prepareを使用した後、セキュリティとパフォーマンスの観点から、wpdbが本当に優れたソリューションであると私は思っていますか?
簡単な答え: いいえ 。 WP_Query
は、クエリに対する単なる上位レベルのアプローチです。クエリ文字列を作成し、$wpdb
を使用してデータベース内でそのSQLクエリを実行します。
OPで2つのクエリを見た場合、たとえば、$wpdb
を使用して実行されたクエリは投稿ステータス、投稿日、または投稿パスワードを考慮に入れていません。それらはユーザーに表示されます。また、クエリは結果の順序やその他のものを考慮に入れていません。すべてを考慮に入れた複雑なクエリ文字列を構築してから$wpdb
を使用して実行できるのであれば、2つの可能性があります。
WP_Query
にすでにcoreで処理されている多くのコードを書くべきです:それは意味がありません。考慮すべきもう1つの重要な要素があります:WP_Query
はかなりたくさんの フィルタとアクションフック を起動します、そして何千ものプラグインとテーマはそれらに頼ります:ループのためのmanual$wpdb
クエリを実行することによってたくさんのことを破る。
そのため、postsをクエリする必要がある場合はWP_Query
を使用します。数ミリ秒は何時間ものコードやフラストレーションの価値がありません。 $wpdb
は、コアで処理されていないクエリを実行する必要がある場合にのみ使用してください。
ここに @TomJNowell を追加する価値があります。
また、WP_Query
を使用すると、WordPressが保持している大量の内部キャッシュを利用できるようになります。たとえば、2度目にクエリを実行した場合などに1回検索したりできます。たぶん、あなたはおそらくあなたの仕事をするためにジョブキューかCLIスクリプトを使うべきです(あなたがたった10人のユーザーとたくさんのお金をサーバーに費やすのでなければ)。