我有以下代码从我的数据库中获取字段并将它们放入html表单的Formats下拉菜单中。在它的当前形式中,我从我的数据库中取出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,但代码只会吐出一级孩子而忽略其余的孩子。
出于演示目的,如果我有第6行:
term_id name slug taxonomy parent
6 Single single format 2
然后代码会这样做:
Entry Form
Twitter
Facebook
- Entry Form
- Page
请注意,Single完全被忽略,但它包含在$ getChildren数组中。
那么如何使这些代码更好?
答案 0 :(得分:1)
第6行的父级值为2.虽然具有term_id 2的行的父级值为3,因此不包含在父对象中。
我可能会使用一个函数来实现这个目标;
$getTerms = $wpdb->get_results($wpdb->prepare("
SELECT * FROM wp_terms p
WHERE t.taxonomy = 'format'
ORDER BY p.name ASC"));
$terms = array();
foreach($getTerms as $key => $term){
$terms[$term->parent][$term->term_id] = $term;
}
function printTerms($terms, $parent = 0, $deep = 0){
if(count($terms[$parent]) > 0){
$indent = "";
for($i = 0; $i < $deep; $i++){
$indent .= " ";
}
foreach($terms[$parent] as $key => $term){
if(count($terms[$term->term_id]) > 0){
if($deep == 0){
echo "<optgroup label='".$term->name."'></optgroup>";
} else {
echo "<option value='".$term->name."'>".$indent.$term->name."</option>";
}
printTerms($terms, $term->term_id, ($deep+1));
} else {
echo "<option value='".$term->name."'>".$indent.$term->name."</option>";
}
}
}
}
?>
<select name="format">
<option value="empty"></option>
<?php printTerms($terms); ?>
</select>
答案 1 :(得分:0)
您需要将输出设置为如下所示,以便在选择中创建标题:
<select>
<optgroup label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
这意味着您需要以某种方式识别哪个输出应该是标签以及应该选择什么。
答案 2 :(得分:0)
没有测试它,但我会先创建一个包含所有ID的分层数组:
$items = array();
$ids = array();
foreach ($getFormats as $format) {
$items[$format->term_id] = $format;
if (isset($format->parent)) {
$ids[$format->parent->term_id][] = $format->term_id;
} else $ids[$format->term_id] = null;
}
然后,可以轻松浏览此数组并创建HTML代码:
foreach ($ids as $id => $subIds) {
if (!empty($subIds)) {
echo '<optgroup label="' . $items[$id]->name . '">';
foreach ($subIds as $subId)
echo '<option value="' . $items[$subId]->name . '">' . $items[$subId]->name . '</option>';
echo '</optgroup>';
} else {
echo '<option value="' . $items[$id]->name . '">' . $items[$id]->name . '</option>';
}
}