One project uses the mongodb database and the query conditions are and or. According to the official Thinkphp manual, use composite query (_ complex) and getLastSql to output query statements, the query condition is null. query in string mode (_ string). The request string query (_ query) cannot meet the requirements. it is estimated that there are not many users using mongodb, and thinkphp does not officially support this. enable thinkphp mongodb Driver, Thinkphp/Extend/Driver/Db/DbMongo. class. php: Find the protected function parseThinkWhere ($ key, $ val) method. We can find that _ complex is not found in the switch. That is to say, when Thinkphp uses mongodb, composite queries are not supported at all. add:
Copy codeThe Code is as follows:
Case '_ complex': // composite Query
$ Arr = array ();
Foreach ($ val as $ nkey => $ nval ){
If (strpos ($ nkey ,'_')! = 0)
{
$ ParseArr = $ this-> parseWhereItem ($ nkey, $ nval );
// Convert to an object
$ 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;
Here we want to convert it to an object because thinkphp uses the json_encode function to generate a query statement. However, if the array element contains a key, the json_encode function will convert the array to an object, which mongodb cannot recognize. because only or is used currently, the Code only processes or.
In addition, a BUG (not sure if it is not counted) is found in the parseWhere method:
Copy codeThe Code is as follows:
Foreach ($ where as $ key => $ val ){
If ('_ id '! = $ Key & 0 === strpos ($ key ,'_')){
// Parse Special Condition expressions
// Original $ query = $ this-> parseThinkWhere ($ key, $ val );
$ Query = array_merge ($ query, $ this-> parseThinkWhere ($ key, $ val ));
} Else {
// Security filtering of query Fields
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 );
}
}
}
When a special conditional expression is parsed, $ query = $ this-> parseThinkWhere ($ key, $ val) is in the source code. When a special expression is not the first element in the where array, an error occurs. The $ query array obtained by the code in else is missing.