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简单对象与数组的转换函数代码(php多层数组和对象的转换)
May 18 PHP
php读取txt文件组成SQL并插入数据库的代码(原创自Zjmainstay)
Jul 31 PHP
一个PHP的远程图片抓取函数分享
Sep 25 PHP
php获取汉字首字母的函数
Nov 07 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
Apr 24 PHP
PHP生成等比缩略图类和自定义函数分享
Jun 25 PHP
Zend Framework页面缓存实例
Jun 25 PHP
PHP获取当前所在目录位置的方法
Nov 26 PHP
php检测mysql表是否存在的方法小结
Jul 20 PHP
PHPMAILER实现PHP发邮件功能
Apr 18 PHP
php实现二叉树中和为某一值的路径方法
Oct 14 PHP
php把文件设置为插件的技巧方法
Feb 03 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
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
php基于Snoopy解析网页html的方法
2015/07/09 PHP
CodeIgniter钩子用法实例详解
2016/01/20 PHP
PHP使用SWOOLE扩展实现定时同步 MySQL 数据
2017/04/09 PHP
php定期拉取数据对比方法实例
2019/09/22 PHP
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
15个值得开发人员关注的jQuery开发技巧和心得总结【经典收藏】
2016/05/25 Javascript
使用JavaScript获取Request中参数的值方法
2016/09/27 Javascript
JS中的作用域链
2017/03/01 Javascript
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
手把手教你搭建ES6的开发运行环境
2017/07/11 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
2017/07/27 Javascript
基于vue2.0实现仿百度前端分页效果附实现代码
2018/10/30 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
如何封装Vue Element的table表格组件
2021/02/06 Vue.js
Cython 三分钟入门教程
2009/09/17 Python
python回调函数的使用方法
2014/01/23 Python
python实现获取客户机上指定文件并传输到服务器的方法
2015/03/16 Python
Python中shutil模块的学习笔记教程
2017/04/04 Python
用Python shell简化开发
2018/08/08 Python
Python多线程同步---文件读写控制方法
2019/02/12 Python
python自动化测试之异常及日志操作实例分析
2019/11/09 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
Python SMTP发送电子邮件的示例
2020/09/23 Python
移动端rem布局的两种实现方法
2018/01/03 HTML / CSS
新锐科技Java程序员面试题
2016/07/25 面试题
工厂仓管员岗位职责
2014/01/01 职场文书
办公室经理岗位职责
2014/01/01 职场文书
乡村卫生服务一体化管理实施方案
2014/03/30 职场文书
领导干部群众路线剖析材料
2014/10/09 职场文书
文艺晚会开场白
2015/05/29 职场文书
任命书格式范文
2015/09/22 职场文书
Django显示可视化图表的实践
2021/05/10 Python
帮你提高开发效率的JavaScript20个技巧
2021/06/18 Javascript