1<?php 2/* vim: set expandtab sw=4 ts=4 sts=4: */ 3/** 4 * Interface to the classic MySQL extension 5 * 6 * @package PhpMyAdmin-DBI 7 * @subpackage MySQL 8 */ 9namespace PhpMyAdmin\Dbi; 10 11use PhpMyAdmin\Core; 12use PhpMyAdmin\DatabaseInterface; 13 14if (! defined('PHPMYADMIN')) { 15 exit; 16} 17 18if (! extension_loaded('mysql')) { 19 // The old MySQL extension is deprecated as of PHP 5.5.0, and will be 20 // removed in the future. Instead, the `MySQLi` or `PDO_MySQL` extension 21 // should be used. 22 return; 23} 24 25/** 26 * Interface to the classic MySQL extension 27 * 28 * @package PhpMyAdmin-DBI 29 * @subpackage MySQL 30 */ 31class DbiMysql implements DbiExtension 32{ 33 /** 34 * Helper function for connecting to the database server 35 * 36 * @param string $server host/port/socket 37 * @param string $user mysql user name 38 * @param string $password mysql user password 39 * @param int $client_flags client flags of connection 40 * @param bool $persistent whether to use persistent connection 41 * 42 * @return mixed false on error or a mysql connection resource on success 43 */ 44 private function _realConnect($server, $user, $password, $client_flags, 45 $persistent = false 46 ) { 47 global $cfg; 48 49 if (ini_get('mysql.allow_local_infile')) { 50 Core::fatalError(__('Please disable mysql.allow_local_infile in your PHP configuration or install the mysqli extension.')); 51 } 52 53 if (empty($client_flags)) { 54 if ($cfg['PersistentConnections'] || $persistent) { 55 $link = @mysql_pconnect($server, $user, $password); 56 } else { 57 $link = @mysql_connect($server, $user, $password); 58 } 59 } else { 60 if ($cfg['PersistentConnections'] || $persistent) { 61 $link = @mysql_pconnect($server, $user, $password, $client_flags); 62 } else { 63 $link = @mysql_connect( 64 $server, $user, $password, false, $client_flags 65 ); 66 } 67 } 68 69 return $link; 70 } 71 72 /** 73 * Run the multi query and output the results 74 * 75 * @param mysqli $link mysqli object 76 * @param string $query multi query statement to execute 77 * 78 * @return boolean false always false since mysql extension not support 79 * for multi query executions 80 */ 81 public function realMultiQuery($link, $query) 82 { 83 // N.B.: PHP's 'mysql' extension does not support 84 // multi_queries so this function will always 85 // return false. Use the 'mysqli' extension, if 86 // you need support for multi_queries. 87 return false; 88 } 89 90 /** 91 * connects to the database server 92 * 93 * @param string $user mysql user name 94 * @param string $password mysql user password 95 * @param array $server host/port/socket/persistent 96 * 97 * @return mixed false on error or a mysqli object on success 98 */ 99 public function connect( 100 $user, $password, array $server 101 ) { 102 if ($server['port'] === 0) { 103 $server_port = ''; 104 } else { 105 $server_port = ':' . $server['port']; 106 } 107 108 if (is_null($server['socket'])) { 109 $server_socket = ''; 110 } else { 111 $server_socket = ':' . $server['socket']; 112 } 113 114 $client_flags = 0; 115 116 if (defined('PMA_ENABLE_LDI')) { 117 // use CLIENT_LOCAL_FILES as defined in mysql_com.h 118 // for the case where the client library was not compiled 119 // with --enable-local-infile 120 $client_flags |= 128; 121 } 122 123 /* Optionally compress connection */ 124 if (defined('MYSQL_CLIENT_COMPRESS') && $server['compress']) { 125 $client_flags |= MYSQL_CLIENT_COMPRESS; 126 } 127 128 /* Optionally enable SSL */ 129 if (defined('MYSQL_CLIENT_SSL') && $server['ssl']) { 130 $client_flags |= MYSQL_CLIENT_SSL; 131 } 132 133 if (!isset($server['host'])) { 134 $link = $this->_realConnect($server_socket, $user, $password, null); 135 } else { 136 $link = $this->_realConnect( 137 $server['host'] . $server_port . $server_socket, 138 $user, $password, null 139 ); 140 } 141 return $link; 142 } 143 144 /** 145 * selects given database 146 * 147 * @param string $dbname name of db to select 148 * @param resource|null $link mysql link resource 149 * 150 * @return bool 151 */ 152 public function selectDb($dbname, $link) 153 { 154 return mysql_select_db($dbname, $link); 155 } 156 157 /** 158 * runs a query and returns the result 159 * 160 * @param string $query query to run 161 * @param resource|null $link mysql link resource 162 * @param int $options query options 163 * 164 * @return mixed 165 */ 166 public function realQuery($query, $link, $options) 167 { 168 if ($options == ($options | DatabaseInterface::QUERY_STORE)) { 169 return mysql_query($query, $link); 170 } elseif ($options == ($options | DatabaseInterface::QUERY_UNBUFFERED)) { 171 return mysql_unbuffered_query($query, $link); 172 } 173 174 return mysql_query($query, $link); 175 } 176 177 /** 178 * returns array of rows with associative and numeric keys from $result 179 * 180 * @param resource $result result MySQL result 181 * 182 * @return array 183 */ 184 public function fetchArray($result) 185 { 186 return mysql_fetch_array($result, MYSQL_BOTH); 187 } 188 189 /** 190 * returns array of rows with associative keys from $result 191 * 192 * @param resource $result MySQL result 193 * 194 * @return array 195 */ 196 public function fetchAssoc($result) 197 { 198 return mysql_fetch_array($result, MYSQL_ASSOC); 199 } 200 201 /** 202 * returns array of rows with numeric keys from $result 203 * 204 * @param resource $result MySQL result 205 * 206 * @return array 207 */ 208 public function fetchRow($result) 209 { 210 return mysql_fetch_array($result, MYSQL_NUM); 211 } 212 213 /** 214 * Adjusts the result pointer to an arbitrary row in the result 215 * 216 * @param resource $result database result 217 * @param integer $offset offset to seek 218 * 219 * @return bool true on success, false on failure 220 */ 221 public function dataSeek($result, $offset) 222 { 223 return mysql_data_seek($result, $offset); 224 } 225 226 /** 227 * Frees memory associated with the result 228 * 229 * @param resource $result database result 230 * 231 * @return void 232 */ 233 public function freeResult($result) 234 { 235 if (is_resource($result) && get_resource_type($result) === 'mysql result') { 236 mysql_free_result($result); 237 } 238 } 239 240 /** 241 * Check if there are any more query results from a multi query 242 * 243 * @param resource $link the connection object 244 * 245 * @return bool false 246 */ 247 public function moreResults($link) 248 { 249 // N.B.: PHP's 'mysql' extension does not support 250 // multi_queries so this function will always 251 // return false. Use the 'mysqli' extension, if 252 // you need support for multi_queries. 253 return false; 254 } 255 256 /** 257 * Prepare next result from multi_query 258 * 259 * @param resource $link the connection object 260 * 261 * @return boolean false 262 */ 263 public function nextResult($link) 264 { 265 // N.B.: PHP's 'mysql' extension does not support 266 // multi_queries so this function will always 267 // return false. Use the 'mysqli' extension, if 268 // you need support for multi_queries. 269 return false; 270 } 271 272 /** 273 * Returns a string representing the type of connection used 274 * 275 * @param resource|null $link mysql link 276 * 277 * @return string type of connection used 278 */ 279 public function getHostInfo($link) 280 { 281 return mysql_get_host_info($link); 282 } 283 284 /** 285 * Returns the version of the MySQL protocol used 286 * 287 * @param resource|null $link mysql link 288 * 289 * @return int version of the MySQL protocol used 290 */ 291 public function getProtoInfo($link) 292 { 293 return mysql_get_proto_info($link); 294 } 295 296 /** 297 * returns a string that represents the client library version 298 * 299 * @return string MySQL client library version 300 */ 301 public function getClientInfo() 302 { 303 return mysql_get_client_info(); 304 } 305 306 /** 307 * returns last error message or false if no errors occurred 308 * 309 * @param resource|null $link mysql link 310 * 311 * @return string|bool $error or false 312 */ 313 public function getError($link) 314 { 315 $GLOBALS['errno'] = 0; 316 317 if (null !== $link && false !== $link) { 318 $error_number = mysql_errno($link); 319 $error_message = mysql_error($link); 320 } else { 321 $error_number = mysql_errno(); 322 $error_message = mysql_error(); 323 } 324 if (0 == $error_number) { 325 return false; 326 } 327 328 // keep the error number for further check after 329 // the call to getError() 330 $GLOBALS['errno'] = $error_number; 331 332 return $GLOBALS['dbi']->formatError($error_number, $error_message); 333 } 334 335 /** 336 * returns the number of rows returned by last query 337 * 338 * @param resource $result MySQL result 339 * 340 * @return string|int 341 */ 342 public function numRows($result) 343 { 344 if (is_bool($result)) { 345 return 0; 346 } 347 348 return mysql_num_rows($result); 349 } 350 351 /** 352 * returns the number of rows affected by last query 353 * 354 * @param resource|null $link the mysql object 355 * 356 * @return int 357 */ 358 public function affectedRows($link) 359 { 360 return mysql_affected_rows($link); 361 } 362 363 /** 364 * returns metainfo for fields in $result 365 * 366 * @param resource $result MySQL result 367 * 368 * @return array meta info for fields in $result 369 * 370 * @todo add missing keys like in mysqli_query (decimals) 371 */ 372 public function getFieldsMeta($result) 373 { 374 $fields = array(); 375 $num_fields = mysql_num_fields($result); 376 for ($i = 0; $i < $num_fields; $i++) { 377 $field = mysql_fetch_field($result, $i); 378 $field->flags = mysql_field_flags($result, $i); 379 $field->orgtable = mysql_field_table($result, $i); 380 $field->orgname = mysql_field_name($result, $i); 381 $fields[] = $field; 382 } 383 return $fields; 384 } 385 386 /** 387 * return number of fields in given $result 388 * 389 * @param resource $result MySQL result 390 * 391 * @return int field count 392 */ 393 public function numFields($result) 394 { 395 return mysql_num_fields($result); 396 } 397 398 /** 399 * returns the length of the given field $i in $result 400 * 401 * @param resource $result MySQL result 402 * @param int $i field 403 * 404 * @return int length of field 405 */ 406 public function fieldLen($result, $i) 407 { 408 return mysql_field_len($result, $i); 409 } 410 411 /** 412 * returns name of $i. field in $result 413 * 414 * @param resource $result MySQL result 415 * @param int $i field 416 * 417 * @return string name of $i. field in $result 418 */ 419 public function fieldName($result, $i) 420 { 421 return mysql_field_name($result, $i); 422 } 423 424 /** 425 * returns concatenated string of human readable field flags 426 * 427 * @param resource $result MySQL result 428 * @param int $i field 429 * 430 * @return string field flags 431 */ 432 public function fieldFlags($result, $i) 433 { 434 return mysql_field_flags($result, $i); 435 } 436 437 /** 438 * Store the result returned from multi query 439 * 440 * @param resource $result MySQL result 441 * 442 * @return false 443 */ 444 public function storeResult($result) 445 { 446 return false; 447 } 448 449 /** 450 * returns properly escaped string for use in MySQL queries 451 * 452 * @param mixed $link database link 453 * @param string $str string to be escaped 454 * 455 * @return string a MySQL escaped string 456 */ 457 public function escapeString($link, $str) 458 { 459 return mysql_real_escape_string($str, $link); 460 } 461} 462