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中路径问题的解决方案
Oct 09 PHP
PHP下通过系统信号量加锁方式获取递增序列ID
Sep 25 PHP
php中in_array函数用法分析
Nov 15 PHP
thinkphp文件引用与分支结构用法实例
Nov 26 PHP
smarty模板引擎从php中获取数据的方法
Jan 22 PHP
php生成酷炫的四个字符验证码
Apr 22 PHP
php 数组字符串搜索array_search技巧
Jul 05 PHP
Yii2中事务的使用实例代码详解
Sep 07 PHP
因str_replace导致的注入问题总结
Aug 08 PHP
关于laravel后台模板laravel-admin select框的使用详解
Oct 03 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
Oct 03 PHP
PHP日期和时间函数的使用示例详解
Aug 06 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
dedecms模板标签代码官方参考
2007/03/17 PHP
php 提速工具eAccelerator 配置参数详解
2010/05/16 PHP
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
PHP中把有符号整型转换为无符号整型方法
2015/05/27 PHP
Laravel5.1框架注册中间件的三种场景详解
2019/07/09 PHP
用js替换除数字与逗号以外的所有字符的代码
2014/06/07 Javascript
jQuery修改CSS伪元素属性的方法
2014/07/30 Javascript
基于AngularJS实现页面滚动到底自动加载数据的功能
2015/10/16 Javascript
JS获取当前脚本文件的绝对路径
2016/03/02 Javascript
js中 计算两个日期间的工作日的简单实例
2016/08/08 Javascript
深入nodejs中流(stream)的理解
2017/03/27 NodeJs
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
详解Vue2 SSR 缓存 Api 数据
2017/11/20 Javascript
layui实现文件或图片上传记录
2018/08/28 Javascript
深入理解NodeJS 多进程和集群
2018/10/17 NodeJs
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
vue开发移动端底部导航条功能
2020/04/08 Javascript
新手该如何学python怎么学好python?
2008/10/07 Python
RC4文件加密的python实现方法
2015/06/30 Python
Python手机号码归属地查询代码
2016/05/04 Python
python学习教程之使用py2exe打包
2017/09/24 Python
Python 利用内置set函数对字符串和列表进行去重的方法
2018/06/29 Python
windows安装TensorFlow和Keras遇到的问题及其解决方法
2019/07/10 Python
使用python实现哈希表、字典、集合操作
2019/12/22 Python
Python终端输出彩色字符方法详解
2020/02/11 Python
python入门之井字棋小游戏
2020/03/05 Python
opencv 图像轮廓的实现示例
2020/07/08 Python
Python 用__new__方法实现单例的操作
2020/12/11 Python
使用 css3 transform 属性来变换背景图的方法
2019/05/07 HTML / CSS
CSS3的常见transformation图形变化用法小结
2016/05/13 HTML / CSS
Argos官网:英国家喻户晓的百货零售连锁商
2017/04/03 全球购物
ASOS亚洲:ASOS Asia
2018/03/04 全球购物
.NET概念性的面试题
2012/02/29 面试题
《水上飞机》教学反思
2014/04/10 职场文书
写字楼租赁意向书
2014/07/30 职场文书