コード例 #1
0
ファイル: DB.php プロジェクト: crunnells/shopp
 /**
  * Send a query to the database and retrieve the results
  *
  * Results can be formatted using 'auto', 'object' or 'array'.
  *
  *    auto - Automatically detects 'object' and 'array' results (default)
  *  object - Provides a single object as the result
  *   array - Provides a list of records/objects
  *
  * Processing results can also be automated by specifying a record processor
  * function. A custom callback function can be provided using standard PHP
  * callback notation, or there are builtin record processing methods
  * supported that can be specified as a string in the callback
  * parameter: 'auto', 'index' or 'col'
  *
  *  auto - Simply adds a record to the result set as a numerically indexed array of records
  *
  * index - Indexes record objects into an associative array using a given column name as the key
  *         sDB::query('query', 'format', 'index', 'column', (bool)collate)
  *         A column name is provided (4th argument) for the index key value
  *         A 'collate' boolean flag can also be provided (5th argument) to collect records with identical index column values into an array
  *
  *   col - Builds records as an associative array with a single column as the array value
  *         sDB::query('query', 'format', 'column', 'indexcolumn', (bool)collate)
  *         A column name is provided (4th argument) as the column for the array value
  *         An index column name can be provided (5th argument) to index records as an associative array using the index column value as the key
  *         A 'collate' boolean flag can also be provided (6th argument) to collect records with identical index column values into an array
  *
  * Collating records using the 'index' or 'col' record processors require an index column.
  * When a record's column value matches another record, the two records are collected into
  * a nested array. The results array will have a single entry where the key is the
  * index column's value and the value of the entry is an array of all the records that share
  * the index column value.
  *
  * @author Jonathan Davis
  * @since 1.0
  * @version 1.2
  *
  * @param string $query The SQL query to send
  * @param string $format (optional) Supports 'auto' (default), 'object', or 'array'
  * @return array|object The query results as an object or array of result rows
  **/
 public static function query($query, $format = 'auto', $callback = false)
 {
     $db = sDB::get();
     $args = func_get_args();
     $args = count($args) > 3 ? array_slice($args, 3) : array();
     if (SHOPP_QUERY_DEBUG) {
         $timer = microtime(true);
     }
     $result = $db->api->query($query);
     if (SHOPP_QUERY_DEBUG) {
         $db->queries[] = array($query, microtime(true) - $timer, sDB::caller());
     }
     // Error handling
     if ($db->dbh && ($error = $db->api->error())) {
         shopp_add_error(sprintf('Query failed: %s - DB Query: %s', $error, str_replace("\n", "", $query)), SHOPP_DB_ERR);
         return false;
     }
     /** Results handling **/
     // Handle special cases
     if (preg_match("/^\\s*(create|drop|insert|delete|update|replace) /i", $query)) {
         if (!$result) {
             return false;
         }
         $db->affected = $db->api->affected();
         if (preg_match("/^\\s*(insert|replace) /i", $query)) {
             $insert = $db->api->object($db->api->query("SELECT LAST_INSERT_ID() AS id"));
             if (!empty($insert->id)) {
                 return (int) $insert->id;
             }
         }
         if ($db->affected > 0) {
             return $db->affected;
         } else {
             return true;
         }
     } elseif (preg_match("/ SQL_CALC_FOUND_ROWS /i", $query)) {
         $rows = $db->api->object($db->api->query("SELECT FOUND_ROWS() AS found"));
     }
     // Default data processing
     if (is_bool($result)) {
         return (bool) $result;
     }
     // Setup record processing callback
     if (is_string($callback) && !function_exists($callback)) {
         $callback = array(__CLASS__, $callback);
     }
     // Failsafe if callback isn't valid
     if (!$callback || is_array($callback) && !method_exists($callback[0], $callback[1])) {
         $callback = array(__CLASS__, 'auto');
     }
     // Process each row through the record processing callback
     $records = array();
     while ($row = $db->api->object($result)) {
         call_user_func_array($callback, array_merge(array(&$records, &$row), $args));
     }
     // Free the results immediately to save memory
     $db->api->free();
     // Save the found count if it is present
     if (isset($rows->found)) {
         $db->found = (int) $rows->found;
     }
     // Handle result format post processing
     switch (strtolower($format)) {
         case 'object':
             return reset($records);
             break;
         case 'array':
             return $records;
             break;
         default:
             return count($records) == 1 ? reset($records) : $records;
             break;
     }
 }