PHPCMS V9 字段筛选功能搭建全教程
在 PHPCMS V9 中,所谓的“字段筛选”通常指的是在列表页(category)根据模型的自定义字段(如品牌、价格区间、颜色、材质等)进行动态筛选,从而让用户可以快速找到符合自己需求的内容。

(图片来源网络,侵删)
这个功能的核心在于 URL 规则 和 PHP 逻辑处理 的结合,下面我们以一个具体的例子来详细拆解整个过程。
场景设定
假设我们有一个产品模型,需要实现以下筛选功能:
- 品牌筛选:苹果、华为、小米
- 价格筛选:0-1000, 1000-3000, 3000以上
- 颜色筛选:黑色、白色、金色
第一步:准备工作 - 创建模型和字段
在实现筛选之前,你必须确保你的数据模型和字段已经正确创建。
- 登录后台:使用管理员账号登录 PHPCMS V9 后台。
- 进入模型管理:在左侧菜单栏中,找到 ->
模型管理->内容模型管理。 - 创建或选择模型:
- 如果是新内容,请先创建一个模型(命名为“产品模型”)。
- 如果已有模型(如文章模型),可以直接使用,但为了演示清晰,我们假设你创建了一个新的模型。
- 添加字段:
- 在模型管理页面,点击你刚创建的模型名称,进入字段管理。
- 添加以下字段(注意字段类型的选择):
brand(品牌):字段类型选择单选,选项填写:苹果,华为,小米。price(价格):字段类型选择数字,用于存储具体价格。color(颜色):字段类型选择多选,选项填写:黑色,白色,金色。- (可选)
price_range(价格区间):字段类型选择单选,选项填写:0-1000元,1000-3000元,3000元以上,这个字段可以用于手动选择区间,但我们更推荐通过price字段进行动态计算,这样更灵活。
重要提示:

(图片来源网络,侵删)
- 字段名:请务必记住你添加的字段名(如
brand,price,color),后续所有代码都会用到它们。 - 内容录入:回到 ->
内容管理,为你的模型添加一些测试数据,确保这些字段都有值,方便后续测试。
第二步:修改列表页模板文件 (category.php)
这是实现筛选功能的核心步骤,我们需要在模板文件中添加筛选的 HTML 表单,并编写 PHP 逻辑来处理筛选条件。
- 找到模板文件:在你的模板目录下,找到对应分类的列表页模板文件,通常是
phpcms/templates/你的模板名/category.php。 - 添加筛选表单:在列表页的适当位置(列表上方)添加筛选表单的 HTML 代码。
<!-- 筛选表单开始 -->
<div class="filter">
<form action="" method="get" id="filter_form">
<!-- 隐藏分类ID,确保筛选后仍在当前分类 -->
<input type="hidden" name="catid" value="{catid}" />
<!-- 品牌筛选 (单选) -->
<div class="filter-item">
<span class="filter-title">品牌:</span>
<a href="{caturl}" {if !$filter.brand}class="active"{/if}>全部</a>
{loop $model_field['brand']['options'] $v}
<a href="{caturl}?brand={$v}" {if $filter.brand == $v}class="active"{/if}>{$v}</a>
{/loop}
</div>
<!-- 颜色筛选 (多选) -->
<div class="filter-item">
<span class="filter-title">颜色:</span>
<a href="{caturl}" {if !$filter.color}class="active"{/if}>全部</a>
{loop $model_field['color']['options'] $v}
<a href="{caturl}?color[]={$v}" {if in_array($v, $filter.color)}class="active"{/if}>{$v}</a>
{/loop}
</div>
<!-- 价格区间筛选 (单选) -->
<div class="filter-item">
<span class="filter-title">价格:</span>
<a href="{caturl}" {if !$filter.price_range}class="active"{/if}>全部</a>
{loop $model_field['price_range']['options'] $v}
{php $price_arr = explode('-', str_replace('元', '', $v));}
{php $min_price = $price_arr[0];}
{php $max_price = isset($price_arr[1]) ? $price_arr[1] : 9999999;}
<a href="{caturl}?price_range={$v}" {if $filter.price_range == $v}class="active"{/if}>{$v}</a>
{/loop}
</div>
</form>
</div>
<!-- 筛选表单结束 -->
<!-- 列表内容开始... -->
代码解释:
{caturl}:这是一个 PHPCMS 的内置变量,代表当前分类的 URL,它会自动包含catid参数。brand={$v}:这是构建筛选 URL 的关键,当用户点击“苹果”时,URL 就会变成...?catid=xx&brand=苹果。color[]={$v}:对于多选字段,我们使用color[]这样的数组形式,这样 PHP 后端可以轻松接收到多个值。class="active":用于高亮显示当前选中的筛选条件,你需要在前端 CSS 中定义这个样式。$model_field:这个变量包含了当前模型所有字段的配置信息,包括选项,我们可以用它来动态生成筛选链接,无需硬编码。
第三步:修改列表页程序文件 (category.php)
模板只是“样子”,真正的筛选逻辑需要写在 PHP 程序文件里,这个文件通常位于 phpcms/modules/content/你的模型名/ 目录下(如果你的模型是自定义的),或者直接修改 phpcms/modules/content/index.php(如果是通用模型)。
为了清晰,我们假设你的模型名为 product,那么程序文件就是 phpcms/modules/content/product.php。

