
在网页开发中,我们经常需要将一系列数据项(例如产品列表、文章列表)按特定数量进行分组展示。例如,每3个项目构成一行,并用一个父div包裹。更进一步的需求是,这个父div需要一个css类,能够准确反映当前组内项目的实际数量,如projectitemcount-3或projectitemcount-2。这对于前端样式控制(例如,根据项目数量调整布局或间距)至关重要。
原始代码尝试通过 $i % 3 == 0 来判断分组的开始和结束,并使用 $griditemcounter 来追踪组内项目。然而,它在为父div添加 projectcount-X 类时,未能准确计算出当前组的实际项目数量,尤其是在遇到最后一组项目不足指定数量时。解决这个问题的关键在于,我们需要在关闭一个分组的父div时,才能准确得知该分组内包含了多少个项目。
为了准确地实现动态分组和计数,我们将采用以下策略:
这种“先收集,后输出”的缓冲机制,能够确保在输出父div时,我们已经掌握了该组内所有项目的准确数量。
下面我们将通过一个PHP代码示例来详细展示如何实现这一功能。
立即学习“PHP免费学习笔记(深入)”;
<?php
// 模拟数据源:假设我们有10个项目
// 在实际应用中,这通常来自数据库查询结果,例如WordPress的WP_Query循环
$all_items_data = [];
for ($k = 0; $k < 10; $k++) {
$all_items_data[] = (object)[
'id' => $k + 1,
'title' => '项目 ' . ($k + 1),
'permalink' => '#item-' . ($k + 1),
'image_url_large' => 'https://via.placeholder.com/940x1260?text=Item+' . ($k + 1),
'image_url_small' => 'https://via.placeholder.com/768x375?text=Item+' . ($k + 1),
'terms' => [ (object)['name' => '分类' . (($k % 2) + 1)] ] // 模拟分类
];
}
$items_per_row = 3; // 每行/每组显示的项目数量
$total_items = count($all_items_data); // 总项目数
$output_html = ''; // 用于累积最终的HTML输出
$current_row_items_buffer = []; // 缓冲区,存储当前组内的项目HTML
$row_counter = 0; // 用于追踪当前是第几行,可用于交替样式(如grid-first/second)
// 遍历所有项目
for ($global_index = 0; $global_index < $total_items; $global_index++) {
$item = $all_items_data[$global_index]; // 获取当前项目数据
// 构建单个项目(project_item)的HTML
$item_html = '<div class="project_item grid' . (($global_index % $items_per_row) + 1) . '"';
$item_html .= ' style="background-image:url(' . ($item->image_url_large ?: 'https://via.placeholder.com/940x1260') . ')">';
$item_html .= '<a href="' . ($item->permalink ?: '#') . '">';
$item_html .= '<div class="project_item_img"><img src="' . ($item->image_url_small ?: 'https://via.placeholder.com/768x375') . '" alt="' . esc_attr($item->title) . '"/></div>';
$item_html .= '<div class="et_pb_text_inner project_item_content">';
$item_html .= '<h3>' . esc_html($item->title) . '</h3>';
// 模拟获取分类信息并输出
if (!empty($item->terms)) {
foreach ($item->terms as $term) {
$item_html .= '<p>' . esc_html($term->name) . '</p>';
}
}
$item_html .= '</div>';
$item_html .= '</a>';
$item_html .= '</div>';
// 将当前项目HTML添加到缓冲区
$current_row_items_buffer[] = $item_html;
// 判断是否需要关闭当前行(组)并输出
// 条件1: 缓冲区已满,达到每行项目数
// 条件2: 这是最后一个项目,无论缓冲区是否已满,都需要输出
if (count($current_row_items_buffer) == $items_per_row || $global_index == $total_items - 1) {
$items_in_this_row = count($current_row_items_buffer); // 获取当前组的实际项目数量
// 构建父div的类名
$row_class = 'project_row projectitemcount-' . $items_in_this_row;
// 可选:根据行号添加交替样式
$row_class .= ' grid-' . (($row_counter % 2 == 0) ? 'first' : 'second');
// 输出父div的开始标签
$output_html .= '<div class="' . $row_class . '">';
// 输出缓冲区中的所有项目
foreach ($current_row_items_buffer as $buffered_item_html) {
$output_html .= $buffered_item_html;
}
// 输出父div的结束标签
$output_html .= '</div>';
// 重置缓冲区,为下一个分组做准备
$current_row_items_buffer = [];
$row_counter++; // 增加行计数器
}
}
// 最终输出生成的HTML
echo $output_html;
// 辅助函数,用于模拟WordPress的转义函数
function esc_attr($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); }
function esc_html($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); }
?>代码解释:
.project_row {
display: flex;
flex-wrap: wrap;
margin-bottom: 20px;
}
.project_row.projectitemcount-3 .project_item {
flex: 0 0 calc(33.333% - 20px); /* 3 items per row with gap */
margin: 10px;以上就是PHP教程:按迭代次数分组内容并准确统计每组项目数量的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号