我有一个显示类别和子类别列表的表,使用一个函数来遍历父/子树。这是脚本的标记:
<table border="1" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<?php
function category_list( $category_parent_id = 0 )
{
// build our category list only once
static $cats;
if ( ! is_array( $cats ) )
{
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id';
$res = tep_db_query( $sql );
$cats = array();
while ( $cat = tep_db_fetch_array( $res ) )
{
$cats[] = $cat;
}
}
// populate a list items array
$list_items = array();
foreach ( $cats as $cat )
{
// if not a match, move on
if ( ( int ) $cat['parent_id'] !== ( int ) $category_parent_id )
{
continue;
}
// open the list item
$list_items[] = '<tr class="dataTableRow">';
$list_items[] = '<td class="dataTableContent"><li>';
// construct the category link
$list_items[] = $cat['categories_name'];
// recurse into the child list
$list_items[] = category_list( $cat['categories_id'] );
// close the list item
$list_items[] = '</li></td>';
$list_items[] = '</tr>';
}
// convert to a string
$list_items = implode( '', $list_items );
// if empty, no list items!
if ( '' == trim( $list_items ) )
{
return '';
}
// ...otherwise, return the list
return '<ul>' . $list_items . '</ul>';
}
echo category_list();
?>
<td class="dataTableContent"></td>
</table>
目前此处正确打印<tr class="dataTableHeadingRow">
和<td class="dataTableHeadingContent">
,但对于<td class="dataTableContent">
,它只会正确打印该功能中的标签。如何正确打印dataTableContent标签,并将它们保存在循环中?
答案 0 :(得分:1)
查看函数category_list
的递归使用,您将在 <tr>
内输出<li>
个元素。这是invaild HTML。
此外,正文中的每个<tr>
只有一个单元格,而标题行中的<tr>
有两个单元格。
您应该考虑输出的外观,然后编写代码来解释它,并按照流程查看正在写出的内容。另外,请检查返回到浏览器的实际HTML源代码,而不是浏览器的呈现方式。请注意,不同的浏览器会以不同的方式呈现无效的HTML。
此外,(与您的问题无关)请考虑使用CSS替换border
,width
,cellspacing
,cellpadding
和align
HTML属性。另一个考虑因素是使用<head>
和<tbody>
元素作为附加语义标记。
进一步说明
你的问题基本上就是这些问题:
// open the list item
$list_items[] = '<tr class="dataTableRow">';
$list_items[] = '<td class="dataTableContent"><li>';
// construct the category link
$list_items[] = $cat['categories_name'];
// recurse into the child list
$list_items[] = category_list( $cat['categories_id'] );
// close the list item
$list_items[] = '</li></td>';
$list_items[] = '</tr>';
循环的每次迭代都会创建一个新的tr
元素!试试这个:
<table border="1" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<tr class="dataTableRow">
<td class="dataTableContent">
<?php
function category_list( $category_parent_id = 0 )
{
// NOTE THE ADDITIION OF THE PARENT ID:
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
$res = tep_db_query( $sql );
$cats = array();
while ( $cat = tep_db_fetch_array( $res ) )
{
$cats[] = $cat;
}
if (count($cats) == 0)
{
// There are no categories to list
return '';
}
// Create a list HTML string
$list = '<ul>';
foreach ( $cats as $cat )
{
// open the list item
$list .= '<li>';
// construct the category link
$list .= $cat['categories_name'];
// recurse into the child list
$list .= category_list( $cat['categories_id'] );
// close the list item
$list .= '</li>';
}
// close and return the list
$list .= '</ul>';
return $list;
}
echo category_list();
?>
</td>
<td class="dataTableContent"></td>
</tr>
</table>
请注意,可以对数据和表示逻辑分离进行进一步改进。您不一定需要采用全面的MVC框架;只需使用OOP将SQL查询封装在代表数据库实体的类中。
修改强>
遵循规范,每个类别都应该在自己的<td>
。
这需要删除列表元素。 <ul>
只能包含<li>
元素作为子元素;它不能包含<tr>
个孩子。 <td>
必须是<tr>
的孩子。其他任何地方都不允许这样做。 <tr>
只能是<thead>
,<tbody>
*或<tfoot>
的孩子。这些规则都在HTML DTD中定义。
因此,您需要注意以下几点:
<table border="1" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<?php
function category_list( $category_parent_id = 0, $level = 0 )
{
// NOTE THE ADDITIION OF THE PARENT ID:
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
$res = tep_db_query( $sql );
$cats = array();
while ( $cat = tep_db_fetch_array( $res ) )
{
$cats[] = $cat;
}
$list = '';
foreach ( $cats as $cat )
{
// start the next row:
$list .= "<tr class=\"dataTableRow\">\n";
// The cell for the category needs
$list .= "<td class=\"dataTableContent\">\n";
// construct the category link. Note we are now enclosing
// this in a div with a left-indent to show the sub level
// this category is at. Adjust the padding-left calculation
// to suit your page
$list .= '<div style="padding-left: ' . (2 * $level) . 'em;">';
$list .= "• {$cat['categories_name']}";
$list .= "</div>\n";
// close the row
$list .= "</td>\n";
$list .= "<td class=\"dataTableContent\"></td>\n";
$list .= "</tr>\n";
// recurse into the child list, incrementing $level
$list .= category_list( $cat['categories_id'], 1+$level );
}
// return the list
return $list;
}
echo category_list();
?>
</table>
*请注意,<tbody>
是隐含的元素。它不必在代码中明确定义,但它始终存在于DOM中。
答案 1 :(得分:0)
要遍历数组并将内容显示为表的一部分,我会将您的业务逻辑与显示逻辑分开一点。我的解决方案如下:
<!-- populate the array of data to be displayed -->
<?php $list_items = category_list(); ?>
<!-- start the table, display header rows -->
<table border="1" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<tr class="dataTableRow">
<td class="dataTableContent">
<ul>
<!-- iterate over data array, create ul for each member -->
<?php
foreach($list_items as $item) {
?>
<li><?php print $item ?></li>
<?php
}
?>
</ul>
<!-- finish the table -->
</td>
</tr>
</table>
<!-- define function which will populate your array -->
<?php
function category_list( $category_parent_id = 0 )
{
/*
this function will look very similar to the one in the
one in the original post but will just return the whole
array instead of printing out one member.
*/
// populate $items_list...
return $items_list;
}
?>
请注意我没有测试这个不完整的代码,但这个想法应该是正确的。
答案 2 :(得分:-1)
尝试替换以下代码:
$list_items[] = '<tr class="dataTableRow">';
$list_items[] = '<td class="dataTableContent"><li>';
使用:
$list_items[] = "<tr class='dataTableRow'>";
$list_items[] = "<td class='dataTableContent'><li>";