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 相关文章推荐
对javascript和select部件的结合运用
Oct 09 PHP
php扩展ZF――Validate扩展
Jan 10 PHP
如何用C语言编写PHP扩展的详解
Jun 13 PHP
PHP中的reflection反射机制测试例子
Aug 05 PHP
PDO防注入原理分析以及注意事项
Feb 25 PHP
php简单日历函数
Oct 28 PHP
PHP使用curl制作简易百度搜索
Nov 03 PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
Apr 01 PHP
php实现的双色球算法示例
Jun 20 PHP
利用 fsockopen() 函数开放端口扫描器的实例
Aug 19 PHP
微信公众号实现扫码获取微信用户信息(网页授权)
Apr 09 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
Dec 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
php的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
PHP实现的敏感词过滤方法示例
2019/03/06 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
div失去焦点事件实现思路
2014/04/22 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
jquery中实现时间戳与日期相互转换
2016/04/12 Javascript
jQuery实现的跨容器无缝拖动效果代码
2016/06/21 Javascript
window.open不被拦截的简单实现代码(推荐)
2016/08/04 Javascript
探究Vue.js 2.0新增的虚拟DOM
2016/10/20 Javascript
Bootstrap基本组件学习笔记之进度条(15)
2016/12/08 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
Vue 中使用 CSS Modules优雅方法
2018/04/09 Javascript
Nodejs异步回调之异常处理实例分析
2018/06/22 NodeJs
利用Node.js如何实现文件循环覆写
2019/04/05 Javascript
eslint 的三大通用规则详解
2019/05/16 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
jQuery实现简单飞机大战
2020/07/05 jQuery
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
2020/10/09 jQuery
解决antd Form 表单校验方法无响应的问题
2020/10/27 Javascript
vue监听滚动事件的方法
2020/12/21 Vue.js
[01:59]翻天覆地,因你而变,7.20版本地图更新速览
2018/11/24 DOTA
python连接数据库的方法
2017/10/19 Python
python ---lambda匿名函数介绍
2019/03/13 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
python 发送邮件的四种方法汇总
2020/12/02 Python
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
英国婴儿及儿童产品商店:TigerParrot
2019/03/04 全球购物
俄语专业毕业生推荐信
2013/10/28 职场文书
初中信息技术教学计划
2015/01/22 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
Python机器学习实战之k-近邻算法的实现
2021/11/27 Python