PHPCMS V9 字段筛选功能搭建全教程

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

phpcms v9字段筛选教程
(图片来源网络,侵删)

这个功能的核心在于 URL 规则PHP 逻辑处理 的结合,下面我们以一个具体的例子来详细拆解整个过程。

场景设定

假设我们有一个产品模型,需要实现以下筛选功能:

  • 品牌筛选:苹果、华为、小米
  • 价格筛选:0-1000, 1000-3000, 3000以上
  • 颜色筛选:黑色、白色、金色

第一步:准备工作 - 创建模型和字段

在实现筛选之前,你必须确保你的数据模型和字段已经正确创建。

  1. 登录后台:使用管理员账号登录 PHPCMS V9 后台。
  2. 进入模型管理:在左侧菜单栏中,找到 -> 模型管理 -> 内容模型管理
  3. 创建或选择模型
    • 如果是新内容,请先创建一个模型(命名为“产品模型”)。
    • 如果已有模型(如文章模型),可以直接使用,但为了演示清晰,我们假设你创建了一个新的模型。
  4. 添加字段
    • 在模型管理页面,点击你刚创建的模型名称,进入字段管理。
    • 添加以下字段(注意字段类型的选择):
      • brand (品牌):字段类型选择 单选,选项填写:苹果,华为,小米
      • price (价格):字段类型选择 数字,用于存储具体价格。
      • color (颜色):字段类型选择 多选,选项填写:黑色,白色,金色
      • (可选) price_range (价格区间):字段类型选择 单选,选项填写:0-1000元,1000-3000元,3000元以上,这个字段可以用于手动选择区间,但我们更推荐通过 price 字段进行动态计算,这样更灵活。

重要提示

phpcms v9字段筛选教程
(图片来源网络,侵删)
  • 字段名:请务必记住你添加的字段名(如 brand, price, color),后续所有代码都会用到它们。
  • 内容录入:回到 -> 内容管理,为你的模型添加一些测试数据,确保这些字段都有值,方便后续测试。

第二步:修改列表页模板文件 (category.php)

这是实现筛选功能的核心步骤,我们需要在模板文件中添加筛选的 HTML 表单,并编写 PHP 逻辑来处理筛选条件。

  1. 找到模板文件:在你的模板目录下,找到对应分类的列表页模板文件,通常是 phpcms/templates/你的模板名/category.php
  2. 添加筛选表单:在列表页的适当位置(列表上方)添加筛选表单的 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 v9字段筛选教程
(图片来源网络,侵删)
  1. 打开程序文件:用代码编辑器打开 phpcms/modules/content/product.php
  2. 找到 category 方法:这个方法是用来处理列表页显示的。
  3. 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 来连接多个筛选条件。
  • 多选字段处理:多选字段的处理相对复杂,如果字段值是 黑色,白色 这样的字符串,需要用 LIKEOR 组合,如果设计的是关联表,则需要用 IN ('值1', '值2'),上面的例子是针对字符串存储的。
  • 价格区间处理:通过 explode 函数分割字符串,得到最小和最大价格,然后用 BETWEEN 语法。
  • 传递给模板$this->assign('filter', $filter); 这行代码至关重要,它让模板中的 {if $filter.brand == $v} 这样的判断得以生效。

第四步:处理分页问题

当用户进行筛选后,分页链接也必须带上筛选条件,否则翻页后筛选就会失效。

  1. 找到分页代码:在 category 方法中,找到生成分页链接的代码,通常是 pages() 函数。
  2. 修改分页参数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 的缓存,否则看不到效果。

  1. 登录后台
  2. 在顶部菜单栏找到 系统 -> 缓存管理
  3. 点击 更新全部缓存 或至少清除 模板缓存

访问你的列表页,应该可以看到筛选器已经可以正常工作了,点击不同的筛选条件,列表会实时更新,URL 也会相应变化。

总结与注意事项

  • 核心思想:URL 传递参数 -> PHP 接收并处理参数 -> 拼接 SQL 查询条件 -> 返回筛选后的结果。
  • 安全性第一:永远不要直接使用用户输入的数据来构建 SQL,必须使用 safe_replace()intval() 等函数进行过滤。
  • 灵活性:本教程提供了一个通用框架,你可以根据自己的字段类型(如下拉、联动、时间等)和业务需求,灵活调整 PHP 的处理逻辑。
  • 性能考虑:当筛选条件非常复杂,或者数据量巨大时,复杂的 SQL 查询(特别是 LIKEOR)可能会导致性能下降,此时可以考虑优化数据库索引或使用更高级的架构。
  • 调试:如果遇到问题,可以在 PHP 代码中 print_r($filter);echo $where; 来检查筛选条件和最终生成的 SQL 是否正确。

希望这份详尽的教程能帮助你成功实现 PHPCMS V9 的字段筛选功能!