thinkphp查询条件被叠加

在ThinkPHP中,如果一个类的方法被控制器多次调用,可能会遇到查询条件叠加的问题,导致后续查询无法得到预期结果。文章通过示例展示了这个问题,并提出了解决方案,即在每次查询前使用`removeOption(where)`重置条件,确保每个查询的条件独立,从而避免数据查询错误。这提醒开发者在使用框架时需要注意代码的执行逻辑和框架的特性。

有时候,用thinkphp写了一个类,用控制器调用多次,发现条件都叠加起来了

//逻辑类
class Module_article extends Model
{
    ...
    public fucntion article_info($condition=[]){
        $info=Db::name("module_article")->where($condition)->find();
        echo Db::name("module_article")->getLastSql().'<br>';
    }

}

//控制器类调用
class Article extends \think\Controller
{
        ...
        $info1 = $this->article_logic->article_info(['type','eq',1]);
        $info2= $this->article_logic->article_info(['type','eq',2]);
        $this->assign('info1',$info1);
        $this->assign('info2',$info2);

}

以上SQL输出:

select * from article where type =1;

select * from article where type =1 && type=2;

第二个显然不是我们想要的,永远查不到数据。

我们可以通过removeOption('where'),将条件重置为空,逻辑类变成:

//逻辑类
class Module_article extends Model
{
    ...
    public fucntion article_info($condition=[]){
        $info=Db::name("module_article")->removeOption('where')->where($condition)->find();
        echo Db::name("module_article")->getLastSql().'<br>';
    }

}

以上SQL输出:

select * from article where type =1;

select * from article where type=2;

完美解决thinkphp条件叠加的问题,防止查不到数据。

其实TP文档手册已经说了,没有仔细看的就会踩到这个坑。

 

启动代码: <?php // 设置工作目录到项目根目录 chdir(dirname(__DIR__)); // 定义必要的常量 if (!defined('DS')) define('DS', DIRECTORY_SEPARATOR); if (!defined('ROOT_PATH')) define('ROOT_PATH', dirname(__DIR__) . DS); if (!defined('APP_PATH')) define('APP_PATH', ROOT_PATH . 'application' . DS); if (!defined('RUNTIME_PATH')) define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS); // 防止重复加载 Composer 自动加载文件 if (!class_exists('Composer\Autoload\ClassLoader', false)) { require ROOT_PATH . 'vendor/autoload.php'; } // 加载框架基础文件 require ROOT_PATH . 'thinkphp/base.php'; // 手动加载应用函数文件 if (file_exists(APP_PATH . 'common.php')) { require_once APP_PATH . 'common.php'; } // 设置错误报告级别 error_reporting(E_ALL); ini_set('display_errors', '1'); // 注册自动加载 \think\Loader::register(); // 手动加载采集服务 require_once APP_PATH . 'caiji/CaijiScheduler.php'; require_once APP_PATH . 'caiji/CaijiWorker.php'; try { // 记录启动日志 file_put_contents(RUNTIME_PATH . 'caiji_start.log', date('[Y-m-d H:i:s]') . " 采集服务启动\n", FILE_APPEND); // 创建锁文件 $lockFile = RUNTIME_PATH . 'caiji.lock'; if (file_exists($lockFile)) { exit("采集进程已在运行中\n"); } file_put_contents($lockFile, getmypid()); // 注册关闭函数 register_shutdown_function(function() use ($lockFile) { if (file_exists($lockFile)) { unlink($lockFile); } }); // 启动调度器 $scheduler = new app\caiji\CaijiScheduler(); $scheduler->start(); // 启动Worker $worker = new app\caiji\CaijiWorker(); $worker->start(); } catch (\Throwable $e) { $error = date('[Y-m-d H:i:s]') . " 错误: " . $e->getMessage() . "\n"; $error .= "追踪: " . $e->getTraceAsString() . "\n"; file_put_contents(RUNTIME_PATH . 'caiji_error.log', $error, FILE_APPEND); exit(1); }
05-30
### ThinkPHP 查询构建器条件语法示例 在 ThinkPHP 中,`where` 方法是最常用于查询条件设置的方法之一。它支持多种型的条件表达式,包括字符串条件、数组条件以及 `exp` 表达式等。 #### 字符串条件 当使用字符串作为查询条件时,可以直接传递 SQL 片段到 `where` 方法中。例如: ```php $User = M('User'); // 实例化 User 模型 $result = $User->where('status=1 AND id>0')->select(); ``` 此代码表示查询状态为 1 并且 ID 大于 0 的记录[^1]。 --- #### 数组条件 除了字符串外,还可以通过数组来定义更复杂的查询条件。以下是常见的数组条件形式及其含义: ##### 基本键值对 ```php $map['name'] = 'thinkphp'; $map['status'] = 1; $result = $User->where($map)->select(); ``` 这相当于执行如下 SQL: ```sql SELECT * FROM user WHERE name='thinkphp' AND status=1; ``` ##### 使用表达式 可以通过指定特殊的关键字(如 `_string`, `_query`, 或者自定义运算符)实现更多功能。例如: ```php $map['age'] = array('egt', 20); // egt 表示大于等于 (>=) $result = $User->where($map)->select(); ``` 该语句会生成以下 SQL: ```sql SELECT * FROM user WHERE age >= 20; ``` 完整的 TP 运算符对照表可参考文档说明[^2]。 --- #### 综合表达式 (`exp`) 对于一些无法简单用键值对描述的复杂场景,可以借助 `exp` 关键字。`exp` 可以嵌入任意合法的 SQL 语法片段,比如调用数据库内置函数或者处理字段间的关系计算。 下面是一个典型的例子——更新某篇文章的点击次数并保存更改: ```php $Dao = M("Article"); $data['id'] = 10; $data['counter'] = array('exp', 'counter+1'); $Dao->save($data); ``` 这段代码的作用是对 ID 为 10 的文章增加一次访问计数[^5]。 如果需要在查询中应用似的逻辑,则可以用作过滤条件的一部分: ```php $condition['create_time'] = array('exp', '> NOW() - INTERVAL 7 DAY'); $list = $Model->where($condition)->select(); ``` 这里实现了筛选最近七天创建的文章列表的功能。 --- #### 高级特性:组合查询 ThinkPHP 支持多层嵌套和逻辑运算符连接多个子条件。例如: ```php $map['_logic'] = 'OR'; // 设置顶层逻辑关系为 OR $map[] = array('title', 'like', '%关键词%'); $map[] = array('content', 'like', '%关键词%'); $result = $Model->where($map)->select(); ``` 上述代码将查找标题或内容中含有特定关键字的所有记录。 --- ### 总结 以上展示了如何利用 ThinkPHP 提供的强大查询机制快速构建灵活高效的数据库交互接口。无论是简单的相等判断还是涉及日期范围、聚合统计等功能的需求都能轻松满足。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值