Thinkphp Mongod 出现BSON field 'count.query' is the wrong type 'array', expected type 'object'

首发 PHP社区
QRI的头像

QRI

这人还不错哦!

新服务器在使用高版本的PHP和mongod扩展的时候,配合thinkphp开发网站应用的时候,需要做数据分页或者查询数据总数的时候需要使用count()方法,出现了报错:

BSON field 'count.query' is the wrong type 'array', expected type 'object'

故障原因在think-mongo版本,vendor/topthink/think-mongo/src/Builder.php文件中,parseWhere方法在做过滤条件初始化的时候,没有考虑周全,将数据类型定义为了数组。这里在返回的时候做一个判断,如果$filter为空,就重新定义为stdClass对象。可以参考以下代码

public function parseWhere( Query $query , $where ) {
        if ( empty( $where ) ) {
            $where=[];
        }

        $filter=[];
        foreach ( $where as $logic=>$val ) {
            foreach ( $val as $field=>$value ) {
                if ( is_array( $value ) ) {
                    if ( key( $value ) !== 0 ) {
                        throw new Exception( 'where express error:'.var_export( $value , true ) );
                    }
                    $field=array_shift( $value );
                } elseif ( !($value instanceof \Closure) ) {
                    throw new Exception( 'where express error:'.var_export( $value , true ) );
                }

                if ( $value instanceof \Closure ) {
                    // 使用闭包查询
                    $query=new Query( $this->connection );
                    call_user_func_array( $value , [ & $query ] );
                    $filter[ $logic ][]=$this->parseWhere( $query , $query->getOptions( 'where' ) );
                } else {
                    if ( strpos( $field , '|' ) ) {
                        // 不同字段使用相同查询条件(OR)
                        $array=explode( '|' , $field );
                        foreach ( $array as $k ) {
                            $filter[ '$or' ][]=$this->parseWhereItem( $query , $k , $value );
                        }
                    } elseif ( strpos( $field , '&' ) ) {
                        // 不同字段使用相同查询条件(AND)
                        $array=explode( '&' , $field );
                        foreach ( $array as $k ) {
                            $filter[ '$and' ][]=$this->parseWhereItem( $query , $k , $value );
                        }
                    } else {
                        // 对字段使用表达式查询
                        $field=is_string( $field )?$field : '';
                        $filter[ $logic ][]=$this->parseWhereItem( $query , $field , $value );
                    }
                }
            }
        }

        $options=$query->getOptions();
        if ( !empty( $options[ 'soft_delete' ] ) ) {
            // 附加软删除条件
            list( $field , $condition )=$options[ 'soft_delete' ];
            $filter[ '$and' ][]=$this->parseWhereItem( $query , $field , $condition );
        }
        if (empty($filter)){ // 返回空对象
            return new stdClass();
        }
        return $filter;
    }
发布于 2019-12-01 00:55:05
阅读:4 0 2019-12-01
文章被以下专栏收录
PHP社区

PHP技术分享,干货分享

目录