データベースからフィールドをフェッチし、それらをフォーマットのhtmlフォームのドロップダウンメニューに配置する次のコードがあります。現在の形式では、データベースから3回フェッチしています。コードがどのように機能するかは、コードのコメントで説明されています。
$getSolos = $wpdb->get_results($wpdb->prepare("
SELECT * FROM wp_terms p
LEFT OUTER JOIN wp_term_taxonomy t ON p.term_id = t.term_id
WHERE t.taxonomy = 'format'
AND t.parent = 0
AND t.term_id NOT IN (SELECT parent FROM wp_term_taxonomy WHERE taxonomy = 'format' AND parent > 0)
ORDER BY t.parent
")); // This fetches all rows that do not have children or parents.
$getParents = $wpdb->get_results($wpdb->prepare("
SELECT * FROM wp_terms p
LEFT OUTER JOIN wp_term_taxonomy t ON p.term_id = t.term_id
WHERE t.taxonomy = 'format'
AND t.parent = 0
AND t.term_id IN (SELECT parent FROM wp_term_taxonomy WHERE taxonomy = 'format' AND parent > 0)
")); // This fetches all rows that have children
$getChildren = $wpdb->get_results($wpdb->prepare("
SELECT * FROM wp_terms p
LEFT OUTER JOIN wp_term_taxonomy t ON p.term_id = t.term_id
WHERE t.taxonomy = 'format'
AND t.parent > 0
ORDER BY t.parent
AND p.name
")); //This fetches all rows that ARE children
<select name="format"> //start the dropdown
<option value="empty"></option> //default field is empty
<?php
foreach ($getSolos as $solo) { //start loop through solos for output
echo "<option value='".$solo->name."'>".$solo->name."</option>"; // output solos as options in the dropdown
}
foreach ($getParents as $parent) { //start loop through parents for output
echo "<optgroup label='".$parent->name."'>"; // Spit out parent as an optgroup
foreach ($getChildren as $child) { //Start loop through children for output
if ($child->parent == $parent->term_id) { // if child's parent value matches the ID of the parent
echo "<option value='".$child->name."'> ".$child->name."</option>"; //Spit out the child as an option
}
}
echo "</optgroup>"; //close the optgroup
}
?>
</select> // end the dropdown
出力は次のとおりです。
Entry Form
Twitter
Facebook
- Entry Form
- Page
データベースの結合テーブルは次のようになります。
term_id name slug taxonomy parent
1 Entry Form entry-form format 0
2 Page page format 3
3 Facebook facebook format 0
4 Entry Form facebook-entry-form format 3
5 Twitter twitter format 0
ただし、この方法には問題があります。
1)データベースに3回アクセスするのは非効率的です。
2)子供にも子供がいる場合は効果がありません。子の子はすべて$getChildrenに入りますが、コードは第1レベルの子のみを吐き出し、残りは無視します。
デモンストレーションの目的で、6行目がある場合:
term_id name slug taxonomy parent
6 Single single format 2
次に、コードはこれを行います:
Entry Form
Twitter
Facebook
- Entry Form
- Page
Singleは完全に無視されますが、$getChildren配列内に含まれていることに注意してください。
では、どうすればこのコードを改善できるでしょうか。