PHPCMS V9 自定义证书查询模块(Ajax+防刷+倒计时)

一、需求背景

最近在做一个项目,需要为网站增加一个证书查询功能。用户输入证书编号,页面无刷新地显示证书详情。数据存储在PHPCMS的 v9_news_data 自定义字段中。看似简单的需求,实际开发中却踩了不少坑,特此记录。

二、初探:遭遇"方法不存在"的连环打击

按照常规思路,我创建了 phpcms/modules/certificate/certificate.php 控制器,并加载了 content_model 模型。

第一次尝试:get_one_info()

我尝试调用一个自以为存在的方法 get_one_info(),结果系统直接报错:
Fatal error: Call to undefined method content_model::get_one_info()

第二次尝试:fetch_next()

查阅资料后,我换用 fetch_next() 方法,然而错误依旧:
Fatal error: Call to undefined method content_model::fetch_next()

第三次尝试:fetch_assoc()

我几乎尝试了所有能想到的模型方法,但PHPCMS的版本差异让我屡屡碰壁:
Fatal error: Call to undefined method content_model::fetch_assoc()

接二连三的失败让我一度怀疑人生,看来这个版本的 content_model 封装非常精简,不能想当然地使用方法。

三、破局:回归PHPCMS官方标准写法

在多次失败后,我决定不再"野路子",而是仔细研究PHPCMS官方模块(如 content/index.php)的写法。在 show() 方法中,我发现了处理主表和附表数据的标准流程:

复制代码
> // 1. 查询主表 (v9_news)
> $r =$this->db->get_one(array('id'=>$id));
> // 2. 切换表名,查询附表 (v9_news_data)
> $this->db->table_name =$tablename.'_data';
> $r2 =$this->db->get_one(array('id'=>$id));
> // 3. 合并数据
> $rs =$r2 ? array_merge($r,$r2) : $r;
> 

茅塞顿开! 原来PHPCMS是通过动态修改 $this->db->table_name 来操作不同数据表的。遵循这个思路,我重写了查询逻辑,先根据 cert_number 在附表中查到文章 id,再用 id 去主表查询其他信息,最后合并。这一次,代码完美运行!

最终核心代码如下:

php 复制代码
public function search() {
        // ========== 查询频率限制 (已修改) ==========
        session_start();
        $limit_time = 5; // 设置限制时间,单位:秒
        $last_query_time = isset($_SESSION['last_cert_query_time']) ? $_SESSION['last_cert_query_time'] : 0;
        $remaining_seconds =$limit_time - (time() - $last_query_time);
        if ($remaining_seconds > 0) {
            // 返回状态码2,表示需要倒计时,并附带剩余秒数
            echo json_encode(array('status' => 2, 'msg' => "查询过于频繁,请稍后再试。", 'remaining_seconds' => $remaining_seconds));
            exit;
        }
        // ========== 新增代码结束 ==========
        $cert_number = isset($_REQUEST['cert_number']) ? safe_replace($_REQUEST['cert_number']) : '';
        
        if(empty($cert_number)) {
            echo json_encode(array('status' => 0, 'msg' => '证书编号不能为空'));
            exit;
        }
        // 1. 获取模型信息,以确定表名
        // 假设你的证书内容模型ID是1,如果不是,请修改
        $modelid = 1; 
        $MODEL = getcache('model','commons');
        $tablename = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
        // 2. 先在附表 (v9_news_data) 中查询证书编号,获取文章ID
        $this->db->table_name = $tablename.'_data';
        $data_result = $this->db->get_one(array('cert_number' => $cert_number), 'id,cert_number');
        if(!$data_result) {
            // 附表中没查到,直接返回无结果
            echo json_encode(array('status' => 0, 'msg' => '未查询到相关证书信息,请核对编号是否正确!'));
            exit;
        }
        $id = $data_result['id'];
        // 3. 根据ID查询主表 (v9_news) 获取其他信息
        $this->db->table_name = $tablename;
        $main_result = $this->db->get_one(array('id' => $id), 'title, inputtime, status');

        if(!$main_result) {
            // 主表中没查到(理论上不应该发生)
            echo json_encode(array('status' => 0, 'msg' => '数据异常,请联系管理员!'));
            exit;
        }
        // 4. 合并数据
        $rs = array_merge($main_result, $data_result);
        // 5. 格式化并返回JSON
        $result_array = array(
            'name' => $rs['title'],
            'cert_number' => $rs['cert_number'],
            'issue_date' => date('Y-m-d', $rs['inputtime']),
            'status' => $rs['status'] == 99 ? '有效' : '无效'
        );
        // ========== 新增代码:更新查询时间 ==========
        // 只有在成功查询并准备返回结果时,才更新时间戳
        $_SESSION['last_cert_query_time'] = time();
        echo json_encode(array('status' => 1, 'msg' => '查询成功', 'data' => $result_array));
    }

四、进阶:增加查询频率限制与倒计时

功能实现后,考虑到安全性,需要防止用户恶意频繁查询。我利用PHP的 SESSION 实现了一个简单的频率限制。

后端逻辑:

  1. 开启 session_start()
  2. 记录用户上次查询的时间戳。
  3. 如果当前时间与上次查询时间差小于设定值(如5秒),则返回一个特殊的状态码和剩余秒数,而不是直接报错。

前端交互:

  1. 前端Ajax收到特殊状态码后,获取剩余秒数。
  2. 禁用查询按钮,并启动一个 setInterval 倒计时。
  3. 按钮文字变为"请等待 (Xs)"。
  4. 倒计时结束后,恢复按钮状态。

这个小小的改进,让用户体验提升了一个档次。

五、总结

这次开发过程虽然曲折,但收获颇丰:

  1. 尊重官方文档:遇到框架相关的问题,回归官方标准和范例往往是最快的解决路径。
  2. 底层思维:当上层封装无法使用时,理解其底层数据库操作原理(如主附表关系)至关重要。
  3. 用户体验:一个优秀的功能,不仅在于实现,更在于细节的打磨,如防刷和倒计时。

希望这篇详细的踩坑记录能帮助到正在使用PHPCMS V9的你。如果觉得有用,请点个赞和收藏吧!

转载请注明出处,谢谢!

项目下载地址:https://download.csdn.net/download/liufucai132/92154547

相关推荐
.生产的驴1 天前
React useEffect组件渲染执行操作 组件生命周期 监视器 副作用
前端·css·react.js·ajax·前端框架·jquery·html5
小白学大数据3 天前
Python爬虫常见陷阱:Ajax动态生成内容的URL去重与数据拼接
爬虫·python·ajax
一壶浊酒..4 天前
ajax局部更新
前端·ajax·okhttp
一壶浊酒..5 天前
什么是AJAX
前端·javascript·ajax
加洛斯7 天前
AJAX 知识篇(2):Axios的核心配置
前端·javascript·ajax
洛克大航海7 天前
Ajax基本使用
java·javascript·ajax·okhttp
星秀日8 天前
JavaWeb--Ajax
前端·javascript·ajax
小小星尘s8 天前
Python编程实战从基础到高级的完整指南
ajax
我是大头鸟11 天前
XMLHttpRequest 异步请求servlet 上传文件并且带有参数
ajax·servlet