[ Index ] |
|
Code source de Drupal 5.3 |
1 <?php 2 // $Id: database.mysqli.inc,v 1.32 2006/12/27 22:50:09 dries Exp $ 3 4 /** 5 * @file 6 * Database interface code for MySQL database servers using the mysqli client libraries. mysqli is included in PHP 5 by default and allows developers to use the advanced features of MySQL 4.1.x, 5.0.x and beyond. 7 */ 8 9 /* Maintainers of this file should consult 10 * http://www.php.net/manual/en/ref.mysqli.php 11 */ 12 13 /** 14 * @ingroup database 15 * @{ 16 */ 17 18 /** 19 * Report database status. 20 */ 21 function db_status_report($phase) { 22 $t = get_t(); 23 24 $version = db_version(); 25 26 $form['mysql'] = array( 27 'title' => $t('MySQL database'), 28 'value' => ($phase == 'runtime') ? l($version, 'admin/logs/status/sql') : $version, 29 ); 30 31 if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) { 32 $form['mysql']['severity'] = REQUIREMENT_ERROR; 33 $form['mysql']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL)); 34 } 35 36 return $form; 37 } 38 39 /** 40 * Returns the version of the database server currently in use. 41 * 42 * @return Database server version 43 */ 44 function db_version() { 45 global $active_db; 46 list($version) = explode('-', mysqli_get_server_info($active_db)); 47 return $version; 48 } 49 50 /** 51 * Initialise a database connection. 52 * 53 * Note that mysqli does not support persistent connections. 54 */ 55 function db_connect($url) { 56 // Check if MySQLi support is present in PHP 57 if (!function_exists('mysqli_init') && !extension_loaded('mysqli')) { 58 drupal_maintenance_theme(); 59 drupal_set_title('PHP MySQLi support not enabled'); 60 print theme('maintenance_page', '<p>We were unable to use the MySQLi database because the MySQLi extension for PHP is not installed. Check your <code>PHP.ini</code> to see how you can enable it.</p> 61 <p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>'); 62 exit; 63 } 64 65 $url = parse_url($url); 66 67 // Decode url-encoded information in the db connection string 68 $url['user'] = urldecode($url['user']); 69 // Test if database url has a password. 70 if(isset($url['pass'])) { 71 $url['pass'] = urldecode($url['pass']); 72 } 73 else { 74 $url['pass'] = ''; 75 } 76 $url['host'] = urldecode($url['host']); 77 $url['path'] = urldecode($url['path']); 78 79 $connection = mysqli_init(); 80 @mysqli_real_connect($connection, $url['host'], $url['user'], $url['pass'], substr($url['path'], 1), $url['port'], NULL, MYSQLI_CLIENT_FOUND_ROWS); 81 82 // Find all database connection errors and error 1045 for access denied for user account 83 if (mysqli_connect_errno() >= 2000 || mysqli_connect_errno() == 1045) { 84 drupal_maintenance_theme(); 85 drupal_set_header('HTTP/1.1 503 Service Unavailable'); 86 drupal_set_title('Unable to connect to database server'); 87 print theme('maintenance_page', '<p>If you still have to install Drupal, proceed to the <a href="'. base_path() .'install.php">installation page</a>.</p> 88 <p>If you have already finished installed Drupal, this either means that the username and password information in your <code>settings.php</code> file is incorrect or that we can\'t connect to the MySQL database server. This could mean your hosting provider\'s database server is down.</p> 89 <p>The MySQL error was: '. theme('placeholder', mysqli_error($connection)) .'.</p> 90 <p>Currently, the username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p> 91 <ul> 92 <li>Are you sure you have the correct username and password?</li> 93 <li>Are you sure that you have typed the correct hostname?</li> 94 <li>Are you sure that the database server is running?</li> 95 <li>Are you sure that the mysqli libraries are compiled in your PHP installation? Try using the mysql library instead by editing your <code>settings.php</code> configuration file in Drupal.</li> 96 </ul> 97 <p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>'); 98 exit; 99 } 100 else if (mysqli_connect_errno() > 0) { 101 drupal_maintenance_theme(); 102 drupal_set_title('Unable to select database'); 103 print theme('maintenance_page', '<p>We were able to connect to the MySQL database server (which means your username and password are okay) but not able to select the database.</p> 104 <p>The MySQL error was: '. theme('placeholder', mysqli_error($connection)) .'.</p> 105 <p>Currently, the database is '. theme('placeholder', substr($url['path'], 1)) .'. The username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p> 106 <ul> 107 <li>Are you sure you have the correct database name?</li> 108 <li>Are you sure the database exists?</li> 109 <li>Are you sure the username has permission to access the database?</li> 110 </ul> 111 <p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>'); 112 exit; 113 } 114 115 /* Force UTF-8 */ 116 mysqli_query($connection, 'SET NAMES "utf8"'); 117 118 return $connection; 119 } 120 121 /** 122 * Helper function for db_query(). 123 */ 124 function _db_query($query, $debug = 0) { 125 global $active_db, $queries; 126 127 if (variable_get('dev_query', 0)) { 128 list($usec, $sec) = explode(' ', microtime()); 129 $timer = (float)$usec + (float)$sec; 130 } 131 132 $result = mysqli_query($active_db, $query); 133 134 if (variable_get('dev_query', 0)) { 135 $bt = debug_backtrace(); 136 $query = $bt[2]['function'] . "\n" . $query; 137 list($usec, $sec) = explode(' ', microtime()); 138 $stop = (float)$usec + (float)$sec; 139 $diff = $stop - $timer; 140 $queries[] = array($query, $diff); 141 } 142 143 if ($debug) { 144 print '<p>query: '. $query .'<br />error:'. mysqli_error($active_db) .'</p>'; 145 } 146 147 if (!mysqli_errno($active_db)) { 148 return $result; 149 } 150 else { 151 trigger_error(check_plain(mysqli_error($active_db) ."\nquery: ". $query), E_USER_WARNING); 152 return FALSE; 153 } 154 } 155 156 /** 157 * Fetch one result row from the previous query as an object. 158 * 159 * @param $result 160 * A database query result resource, as returned from db_query(). 161 * @return 162 * An object representing the next row of the result. The attributes of this 163 * object are the table fields selected by the query. 164 */ 165 function db_fetch_object($result) { 166 if ($result) { 167 return mysqli_fetch_object($result); 168 } 169 } 170 171 /** 172 * Fetch one result row from the previous query as an array. 173 * 174 * @param $result 175 * A database query result resource, as returned from db_query(). 176 * @return 177 * An associative array representing the next row of the result. The keys of 178 * this object are the names of the table fields selected by the query, and 179 * the values are the field values for this result row. 180 */ 181 function db_fetch_array($result) { 182 if ($result) { 183 return mysqli_fetch_array($result, MYSQLI_ASSOC); 184 } 185 } 186 187 /** 188 * Determine how many result rows were found by the preceding query. 189 * 190 * @param $result 191 * A database query result resource, as returned from db_query(). 192 * @return 193 * The number of result rows. 194 */ 195 function db_num_rows($result) { 196 if ($result) { 197 return mysqli_num_rows($result); 198 } 199 } 200 201 /** 202 * Return an individual result field from the previous query. 203 * 204 * Only use this function if exactly one field is being selected; otherwise, 205 * use db_fetch_object() or db_fetch_array(). 206 * 207 * @param $result 208 * A database query result resource, as returned from db_query(). 209 * @param $row 210 * The index of the row whose result is needed. 211 * @return 212 * The resulting field or FALSE. 213 */ 214 function db_result($result, $row = 0) { 215 if ($result && mysqli_num_rows($result) > $row) { 216 $array = mysqli_fetch_array($result, MYSQLI_NUM); 217 return $array[0]; 218 } 219 return FALSE; 220 } 221 222 /** 223 * Determine whether the previous query caused an error. 224 */ 225 function db_error() { 226 global $active_db; 227 return mysqli_errno($active_db); 228 } 229 230 /** 231 * Return a new unique ID in the given sequence. 232 * 233 * For compatibility reasons, Drupal does not use auto-numbered fields in its 234 * database tables. Instead, this function is used to return a new unique ID 235 * of the type requested. If necessary, a new sequence with the given name 236 * will be created. 237 * 238 * Note that the table name should be in curly brackets to preserve compatibility 239 * with table prefixes. For example, db_next_id('{node}_nid'); 240 */ 241 function db_next_id($name) { 242 $name = db_prefix_tables($name); 243 db_query('LOCK TABLES {sequences} WRITE'); 244 $id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) + 1; 245 db_query("REPLACE INTO {sequences} VALUES ('%s', %d)", $name, $id); 246 db_query('UNLOCK TABLES'); 247 248 return $id; 249 } 250 251 /** 252 * Determine the number of rows changed by the preceding query. 253 */ 254 function db_affected_rows() { 255 global $active_db; /* mysqli connection resource */ 256 return mysqli_affected_rows($active_db); 257 } 258 259 /** 260 * Runs a limited-range query in the active database. 261 * 262 * Use this as a substitute for db_query() when a subset of the query is to be 263 * returned. 264 * User-supplied arguments to the query should be passed in as separate parameters 265 * so that they can be properly escaped to avoid SQL injection attacks. 266 * 267 * @param $query 268 * A string containing an SQL query. 269 * @param ... 270 * A variable number of arguments which are substituted into the query 271 * using printf() syntax. The query arguments can be enclosed in one 272 * array instead. 273 * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose 274 * in '') and %%. 275 * 276 * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, 277 * and TRUE values to decimal 1. 278 * 279 * @param $from 280 * The first result row to return. 281 * @param $count 282 * The maximum number of result rows to return. 283 * @return 284 * A database query result resource, or FALSE if the query was not executed 285 * correctly. 286 */ 287 function db_query_range($query) { 288 $args = func_get_args(); 289 $count = array_pop($args); 290 $from = array_pop($args); 291 array_shift($args); 292 293 $query = db_prefix_tables($query); 294 if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax 295 $args = $args[0]; 296 } 297 _db_query_callback($args, TRUE); 298 $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); 299 $query .= ' LIMIT '. (int)$from .', '. (int)$count; 300 return _db_query($query); 301 } 302 303 /** 304 * Runs a SELECT query and stores its results in a temporary table. 305 * 306 * Use this as a substitute for db_query() when the results need to stored 307 * in a temporary table. Temporary tables exist for the duration of the page 308 * request. 309 * User-supplied arguments to the query should be passed in as separate parameters 310 * so that they can be properly escaped to avoid SQL injection attacks. 311 * 312 * Note that if you need to know how many results were returned, you should do 313 * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and 314 * db_affected_rows() do not give consistent result across different database 315 * types in this case. 316 * 317 * @param $query 318 * A string containing a normal SELECT SQL query. 319 * @param ... 320 * A variable number of arguments which are substituted into the query 321 * using printf() syntax. The query arguments can be enclosed in one 322 * array instead. 323 * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose 324 * in '') and %%. 325 * 326 * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, 327 * and TRUE values to decimal 1. 328 * 329 * @param $table 330 * The name of the temporary table to select into. This name will not be 331 * prefixed as there is no risk of collision. 332 * @return 333 * A database query result resource, or FALSE if the query was not executed 334 * correctly. 335 */ 336 function db_query_temporary($query) { 337 $args = func_get_args(); 338 $tablename = array_pop($args); 339 array_shift($args); 340 341 $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' SELECT', db_prefix_tables($query)); 342 if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax 343 $args = $args[0]; 344 } 345 _db_query_callback($args, TRUE); 346 $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); 347 return _db_query($query); 348 } 349 350 /** 351 * Returns a properly formatted Binary Large Object value. 352 * 353 * @param $data 354 * Data to encode. 355 * @return 356 * Encoded data. 357 */ 358 function db_encode_blob($data) { 359 global $active_db; 360 return "'" . mysqli_real_escape_string($active_db, $data) . "'"; 361 } 362 363 /** 364 * Returns text from a Binary Large OBject value. 365 * 366 * @param $data 367 * Data to decode. 368 * @return 369 * Decoded data. 370 */ 371 function db_decode_blob($data) { 372 return $data; 373 } 374 375 /** 376 * Prepare user input for use in a database query, preventing SQL injection attacks. 377 */ 378 function db_escape_string($text) { 379 global $active_db; 380 return mysqli_real_escape_string($active_db, $text); 381 } 382 383 /** 384 * Lock a table. 385 */ 386 function db_lock_table($table) { 387 db_query('LOCK TABLES {'. db_escape_table($table) .'} WRITE'); 388 } 389 390 /** 391 * Unlock all locked tables. 392 */ 393 function db_unlock_tables() { 394 db_query('UNLOCK TABLES'); 395 } 396 397 /** 398 * Check if a table exists. 399 */ 400 function db_table_exists($table) { 401 return db_num_rows(db_query("SHOW TABLES LIKE '{" . db_escape_table($table) . "}'")); 402 } 403 404 /** 405 * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to 406 * the SELECT list entry of the given query and the resulting query is returned. 407 * This function only applies the wrapper if a DISTINCT doesn't already exist in 408 * the query. 409 * 410 * @param $table Table containing the field to set as DISTINCT 411 * @param $field Field to set as DISTINCT 412 * @param $query Query to apply the wrapper to 413 * @return SQL query with the DISTINCT wrapper surrounding the given table.field. 414 */ 415 function db_distinct_field($table, $field, $query) { 416 $field_to_select = 'DISTINCT('. $table .'.'. $field .')'; 417 // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT). 418 return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query); 419 } 420 421 /** 422 * @} End of "ingroup database". 423 */ 424
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Nov 30 16:20:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |