Thinkphp使用mongodb数据库实现多条件查询方法


Posted in PHP onJune 26, 2014

有个项目用了mongodb数据库,查询条件有and也有or,按Thinkphp官方手册,使用复合查询(_complex),getLastSql输出查询语句,发现查询条件是空的.用字符串模式查询(_string),请求字符串查询(_query)无法满足需求.估计用mongodb的用户不多,thinkphp官方对这方面支持也不够.打开thinkphp的mongodb驱动,Thinkphp/Extend/Driver/Db/DbMongo.class.php,找到protected function parseThinkWhere($key,$val)方法,可以发现,switch里没有_complex,也就是说,Thinkphp使用mongodb时,根本不支持复合查询.加上:

case '_complex'://复合查询

             $arr   = array();

             foreach ($val as $nkey=>$nval){

              if( strpos($nkey,'_')!=0)

              {

               $parseArr=$this->parseWhereItem($nkey,$nval);

               //转换成对象

               $obj=new stdClass();

               foreach ($parseArr as $pkey=>$pval)

               {

                $obj->$pkey=$pval;

               }

               array_push($arr, $obj);

              }

             }

             if(isset($val['_logic']) && strtolower($val['_logic']) == 'or' ) {

              unset($val['_logic']);

              $query['$or']   =  $arr;

             }

             break;

这里之所以要转换成对象,是因为使用thinkphp使用json_encode函数生成查询语句,但是如果数组元素带key,json_encode函数会把数组转换成对象的形式,mongodb不能识别.因为目前只用到or,所以,代码只对or作了处理.
另外,发现个BUG(不知道算不算),在parseWhere方法中:

foreach ($where as $key=>$val){

            if('_id' != $key && 0===strpos($key,'_')) {

                // 解析特殊条件表达式

                //原 $query=$this->parseThinkWhere($key,$val);

                $query   = array_merge($query,$this->parseThinkWhere($key,$val));

            }else{

                // 查询字段的安全过滤

                if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){

                    throw_exception(L('_ERROR_QUERY_').':'.$key);

                }

                $key = trim($key);

                if(strpos($key,'|')) {

                    $array   =  explode('|',$key);

                    $str   = array();

                    foreach ($array as $k){

                        $str[]   = $this->parseWhereItem($k,$val);

                    }

                    $query['$or'] =    $str;

                }elseif(strpos($key,'&')){

                    $array   =  explode('&',$key);

                    $str   = array();

                    foreach ($array as $k){

                        $str[]   = $this->parseWhereItem($k,$val);

                    }

                    $query   = array_merge($query,$str);

                }else{

                    $str   = $this->parseWhereItem($key,$val);

                    $query   = array_merge($query,$str);

                }

            }

        }

解析特殊条件表达式时,源代码里是$query=$this->parseThinkWhere($key,$val);当特殊表达式在where数组里不是第一个元素时,就出错了,else里的代码得到的$query数组,都没了.

PHP 相关文章推荐
在PHP3中实现SESSION的功能(三)
Oct 09 PHP
PHP的范围解析操作符(::)的含义分析说明
Jul 03 PHP
一个PHP的QRcode类与大家分享
Nov 13 PHP
数组与类使用PHP的可变变量名需要的注意的问题
Jun 20 PHP
php与java通过socket通信的实现代码
Oct 21 PHP
百度地图API应用之获取用户的具体位置
Jun 10 PHP
PHP生成二维码的两个方法和实例
Jul 01 PHP
windows的文件系统机制引发的PHP路径爆破问题分析
Jul 28 PHP
thinkphp 手机号和用户名同时登录
Jan 20 PHP
php redis实现对200w用户的即时推送
Mar 04 PHP
workerman结合laravel开发在线聊天应用的示例代码
Oct 30 PHP
PHP htmlspecialchars_decode()函数用法讲解
Mar 01 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 #PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 #PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
Jun 25 #PHP
ThinkPHP多表联合查询的常用方法
Mar 24 #PHP
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
Jun 25 #PHP
ThinkPHP查询中的魔术方法简述
Jun 25 #PHP
Thinkphp实现MySQL读写分离操作示例
Jun 25 #PHP
You might like
制作美丽的拉花
2021/03/03 冲泡冲煮
一步一步学习PHP(6) 面向对象
2010/02/16 PHP
PHP的加密方式及原理
2012/06/14 PHP
php变量范围介绍
2012/10/15 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
php使用正则验证中文
2016/04/06 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
基于PHP实现的多元线性回归模拟曲线算法
2018/01/30 PHP
对laravel in 查询的使用方法详解
2019/10/09 PHP
Jquery事件的连接使用示例
2013/06/18 Javascript
Js日期选择器并自动加入到输入框中示例代码
2013/08/02 Javascript
基于jquery animate操作css样式属性小结
2015/11/27 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
jQuery移动端图片上传组件
2016/06/12 Javascript
Bootstrap实现登录校验表单(带验证码)
2016/06/23 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
实战node静态文件服务器的示例代码
2018/03/08 Javascript
利用npm 安装删除模块的方法
2018/05/15 Javascript
JavaScript获取某一天所在的星期
2019/09/05 Javascript
Vue路由的模块自动化与统一加载实现
2020/06/05 Javascript
js实现可爱的气泡特效
2020/09/05 Javascript
json.stringify()与json.parse()的区别以及用处
2021/01/25 Javascript
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
Python字符串、元组、列表、字典互相转换的方法
2016/01/23 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
2018/06/13 Python
pytorch中tensor张量数据类型的转化方式
2019/12/31 Python
tensorflow 限制显存大小的实现
2020/02/03 Python
Django在Model保存前记录日志实例
2020/05/14 Python
Python使用cn2an实现中文数字与阿拉伯数字的相互转换
2021/03/02 Python
新春文艺演出主持词
2014/03/27 职场文书
清明节网上祭英烈活动总结
2014/04/30 职场文书
离职保密承诺书
2014/05/28 职场文书
人事主管岗位职责
2015/02/04 职场文书
文言文辞职信
2015/02/28 职场文书
如何撰写创业策划书
2019/06/27 职场文书
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题