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:
The code is as follows: |
Copy code |
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:
The code is as follows: |
Copy code |
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.