(图片来源网络,侵删)
- 打开程序文件:用代码编辑器打开
phpcms/modules/content/product.php。 - 找到
category方法:这个方法是用来处理列表页显示的。 - 在
category方法中添加筛选逻辑:通常在 SQL 查询构建之前进行。
<?php
defined('IN_PHPCMS') or exit('No permission resources.');
pc_base::load_app_class('content','',0);
class product extends content {
public function __construct() {
parent::__construct();
}
public function category() {
// ... (这里保留原有的代码,如获取分类信息、设置SEO等)
// ======== 开始:添加我们的筛选逻辑 ========
// 1. 初始化筛选条件数组
$filter = array();
$where = '1=1'; // SQL 查询的初始条件
// 2. 处理品牌筛选 (单选)
if (isset($_GET['brand']) && $_GET['brand']) {
$brand = safe_replace($_GET['brand']); // 防止SQL注入
$filter['brand'] = $brand;
$where .= " AND a.brand = '{$brand}'";
}
// 3. 处理颜色筛选 (多选)
if (isset($_GET['color']) && is_array($_GET['color'])) {
$colors = array_map('safe_replace', $_GET['color']);
$color_str = implode("','", $colors);
$filter['color'] = $colors;
// 注意:如果你的颜色字段存储的是 '黑色,白色' 这样的字符串,用 LIKE
// 如果你的颜色字段设计为关联表,这里要用 IN
$where .= " AND (a.color LIKE '%{$colors[0]}%'"; // 动态构建,至少有一个
for($i = 1; $i < count($colors); $i++) {
$where .= " OR a.color LIKE '%{$colors[$i]}%'";
}
$where .= ")";
}
// 4. 处理价格区间筛选 (单选)
if (isset($_GET['price_range']) && $_GET['price_range']) {
$price_range = safe_replace($_GET['price_range']);
$filter['price_range'] = $price_range;
// 解析价格区间字符串
if (strpos($price_range, '以上') !== false) {
$min_price = (int)str_replace('元以上', '', $price_range);
$where .= " AND a.price >= {$min_price}";
} else {
$price_arr = explode('-', str_replace('元', '', $price_range));
$min_price = (int)$price_arr[0];
$max_price = (int)$price_arr[1];
$where .= " AND a.price BETWEEN {$min_price} AND {$max_price}";
}
}
// 5. 将筛选条件传递给模板
$this->assign('filter', $filter);
// ======== 结束:我们的筛选逻辑 ========
// ... (这里保留原有的代码,如获取分页信息等)
// 6. 修改 SQL 查询,将我们的 $where 条件加入进去
// 找到类似 $sql = "SELECT ... FROM ... WHERE ..." 的地方
// 在 WHERE 后面加上我们的 $where 条件
// 原始SQL可能是:
// $sql = "SELECT a.*,b.content FROM `v9_product` a LEFT JOIN `v9_product_data` b ON a.id=b.id WHERE a.catid='$catid' $where ORDER BY listorder ASC,id DESC";
// 注意:v9_product 和 v9_product_data 是你的数据表前缀+表名,需要根据实际情况修改。
// ... (后续的分页、模板赋值、显示等代码)
}
}
?>
代码解释:
$filter数组:用于收集所有有效的筛选条件,并最终传递给模板,以便模板可以正确高亮当前选中的项。safe_replace():这是一个非常重要的安全函数,用于过滤用户输入,防止 SQL 注入攻击,所有来自$_GET或$_POST的数据都应该经过此函数处理。$where字符串:这是我们要拼接到 SQL 查询WHERE子句中的条件,我们用AND来连接多个筛选条件。- 多选字段处理:多选字段的处理相对复杂,如果字段值是
黑色,白色这样的字符串,需要用LIKE和OR组合,如果设计的是关联表,则需要用IN ('值1', '值2'),上面的例子是针对字符串存储的。 - 价格区间处理:通过
explode函数分割字符串,得到最小和最大价格,然后用BETWEEN语法。 - 传递给模板:
$this->assign('filter', $filter);这行代码至关重要,它让模板中的{if $filter.brand == $v}这样的判断得以生效。
第四步:处理分页问题
当用户进行筛选后,分页链接也必须带上筛选条件,否则翻页后筛选就会失效。
- 找到分页代码:在
category方法中,找到生成分页链接的代码,通常是pages()函数。 - 修改分页参数:
pages()函数的第二个参数可以传入一个数组,用于在分页 URL 中附加额外的参数。
// 在 category 方法中,找到生成分页的地方 // 原始代码可能是这样: // $pages = pages($total, $page, $pagesize); // 修改为: // 将 $_GET 数组中除了 'page' 之外的所有参数都带上 $param = $_GET; unset($param['page']); // 移除 page 参数,因为分页函数会自己处理 $pages = pages($total, $page, $pagesize, '', $param);
这样,分页链接就会自动包含 ?catid=xx&brand=苹果&color[]=黑色 这样的完整筛选信息。
第五步:清除缓存
完成以上所有步骤后,请务必清除 PHPCMS 的缓存,否则看不到效果。
- 登录后台。
- 在顶部菜单栏找到
系统->缓存管理。 - 点击
更新全部缓存或至少清除模板缓存。
访问你的列表页,应该可以看到筛选器已经可以正常工作了,点击不同的筛选条件,列表会实时更新,URL 也会相应变化。
总结与注意事项
- 核心思想:URL 传递参数 -> PHP 接收并处理参数 -> 拼接 SQL 查询条件 -> 返回筛选后的结果。
- 安全性第一:永远不要直接使用用户输入的数据来构建 SQL,必须使用
safe_replace()或intval()等函数进行过滤。 - 灵活性:本教程提供了一个通用框架,你可以根据自己的字段类型(如下拉、联动、时间等)和业务需求,灵活调整 PHP 的处理逻辑。
- 性能考虑:当筛选条件非常复杂,或者数据量巨大时,复杂的 SQL 查询(特别是
LIKE和OR)可能会导致性能下降,此时可以考虑优化数据库索引或使用更高级的架构。 - 调试:如果遇到问题,可以在 PHP 代码中
print_r($filter);和echo $where;来检查筛选条件和最终生成的 SQL 是否正确。
希望这份详尽的教程能帮助你成功实现 PHPCMS V9 的字段筛选功能!
