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 相关文章推荐
用PHP函数解决SQL injection
Oct 09 PHP
DedeCMS dede_channeltype表字段注释
Apr 07 PHP
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
Oct 05 PHP
ThinkPHP3.1数据CURD操作快速入门
Jun 19 PHP
PHP+FastCGI+Nginx配置PHP运行环境
Aug 07 PHP
php输出全球各个时区列表的方法
Mar 31 PHP
php文件操作相关类实例
Jun 18 PHP
php根据一个给定范围和步进生成数组的方法
Jun 19 PHP
Yii视图CGridView实现操作按钮定义地址示例
Jul 14 PHP
PHP实现下载远程图片保存到本地的方法
Jun 19 PHP
PHP使用preg_split和explode分割textarea存放内容的方法分析
Jul 03 PHP
PHP 技巧 * SVG 保存为图片(分享图生成)
Apr 02 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
第二节 对象模型 [2]
2006/10/09 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
php+MySql实现登录系统与输出浏览者信息功能
2016/07/01 PHP
PHP记录和读取JSON格式日志文件
2016/07/07 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
利用JQuery+EasyDrag 实现弹出可拖动的Div,同时向Div传值,然后返回Div选中的值
2009/10/24 Javascript
滚动条变色 隐藏滚动条与双击网页自动滚屏显示代码
2009/12/28 Javascript
JS去掉第一个字符和最后一个字符的实现代码
2014/02/20 Javascript
js实现select组件的选择输入过滤代码
2014/10/14 Javascript
JQuery实现防止退格键返回的方法
2015/02/12 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
Bootstarp 基础教程之表单部分实例代码
2017/02/03 Javascript
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
vue实现的组件兄弟间通信功能示例
2018/12/04 Javascript
JavaScript中callee和caller的区别与用法实例分析
2019/06/28 Javascript
解决小程序无法触发SESSION问题
2020/02/03 Javascript
uniapp实现横向滚动选择日期
2020/10/21 Javascript
js实现移动端轮播图滑动切换
2020/12/21 Javascript
用python删除java文件头上版权信息的方法
2014/07/31 Python
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
python基础教程之Filter使用方法
2017/01/17 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
Python基于mysql实现学生管理系统
2019/02/21 Python
selenium如何定位span元素的实现
2021/01/13 Python
HTML5安全介绍之内容安全策略(CSP)简介
2012/07/10 HTML / CSS
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
文明青少年标兵事迹材料
2014/01/28 职场文书
3分钟英语演讲稿
2014/04/29 职场文书
3的组成教学反思
2014/04/30 职场文书
医院节能减排方案
2014/06/13 职场文书
2019年国庆祝福语(70句)
2019/09/19 职场文书
导游词之长城八达岭
2019/09/24 职场文书