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 相关文章推荐
基于文本的访客签到簿
Oct 09 PHP
PHP分页显示制作详细讲解
Dec 05 PHP
php5 mysql分页实例代码
Apr 10 PHP
php cc攻击代码与防范方法
Oct 18 PHP
php查询mssql出现乱码的解决方法
Dec 29 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
May 08 PHP
PHP中的魔术方法总结和使用实例
May 11 PHP
PHP获取当前相对于域名目录的方法
Jun 26 PHP
PHP简单遍历对象示例
Sep 28 PHP
Laravel5.5新特性之友好报错以及展示详解
Aug 13 PHP
PHP parse_ini_file函数的应用与扩展操作示例
Jan 07 PHP
Laravel手动返回错误码示例
Oct 22 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
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
一个简单的自动发送邮件系统(三)
2006/10/09 PHP
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
2007/08/26 PHP
php获取字符串前几位的实例(substr返回字符串的子串用法)
2017/03/08 PHP
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
Mootools 1.2教程 设置和获取样式表属性
2009/09/15 Javascript
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
jquery 表格的增行删行实现思路
2013/03/21 Javascript
jquery自定义类似$.ajax()的方法实现代码
2013/08/13 Javascript
jQuery中bind与live的用法及区别小结
2014/01/27 Javascript
js检验密码强度(低中高)附图
2014/06/05 Javascript
JQuery中serialize() 序列化
2015/03/13 Javascript
JS给Textarea文本框添加行号的方法
2015/08/20 Javascript
Vue利用路由钩子token过期后跳转到登录页的实例
2017/10/26 Javascript
Bootstrap框架建立树形菜单(Tree)的实例代码
2017/10/30 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
从零开始学习搭建React脚手架项目
2018/08/23 Javascript
[01:16:37]【全国守擂赛】第三周决赛 Dark Knight vs. 一个弱队
2020/05/04 DOTA
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
Python迭代器和生成器定义与用法示例
2018/02/10 Python
Python-OpenCV基本操作方法详解
2018/04/02 Python
Linux下远程连接Jupyter+pyspark部署教程
2019/06/21 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
Python Django 页面上展示固定的页码数实现代码
2019/08/21 Python
scikit-learn线性回归,多元回归,多项式回归的实现
2019/08/29 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
python多线程和多进程关系详解
2020/12/14 Python
美国最受欢迎的童装品牌之一:The Children’s Place
2016/07/23 全球购物
西班牙美妆电商:Perfume’s Club(有中文站)
2018/08/08 全球购物
Molly Bracken法国电子商店:法国女性时尚品牌
2019/07/24 全球购物
世界上最大的乐谱选择:Sheet Music Plus
2020/01/18 全球购物
经典c++面试题四
2015/05/14 面试题
家长会主持词开场白
2015/05/29 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书