root/ext/mysql/php_mysql.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_DECLARE_MODULE_GLOBALS
  2. _free_mysql_result
  3. php_mysql_set_default_link
  4. php_mysql_select_db
  5. _close_mysql_link
  6. _close_mysql_plink
  7. PHP_INI_MH
  8. PHP_INI_BEGIN
  9. mysql_convert_zv_to_mysqlnd
  10. ZEND_MODULE_STARTUP_D
  11. PHP_MSHUTDOWN_FUNCTION
  12. PHP_RINIT_FUNCTION
  13. php_mysql_persistent_helper
  14. PHP_RSHUTDOWN_FUNCTION
  15. PHP_MINFO_FUNCTION
  16. php_mysql_do_connect
  17. php_mysql_get_default_link
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. PHP_FUNCTION
  25. PHP_FUNCTION
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. php_mysql_do_query_general
  34. php_mysql_do_query
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. PHP_FUNCTION
  41. PHP_FUNCTION
  42. PHP_FUNCTION
  43. PHP_FUNCTION
  44. PHP_FUNCTION
  45. PHP_FUNCTION
  46. PHP_FUNCTION
  47. PHP_FUNCTION
  48. PHP_FUNCTION
  49. PHP_FUNCTION
  50. PHP_FUNCTION
  51. php_mysql_fetch_hash
  52. PHP_FUNCTION
  53. PHP_FUNCTION
  54. PHP_FUNCTION
  55. PHP_FUNCTION
  56. PHP_FUNCTION
  57. PHP_FUNCTION
  58. php_mysql_get_field_name
  59. PHP_FUNCTION
  60. PHP_FUNCTION
  61. php_mysql_field_info
  62. PHP_FUNCTION
  63. PHP_FUNCTION
  64. PHP_FUNCTION
  65. PHP_FUNCTION
  66. PHP_FUNCTION
  67. PHP_FUNCTION
  68. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Zeev Suraski <zeev@zend.com>                                |
  16    |          Zak Greant <zak@mysql.com>                                  |
  17    |          Georg Richter <georg@php.net>                               |
  18    +----------------------------------------------------------------------+
  19 */
  20 
  21 /* $Id$ */
  22 
  23 /* TODO:
  24  *
  25  * ? Safe mode implementation
  26  */
  27 
  28 #ifdef HAVE_CONFIG_H
  29 # include "config.h"
  30 #endif
  31 
  32 #include "php.h"
  33 #include "php_globals.h"
  34 #include "ext/standard/info.h"
  35 #include "ext/standard/php_string.h"
  36 #include "ext/standard/basic_functions.h"
  37 
  38 #ifdef ZEND_ENGINE_2
  39 # include "zend_exceptions.h"
  40 #else
  41   /* PHP 4 compat */
  42 # define OnUpdateLong   OnUpdateInt
  43 # define E_STRICT               E_NOTICE
  44 #endif
  45 
  46 #if HAVE_MYSQL
  47 
  48 #ifdef PHP_WIN32
  49 # include <winsock2.h>
  50 # define signal(a, b) NULL
  51 #elif defined(NETWARE)
  52 # include <sys/socket.h>
  53 # define signal(a, b) NULL
  54 #else
  55 # if HAVE_SIGNAL_H
  56 #  include <signal.h>
  57 # endif
  58 # if HAVE_SYS_TYPES_H
  59 #  include <sys/types.h>
  60 # endif
  61 # include <netdb.h>
  62 # include <netinet/in.h>
  63 # if HAVE_ARPA_INET_H
  64 #  include <arpa/inet.h>
  65 # endif
  66 #endif
  67 
  68 #include "php_ini.h"
  69 #include "php_mysql_structs.h"
  70 
  71 /* True globals, no need for thread safety */
  72 static int le_result, le_link, le_plink;
  73 
  74 #ifdef HAVE_MYSQL_REAL_CONNECT
  75 # ifdef HAVE_ERRMSG_H
  76 #  include <errmsg.h>
  77 # endif
  78 #endif
  79 
  80 #define SAFE_STRING(s) ((s)?(s):"")
  81 
  82 #if MYSQL_VERSION_ID > 32199 || defined(MYSQL_USE_MYSQLND)
  83 # define mysql_row_length_type unsigned long
  84 # define HAVE_MYSQL_ERRNO
  85 #else
  86 # define mysql_row_length_type unsigned int
  87 # ifdef mysql_errno
  88 #  define HAVE_MYSQL_ERRNO
  89 # endif
  90 #endif
  91 
  92 #if MYSQL_VERSION_ID >= 32032 || defined(MYSQL_USE_MYSQLND)
  93 #define HAVE_GETINFO_FUNCS
  94 #endif
  95 
  96 #if MYSQL_VERSION_ID > 32133 || defined(FIELD_TYPE_TINY)
  97 #define MYSQL_HAS_TINY
  98 #endif
  99 
 100 #if MYSQL_VERSION_ID >= 32200
 101 #define MYSQL_HAS_YEAR
 102 #endif
 103 
 104 #define MYSQL_ASSOC             1<<0
 105 #define MYSQL_NUM               1<<1
 106 #define MYSQL_BOTH              (MYSQL_ASSOC|MYSQL_NUM)
 107 
 108 #define MYSQL_USE_RESULT        0
 109 #define MYSQL_STORE_RESULT      1
 110 
 111 #if MYSQL_VERSION_ID < 32224
 112 #define PHP_MYSQL_VALID_RESULT(mysql)           \
 113         (mysql_num_fields(mysql)>0)
 114 #else
 115 #define PHP_MYSQL_VALID_RESULT(mysql)           \
 116         (mysql_field_count(mysql)>0)
 117 #endif
 118 
 119 ZEND_DECLARE_MODULE_GLOBALS(mysql)
 120 static PHP_GINIT_FUNCTION(mysql);
 121 
 122 typedef struct _php_mysql_conn {
 123         MYSQL *conn;
 124         int active_result_id;
 125         int multi_query;
 126 } php_mysql_conn;
 127 
 128 
 129 #if MYSQL_VERSION_ID >= 40101
 130 #define MYSQL_DISABLE_MQ if (mysql->multi_query) { \
 131         mysql_set_server_option(mysql->conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
 132         mysql->multi_query = 0; \
 133 }
 134 #else
 135 #define MYSQL_DISABLE_MQ
 136 #endif
 137 
 138 /* {{{ arginfo */
 139 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_connect, 0, 0, 0)
 140         ZEND_ARG_INFO(0, hostname)
 141         ZEND_ARG_INFO(0, username)
 142         ZEND_ARG_INFO(0, password)
 143         ZEND_ARG_INFO(0, new)
 144         ZEND_ARG_INFO(0, flags)
 145 ZEND_END_ARG_INFO()
 146 
 147 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_pconnect, 0, 0, 0)
 148         ZEND_ARG_INFO(0, hostname)
 149         ZEND_ARG_INFO(0, username)
 150         ZEND_ARG_INFO(0, password)
 151         ZEND_ARG_INFO(0, flags)
 152 ZEND_END_ARG_INFO()
 153 
 154 ZEND_BEGIN_ARG_INFO_EX(arginfo__optional_mysql_link, 0, 0, 0)
 155         ZEND_ARG_INFO(0, link_identifier)
 156 ZEND_END_ARG_INFO()
 157 
 158 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_select_db, 0, 0, 1)
 159         ZEND_ARG_INFO(0, database_name)
 160         ZEND_ARG_INFO(0, link_identifier)
 161 ZEND_END_ARG_INFO()
 162 
 163 ZEND_BEGIN_ARG_INFO(arginfo__void_mysql_arg, 0)
 164 ZEND_END_ARG_INFO()
 165 
 166 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_set_charset, 0, 0, 1)
 167         ZEND_ARG_INFO(0, charset_name)
 168         ZEND_ARG_INFO(0, link_identifier)
 169 ZEND_END_ARG_INFO()
 170 
 171 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_query, 0, 0, 1)
 172         ZEND_ARG_INFO(0, query)
 173         ZEND_ARG_INFO(0, link_identifier)
 174 ZEND_END_ARG_INFO()
 175 
 176 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_db_query, 0, 0, 2)
 177         ZEND_ARG_INFO(0, database_name)
 178         ZEND_ARG_INFO(0, query)
 179         ZEND_ARG_INFO(0, link_identifier)
 180 ZEND_END_ARG_INFO()
 181 
 182 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_list_fields, 0, 0, 2)
 183         ZEND_ARG_INFO(0, database_name)
 184         ZEND_ARG_INFO(0, table_name)
 185         ZEND_ARG_INFO(0, link_identifier)
 186 ZEND_END_ARG_INFO()
 187 
 188 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_escape_string, 0, 0, 1)
 189         ZEND_ARG_INFO(0, string)
 190 ZEND_END_ARG_INFO()
 191 
 192 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_real_escape_string, 0, 0, 1)
 193         ZEND_ARG_INFO(0, string)
 194         ZEND_ARG_INFO(0, link_identifier)
 195 ZEND_END_ARG_INFO()
 196 
 197 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_result, 0, 0, 2)
 198         ZEND_ARG_INFO(0, result)
 199         ZEND_ARG_INFO(0, row)
 200         ZEND_ARG_INFO(0, field)
 201 ZEND_END_ARG_INFO()
 202 
 203 ZEND_BEGIN_ARG_INFO_EX(arginfo__result_mysql_arg, 0, 0, 1)
 204         ZEND_ARG_INFO(0, result)
 205 ZEND_END_ARG_INFO()
 206 
 207 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_object, 0, 0, 1)
 208         ZEND_ARG_INFO(0, result)
 209         ZEND_ARG_INFO(0, class_name)
 210         ZEND_ARG_INFO(0, ctor_params)
 211 ZEND_END_ARG_INFO()
 212 
 213 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_array, 0, 0, 1)
 214         ZEND_ARG_INFO(0, result)
 215         ZEND_ARG_INFO(0, result_type)
 216 ZEND_END_ARG_INFO()
 217 
 218 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_data_seek, 0, 0, 2)
 219         ZEND_ARG_INFO(0, result)
 220         ZEND_ARG_INFO(0, row_number)
 221 ZEND_END_ARG_INFO()
 222 
 223 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_field, 0, 0, 1)
 224         ZEND_ARG_INFO(0, result)
 225         ZEND_ARG_INFO(0, field_offset)
 226 ZEND_END_ARG_INFO()
 227 
 228 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_seek, 0, 0, 2)
 229         ZEND_ARG_INFO(0, result)
 230         ZEND_ARG_INFO(0, field_offset)
 231 ZEND_END_ARG_INFO()
 232 
 233 ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_name, 0, 0, 2)
 234         ZEND_ARG_INFO(0, result)
 235         ZEND_ARG_INFO(0, field_index)
 236 ZEND_END_ARG_INFO()
 237 /* }}} */
 238 
 239 /* {{{ mysql_functions[]
 240  */
 241 static const zend_function_entry mysql_functions[] = {
 242         PHP_FE(mysql_connect,                                                           arginfo_mysql_connect)
 243         PHP_FE(mysql_pconnect,                                                          arginfo_mysql_pconnect)
 244         PHP_FE(mysql_close,                                                                     arginfo__optional_mysql_link)
 245         PHP_FE(mysql_select_db,                                                         arginfo_mysql_select_db)
 246 #ifndef NETWARE         /* The below two functions not supported on NetWare */
 247 #if MYSQL_VERSION_ID < 40000
 248         PHP_DEP_FE(mysql_create_db,                                                     arginfo_mysql_select_db)
 249         PHP_DEP_FE(mysql_drop_db,                                                       arginfo_mysql_select_db)
 250 #endif
 251 #endif  /* NETWARE */
 252         PHP_FE(mysql_query,                                                                     arginfo_mysql_query)
 253         PHP_FE(mysql_unbuffered_query,                                          arginfo_mysql_query)
 254         PHP_DEP_FE(mysql_db_query,                                                      arginfo_mysql_db_query)
 255         PHP_DEP_FE(mysql_list_dbs,                                                      arginfo__optional_mysql_link)
 256         PHP_DEP_FE(mysql_list_tables,                                           arginfo_mysql_select_db)
 257         PHP_FE(mysql_list_fields,                                                       arginfo_mysql_list_fields)
 258         PHP_FE(mysql_list_processes,                                            arginfo__optional_mysql_link)
 259         PHP_FE(mysql_error,                                                                     arginfo__optional_mysql_link)
 260 #ifdef HAVE_MYSQL_ERRNO
 261         PHP_FE(mysql_errno,                                                                     arginfo__optional_mysql_link)
 262 #endif
 263         PHP_FE(mysql_affected_rows,                                                     arginfo__optional_mysql_link)
 264         PHP_FE(mysql_insert_id,                                                         arginfo__optional_mysql_link)
 265         PHP_FE(mysql_result,                                                            arginfo_mysql_result)
 266         PHP_FE(mysql_num_rows,                                                          arginfo__result_mysql_arg)
 267         PHP_FE(mysql_num_fields,                                                        arginfo__result_mysql_arg)
 268         PHP_FE(mysql_fetch_row,                                                         arginfo__result_mysql_arg)
 269         PHP_FE(mysql_fetch_array,                                                       arginfo_mysql_fetch_array)
 270         PHP_FE(mysql_fetch_assoc,                                                       arginfo__result_mysql_arg)
 271         PHP_FE(mysql_fetch_object,                                                      arginfo_mysql_fetch_object)
 272         PHP_FE(mysql_data_seek,                                                         arginfo_mysql_data_seek)
 273         PHP_FE(mysql_fetch_lengths,                                                     arginfo__result_mysql_arg)
 274         PHP_FE(mysql_fetch_field,                                                       arginfo_mysql_fetch_field)
 275         PHP_FE(mysql_field_seek,                                                        arginfo_mysql_field_seek)
 276         PHP_FE(mysql_free_result,                                                       arginfo__result_mysql_arg)
 277         PHP_FE(mysql_field_name,                                                        arginfo_mysql_field_name)
 278         PHP_FE(mysql_field_table,                                                       arginfo_mysql_field_seek)
 279         PHP_FE(mysql_field_len,                                                         arginfo_mysql_field_seek)
 280         PHP_FE(mysql_field_type,                                                        arginfo_mysql_field_seek)
 281         PHP_FE(mysql_field_flags,                                                       arginfo_mysql_field_seek)
 282         PHP_FE(mysql_escape_string,                                                     arginfo_mysql_escape_string)
 283         PHP_FE(mysql_real_escape_string,                                        arginfo_mysql_real_escape_string)
 284         PHP_FE(mysql_stat,                                                                      arginfo__optional_mysql_link)
 285         PHP_FE(mysql_thread_id,                                                         arginfo__optional_mysql_link)
 286         PHP_FE(mysql_client_encoding,                                           arginfo__optional_mysql_link)
 287         PHP_FE(mysql_ping,                                                                      arginfo__optional_mysql_link)
 288 #ifdef HAVE_GETINFO_FUNCS
 289         PHP_FE(mysql_get_client_info,                                           arginfo__void_mysql_arg)
 290         PHP_FE(mysql_get_host_info,                                                     arginfo__optional_mysql_link)
 291         PHP_FE(mysql_get_proto_info,                                            arginfo__optional_mysql_link)
 292         PHP_FE(mysql_get_server_info,                                           arginfo__optional_mysql_link)
 293 #endif
 294 
 295         PHP_FE(mysql_info,                                                                      arginfo__optional_mysql_link)
 296 #ifdef MYSQL_HAS_SET_CHARSET
 297         PHP_FE(mysql_set_charset,                                                       arginfo_mysql_set_charset)
 298 #endif
 299         /* for downwards compatibility */
 300         PHP_DEP_FALIAS(mysql,                           mysql_db_query,         arginfo_mysql_db_query)
 301         PHP_DEP_FALIAS(mysql_fieldname,         mysql_field_name,       arginfo_mysql_field_name)
 302         PHP_DEP_FALIAS(mysql_fieldtable,        mysql_field_table,      arginfo_mysql_field_seek)
 303         PHP_DEP_FALIAS(mysql_fieldlen,          mysql_field_len,        arginfo_mysql_field_seek)
 304         PHP_DEP_FALIAS(mysql_fieldtype,         mysql_field_type,       arginfo_mysql_field_seek)
 305         PHP_DEP_FALIAS(mysql_fieldflags,        mysql_field_flags,      arginfo_mysql_field_seek)
 306         PHP_DEP_FALIAS(mysql_selectdb,          mysql_select_db,        arginfo_mysql_select_db)
 307 #ifndef NETWARE         /* The below two functions not supported on NetWare */
 308 #if MYSQL_VERSION_ID < 40000
 309         PHP_DEP_FALIAS(mysql_createdb,  mysql_create_db,        arginfo_mysql_select_db)
 310         PHP_DEP_FALIAS(mysql_dropdb,    mysql_drop_db,          arginfo_mysql_select_db)
 311 #endif
 312 #endif  /* NETWARE */
 313         PHP_DEP_FALIAS(mysql_freeresult,        mysql_free_result,      arginfo__result_mysql_arg)
 314         PHP_DEP_FALIAS(mysql_numfields,         mysql_num_fields,       arginfo__result_mysql_arg)
 315         PHP_DEP_FALIAS(mysql_numrows,           mysql_num_rows,         arginfo__result_mysql_arg)
 316         PHP_DEP_FALIAS(mysql_listdbs,           mysql_list_dbs,         arginfo__optional_mysql_link)
 317         PHP_DEP_FALIAS(mysql_listtables,mysql_list_tables,      arginfo_mysql_select_db)
 318         PHP_DEP_FALIAS(mysql_listfields,        mysql_list_fields,      arginfo_mysql_list_fields)
 319         PHP_FALIAS(mysql_db_name,               mysql_result,           arginfo_mysql_result)
 320         PHP_DEP_FALIAS(mysql_dbname,            mysql_result,           arginfo_mysql_result)
 321         PHP_FALIAS(mysql_tablename,             mysql_result,           arginfo_mysql_result)
 322         PHP_FALIAS(mysql_table_name,    mysql_result,           arginfo_mysql_result)
 323         PHP_FE_END
 324 };
 325 /* }}} */
 326 
 327 /* Dependancies */
 328 static const zend_module_dep mysql_deps[] = {
 329 #if defined(MYSQL_USE_MYSQLND)
 330         ZEND_MOD_REQUIRED("mysqlnd")
 331 #endif
 332         ZEND_MOD_END
 333 };
 334 
 335 /* {{{ mysql_module_entry
 336  */
 337 zend_module_entry mysql_module_entry = {
 338 #if ZEND_MODULE_API_NO >= 20050922
 339         STANDARD_MODULE_HEADER_EX, NULL,
 340         mysql_deps,
 341 #elif ZEND_MODULE_API_NO >= 20010901
 342         STANDARD_MODULE_HEADER,
 343 #endif
 344         "mysql",
 345         mysql_functions,
 346         ZEND_MODULE_STARTUP_N(mysql),
 347         PHP_MSHUTDOWN(mysql),
 348         PHP_RINIT(mysql),
 349         PHP_RSHUTDOWN(mysql),
 350         PHP_MINFO(mysql),
 351         "1.0",
 352         PHP_MODULE_GLOBALS(mysql),
 353         PHP_GINIT(mysql),
 354         NULL,
 355         NULL,
 356         STANDARD_MODULE_PROPERTIES_EX
 357 };
 358 /* }}} */
 359 
 360 #ifdef COMPILE_DL_MYSQL
 361 ZEND_GET_MODULE(mysql)
 362 #endif
 363 
 364 void timeout(int sig);
 365 
 366 #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
 367 
 368 #if defined(MYSQL_USE_MYSQLND)
 369 #define PHPMY_UNBUFFERED_QUERY_CHECK() \
 370 {\
 371         if (mysql->active_result_id) { \
 372                 do {                                    \
 373                         int type;                       \
 374                         MYSQL_RES *_mysql_result;       \
 375                                                         \
 376                         _mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type);   \
 377                         if (_mysql_result && type==le_result) {                                         \
 378                                 if (mysql_result_is_unbuffered(_mysql_result) && !mysql_eof(_mysql_result)) { \
 379                                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
 380                                 }                                               \
 381                                 zend_list_delete(mysql->active_result_id);      \
 382                                 mysql->active_result_id = 0;                    \
 383                         } \
 384                 } while(0); \
 385         }\
 386 }
 387 #else
 388 #define PHPMY_UNBUFFERED_QUERY_CHECK()                  \
 389 {                                                       \
 390         if (mysql->active_result_id) {                  \
 391                 do {                                    \
 392                         int type;                       \
 393                         MYSQL_RES *mysql_result;        \
 394                                                         \
 395                         mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type);    \
 396                         if (mysql_result && type==le_result) {                                          \
 397                                 if (!mysql_eof(mysql_result)) {                                         \
 398                                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
 399                                         while (mysql_fetch_row(mysql_result));  \
 400                                 }                                               \
 401                                 zend_list_delete(mysql->active_result_id);      \
 402                                 mysql->active_result_id = 0;                    \
 403                         }                                                       \
 404                 } while(0);                                                     \
 405         }                                                                       \
 406 }
 407 #endif
 408 
 409 /* {{{ _free_mysql_result
 410  * This wrapper is required since mysql_free_result() returns an integer, and
 411  * thus, cannot be used directly
 412  */
 413 static void _free_mysql_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 414 {
 415         MYSQL_RES *mysql_result = (MYSQL_RES *)rsrc->ptr;
 416 
 417         mysql_free_result(mysql_result);
 418         MySG(result_allocated)--;
 419 }
 420 /* }}} */
 421 
 422 /* {{{ php_mysql_set_default_link
 423  */
 424 static void php_mysql_set_default_link(int id TSRMLS_DC)
 425 {
 426         if (MySG(default_link) != -1) {
 427                 zend_list_delete(MySG(default_link));
 428         }
 429         MySG(default_link) = id;
 430         zend_list_addref(id);
 431 }
 432 /* }}} */
 433 
 434 /* {{{ php_mysql_select_db
 435 */
 436 static int php_mysql_select_db(php_mysql_conn *mysql, char *db TSRMLS_DC)
 437 {
 438         PHPMY_UNBUFFERED_QUERY_CHECK();
 439 
 440         if (mysql_select_db(mysql->conn, db) != 0) {
 441                 return 0;
 442         } else {
 443                 return 1;
 444         }
 445 }
 446 /* }}} */
 447 
 448 /* {{{ _close_mysql_link
 449  */
 450 static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 451 {
 452         php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
 453         void (*handler) (int);
 454 
 455         handler = signal(SIGPIPE, SIG_IGN);
 456         mysql_close(link->conn);
 457         signal(SIGPIPE, handler);
 458         efree(link);
 459         MySG(num_links)--;
 460 }
 461 /* }}} */
 462 
 463 /* {{{ _close_mysql_plink
 464  */
 465 static void _close_mysql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 466 {
 467         php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
 468         void (*handler) (int);
 469 
 470         handler = signal(SIGPIPE, SIG_IGN);
 471         mysql_close(link->conn);
 472         signal(SIGPIPE, handler);
 473 
 474         free(link);
 475         MySG(num_persistent)--;
 476         MySG(num_links)--;
 477 }
 478 /* }}} */
 479 
 480 /* {{{ PHP_INI_MH
 481  */
 482 static PHP_INI_MH(OnMySQLPort)
 483 {
 484         if (new_value != NULL) { /* default port */
 485                 MySG(default_port) = atoi(new_value);
 486         } else {
 487                 MySG(default_port) = -1;
 488         }
 489 
 490         return SUCCESS;
 491 }
 492 /* }}} */
 493 
 494 /* {{{ PHP_INI */
 495 PHP_INI_BEGIN()
 496         STD_PHP_INI_BOOLEAN("mysql.allow_persistent",   "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_persistent,       zend_mysql_globals,             mysql_globals)
 497         STD_PHP_INI_ENTRY_EX("mysql.max_persistent",    "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_persistent,         zend_mysql_globals,             mysql_globals,  display_link_numbers)
 498         STD_PHP_INI_ENTRY_EX("mysql.max_links",                 "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_links,                      zend_mysql_globals,             mysql_globals,  display_link_numbers)
 499         STD_PHP_INI_ENTRY("mysql.default_host",                 NULL,   PHP_INI_ALL,            OnUpdateString,         default_host,           zend_mysql_globals,             mysql_globals)
 500         STD_PHP_INI_ENTRY("mysql.default_user",                 NULL,   PHP_INI_ALL,            OnUpdateString,         default_user,           zend_mysql_globals,             mysql_globals)
 501         STD_PHP_INI_ENTRY("mysql.default_password",             NULL,   PHP_INI_ALL,            OnUpdateString,         default_password,       zend_mysql_globals,             mysql_globals)
 502         PHP_INI_ENTRY("mysql.default_port",                             NULL,   PHP_INI_ALL,            OnMySQLPort)
 503 #ifdef MYSQL_UNIX_ADDR
 504         STD_PHP_INI_ENTRY("mysql.default_socket",               MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty,      default_socket, zend_mysql_globals,             mysql_globals)
 505 #else
 506         STD_PHP_INI_ENTRY("mysql.default_socket",               NULL,   PHP_INI_ALL,            OnUpdateStringUnempty,  default_socket, zend_mysql_globals,             mysql_globals)
 507 #endif
 508         STD_PHP_INI_ENTRY("mysql.connect_timeout",              "60",   PHP_INI_ALL,            OnUpdateLong,           connect_timeout,        zend_mysql_globals,             mysql_globals)
 509         STD_PHP_INI_BOOLEAN("mysql.trace_mode",                 "0",    PHP_INI_ALL,            OnUpdateLong,           trace_mode,             zend_mysql_globals,             mysql_globals)
 510         STD_PHP_INI_BOOLEAN("mysql.allow_local_infile", "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_local_infile, zend_mysql_globals,         mysql_globals)
 511 PHP_INI_END()
 512 /* }}} */
 513 
 514 /* {{{ PHP_GINIT_FUNCTION
 515  */
 516 static PHP_GINIT_FUNCTION(mysql)
 517 {
 518         mysql_globals->num_persistent = 0;
 519         mysql_globals->default_socket = NULL;
 520         mysql_globals->default_host = NULL;
 521         mysql_globals->default_user = NULL;
 522         mysql_globals->default_password = NULL;
 523         mysql_globals->connect_errno = 0;
 524         mysql_globals->connect_error = NULL;
 525         mysql_globals->connect_timeout = 0;
 526         mysql_globals->trace_mode = 0;
 527         mysql_globals->allow_local_infile = 1;
 528         mysql_globals->result_allocated = 0;
 529 }
 530 /* }}} */
 531 
 532 #ifdef MYSQL_USE_MYSQLND
 533 #include "ext/mysqlnd/mysqlnd_reverse_api.h"
 534 static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
 535 {
 536         php_mysql_conn *mysql;
 537 
 538         if (Z_TYPE_P(zv) != IS_RESOURCE) {
 539                 /* Might be nicer to check resource type, too, but ext/mysql is the only one using resources so emitting an error is not to bad, while usually this hook should be silent */
 540                 return NULL;
 541         }
 542 
 543         mysql = (php_mysql_conn *)zend_fetch_resource(&zv TSRMLS_CC, -1, "MySQL-Link", NULL, 2, le_link, le_plink);
 544 
 545         if (!mysql) {
 546                 return NULL;
 547         }
 548 
 549         return mysql->conn;
 550 }
 551 
 552 static MYSQLND_REVERSE_API mysql_reverse_api = {
 553         &mysql_module_entry,
 554         mysql_convert_zv_to_mysqlnd
 555 };
 556 #endif
 557 
 558 /* {{{ PHP_MINIT_FUNCTION
 559  */
 560 ZEND_MODULE_STARTUP_D(mysql)
 561 {
 562         REGISTER_INI_ENTRIES();
 563         le_result = zend_register_list_destructors_ex(_free_mysql_result, NULL, "mysql result", module_number);
 564         le_link = zend_register_list_destructors_ex(_close_mysql_link, NULL, "mysql link", module_number);
 565         le_plink = zend_register_list_destructors_ex(NULL, _close_mysql_plink, "mysql link persistent", module_number);
 566         Z_TYPE(mysql_module_entry) = type;
 567 
 568         REGISTER_LONG_CONSTANT("MYSQL_ASSOC", MYSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
 569         REGISTER_LONG_CONSTANT("MYSQL_NUM", MYSQL_NUM, CONST_CS | CONST_PERSISTENT);
 570         REGISTER_LONG_CONSTANT("MYSQL_BOTH", MYSQL_BOTH, CONST_CS | CONST_PERSISTENT);
 571         REGISTER_LONG_CONSTANT("MYSQL_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
 572 #if MYSQL_VERSION_ID >= 40000
 573         REGISTER_LONG_CONSTANT("MYSQL_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
 574 #endif
 575         REGISTER_LONG_CONSTANT("MYSQL_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
 576         REGISTER_LONG_CONSTANT("MYSQL_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
 577 
 578 #ifndef MYSQL_USE_MYSQLND
 579 #if MYSQL_VERSION_ID >= 40000
 580         if (mysql_server_init(0, NULL, NULL)) {
 581                 return FAILURE;
 582         }
 583 #endif
 584 #endif
 585 
 586 #ifdef MYSQL_USE_MYSQLND
 587         mysqlnd_reverse_api_register_api(&mysql_reverse_api TSRMLS_CC);
 588 #endif
 589 
 590         return SUCCESS;
 591 }
 592 /* }}} */
 593 
 594 /* {{{ PHP_MSHUTDOWN_FUNCTION
 595  */
 596 PHP_MSHUTDOWN_FUNCTION(mysql)
 597 {
 598 #ifndef MYSQL_USE_MYSQLND
 599 #if MYSQL_VERSION_ID >= 40000
 600 #ifdef PHP_WIN32
 601         unsigned long client_ver = mysql_get_client_version();
 602         /*
 603           Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
 604           PHP bug#41350 MySQL bug#25621
 605         */
 606         if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
 607                 mysql_server_end();
 608         }
 609 #else
 610         mysql_server_end();
 611 #endif
 612 #endif
 613 #endif
 614 
 615         UNREGISTER_INI_ENTRIES();
 616         return SUCCESS;
 617 }
 618 /* }}} */
 619 
 620 /* {{{ PHP_RINIT_FUNCTION
 621  */
 622 PHP_RINIT_FUNCTION(mysql)
 623 {
 624 #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
 625         if (mysql_thread_init()) {
 626                 return FAILURE;
 627         }
 628 #endif
 629         MySG(default_link)=-1;
 630         MySG(num_links) = MySG(num_persistent);
 631         /* Reset connect error/errno on every request */
 632         MySG(connect_error) = NULL;
 633         MySG(connect_errno) =0;
 634         MySG(result_allocated) = 0;
 635 
 636         return SUCCESS;
 637 }
 638 /* }}} */
 639 
 640 
 641 #if defined(A0) && defined(MYSQL_USE_MYSQLND)
 642 static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
 643 {
 644         if (le->type == le_plink) {
 645                 mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn);
 646         }
 647         return ZEND_HASH_APPLY_KEEP;
 648 } /* }}} */
 649 #endif
 650 
 651 
 652 /* {{{ PHP_RSHUTDOWN_FUNCTION
 653  */
 654 PHP_RSHUTDOWN_FUNCTION(mysql)
 655 {
 656 #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
 657         mysql_thread_end();
 658 #endif
 659 
 660         if (MySG(trace_mode)) {
 661                 if (MySG(result_allocated)){
 662                         php_error_docref("function.mysql-free-result" TSRMLS_CC, E_WARNING, "%lu result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query()", MySG(result_allocated));
 663                 }
 664         }
 665 
 666         if (MySG(connect_error)!=NULL) {
 667                 efree(MySG(connect_error));
 668         }
 669 
 670 #if defined(A0) && defined(MYSQL_USE_MYSQLND)
 671         zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC);
 672 #endif
 673 
 674         return SUCCESS;
 675 }
 676 /* }}} */
 677 
 678 /* {{{ PHP_MINFO_FUNCTION
 679  */
 680 PHP_MINFO_FUNCTION(mysql)
 681 {
 682         char buf[32];
 683 
 684         php_info_print_table_start();
 685         php_info_print_table_header(2, "MySQL Support", "enabled");
 686         snprintf(buf, sizeof(buf), "%ld", MySG(num_persistent));
 687         php_info_print_table_row(2, "Active Persistent Links", buf);
 688         snprintf(buf, sizeof(buf), "%ld", MySG(num_links));
 689         php_info_print_table_row(2, "Active Links", buf);
 690         php_info_print_table_row(2, "Client API version", mysql_get_client_info());
 691 #if !defined (PHP_WIN32) && !defined (NETWARE) && !defined(MYSQL_USE_MYSQLND)
 692         php_info_print_table_row(2, "MYSQL_MODULE_TYPE", PHP_MYSQL_TYPE);
 693         php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR);
 694         php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE);
 695         php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS);
 696 #endif
 697 
 698         php_info_print_table_end();
 699 
 700         DISPLAY_INI_ENTRIES();
 701 
 702 }
 703 /* }}} */
 704 
 705 /* {{{ php_mysql_do_connect
 706  */
 707 #define MYSQL_DO_CONNECT_CLEANUP()      \
 708         if (free_host) {                                \
 709                 efree(host);                            \
 710         }
 711 
 712 #define MYSQL_DO_CONNECT_RETURN_FALSE()         \
 713         MYSQL_DO_CONNECT_CLEANUP();                             \
 714         RETURN_FALSE;
 715 
 716 #ifdef MYSQL_USE_MYSQLND
 717 #define MYSQL_PORT 0
 718 #endif
 719 
 720 static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
 721 {
 722         char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL;
 723         int  user_len = 0, passwd_len = 0, host_len = 0;
 724         char *hashed_details=NULL;
 725         int hashed_details_length, port = MYSQL_PORT;
 726         long client_flags = 0;
 727         php_mysql_conn *mysql=NULL;
 728 #if MYSQL_VERSION_ID <= 32230
 729         void (*handler) (int);
 730 #endif
 731         zend_bool free_host=0, new_link=0;
 732         long connect_timeout;
 733 
 734     php_error_docref(NULL TSRMLS_CC,
 735                      E_DEPRECATED,
 736                      "The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead");
 737 
 738 #if !defined(MYSQL_USE_MYSQLND)
 739         if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
 740                 php_error_docref(NULL TSRMLS_CC, E_WARNING,
 741                                                 "Headers and client library minor version mismatch. Headers:%d Library:%ld",
 742                                                 MYSQL_VERSION_ID, mysql_get_client_version());
 743         }
 744 #endif
 745 
 746         connect_timeout = MySG(connect_timeout);
 747 
 748         socket = MySG(default_socket);
 749 
 750         if (MySG(default_port) < 0) {
 751 #if !defined(PHP_WIN32) && !defined(NETWARE)
 752                 struct servent *serv_ptr;
 753                 char *env;
 754 
 755                 MySG(default_port) = MYSQL_PORT;
 756                 if ((serv_ptr = getservbyname("mysql", "tcp"))) {
 757                         MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
 758                 }
 759                 if ((env = getenv("MYSQL_TCP_PORT"))) {
 760                         MySG(default_port) = (uint) atoi(env);
 761                 }
 762 #else
 763                 MySG(default_port) = MYSQL_PORT;
 764 #endif
 765         }
 766 
 767         if (PG(sql_safe_mode)) {
 768                 if (ZEND_NUM_ARGS()>0) {
 769                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
 770                 }
 771                 host_and_port=passwd=NULL;
 772                 user=php_get_current_user(TSRMLS_C);
 773                 hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user);
 774                 client_flags = CLIENT_INTERACTIVE;
 775         } else {
 776                 /* mysql_pconnect does not support new_link parameter */
 777                 if (persistent) {
 778                         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len,
 779                                                                         &user, &user_len, &passwd, &passwd_len,
 780                                                                         &client_flags)==FAILURE) {
 781                                 return;
 782                 }
 783                 } else {
 784                         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len,
 785                                                                                 &user, &user_len, &passwd, &passwd_len,
 786                                                                                 &new_link, &client_flags)==FAILURE) {
 787                                 return;
 788                         }
 789                 }
 790 
 791                 if (!host_and_port) {
 792                         host_and_port = MySG(default_host);
 793                 }
 794                 if (!user) {
 795                         user = MySG(default_user);
 796                 }
 797                 if (!passwd) {
 798                         passwd = MySG(default_password);
 799                         passwd_len = passwd? strlen(passwd):0;
 800                 }
 801 
 802 #if !defined(MYSQL_USE_MYSQLND)
 803                 /* disable local infile option for open_basedir */
 804 #if PHP_API_VERSION < 20100412
 805                 if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
 806 #else
 807                 if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) {
 808 #endif
 809                         client_flags ^= CLIENT_LOCAL_FILES;
 810                 }
 811 #endif
 812 
 813 #ifdef CLIENT_MULTI_RESULTS
 814                 client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
 815 #endif
 816 #ifdef CLIENT_MULTI_STATEMENTS
 817                 client_flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
 818 #endif
 819                 hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags);
 820         }
 821 
 822         /* We cannot use mysql_port anymore in windows, need to use
 823          * mysql_real_connect() to set the port.
 824          */
 825         if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
 826                 host = estrndup(host_and_port, tmp-host_and_port);
 827                 free_host = 1;
 828                 tmp++;
 829                 if (tmp[0] != '/') {
 830                         port = atoi(tmp);
 831                         if ((tmp=strchr(tmp, ':'))) {
 832                                 tmp++;
 833                                 socket=tmp;
 834                         }
 835                 } else {
 836                         socket = tmp;
 837                 }
 838         } else {
 839                 host = host_and_port;
 840                 port = MySG(default_port);
 841         }
 842 
 843 #if MYSQL_VERSION_ID < 32200
 844         mysql_port = port;
 845 #endif
 846 
 847         if (!MySG(allow_persistent)) {
 848                 persistent=0;
 849         }
 850         if (persistent) {
 851                 zend_rsrc_list_entry *le;
 852 
 853                 /* try to find if we already have this link in our persistent list */
 854                 if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
 855                         zend_rsrc_list_entry new_le;
 856 
 857                         if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
 858                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
 859                                 efree(hashed_details);
 860                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 861                         }
 862                         if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) {
 863                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
 864                                 efree(hashed_details);
 865                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 866                         }
 867                         /* create the link */
 868                         mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
 869                         if (!mysql) {
 870                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link");
 871                         }
 872                         mysql->active_result_id = 0;
 873 #ifdef CLIENT_MULTI_STATEMENTS
 874                         mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
 875 #else
 876                         mysql->multi_query = 0;
 877 #endif
 878 
 879 #ifndef MYSQL_USE_MYSQLND
 880                         mysql->conn = mysql_init(NULL);
 881 #else
 882                         mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
 883 #endif
 884 
 885                         if (connect_timeout != -1) {
 886                                 mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
 887                         }
 888 #ifndef MYSQL_USE_MYSQLND
 889                         if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
 890 #else
 891                         if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
 892 #endif
 893                         {
 894                                 /* Populate connect error globals so that the error functions can read them */
 895                                 if (MySG(connect_error) != NULL) {
 896                                         efree(MySG(connect_error));
 897                                 }
 898                                 MySG(connect_error) = estrdup(mysql_error(mysql->conn));
 899                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
 900 #if defined(HAVE_MYSQL_ERRNO)
 901                                 MySG(connect_errno) = mysql_errno(mysql->conn);
 902 #endif
 903                                 free(mysql);
 904                                 efree(hashed_details);
 905                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 906                         }
 907                         mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
 908 
 909                         /* hash it up */
 910                         Z_TYPE(new_le) = le_plink;
 911                         new_le.ptr = mysql;
 912                         if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
 913                                 free(mysql);
 914                                 efree(hashed_details);
 915                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 916                         }
 917                         MySG(num_persistent)++;
 918                         MySG(num_links)++;
 919                 } else {  /* The link is in our list of persistent connections */
 920                         if (Z_TYPE_P(le) != le_plink) {
 921                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 922                         }
 923                         mysql = (php_mysql_conn *) le->ptr;
 924                         mysql->active_result_id = 0;
 925 #ifdef CLIENT_MULTI_STATEMENTS
 926                         mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
 927 #else
 928                         mysql->multi_query = 0;
 929 #endif
 930                         /* ensure that the link did not die */
 931 #if defined(A0) && MYSQL_USE_MYSQLND
 932                         mysqlnd_end_psession(mysql->conn);
 933 #endif
 934                         if (mysql_ping(mysql->conn)) {
 935                                 if (mysql_errno(mysql->conn) == 2006) {
 936 #ifndef MYSQL_USE_MYSQLND
 937                                         if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
 938 #else
 939                                         if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
 940 #endif
 941                                         {
 942                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
 943                                                 zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
 944                                                 efree(hashed_details);
 945                                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 946                                         }
 947                                         mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
 948                                 }
 949                         } else {
 950 #ifdef MYSQL_USE_MYSQLND
 951                                 mysqlnd_restart_psession(mysql->conn);
 952 #endif
 953                         }
 954                 }
 955                 ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
 956         } else { /* non persistent */
 957                 zend_rsrc_list_entry *index_ptr, new_index_ptr;
 958 
 959                 /* first we check the hash for the hashed_details key.  if it exists,
 960                  * it should point us to the right offset where the actual mysql link sits.
 961                  * if it doesn't, open a new mysql link, add it to the resource list,
 962                  * and add a pointer to it with hashed_details as the key.
 963                  */
 964                 if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
 965                         int type;
 966                         long link;
 967                         void *ptr;
 968 
 969                         if (Z_TYPE_P(index_ptr) != le_index_ptr) {
 970                                 MYSQL_DO_CONNECT_RETURN_FALSE();
 971                         }
 972                         link = (long) index_ptr->ptr;
 973                         ptr = zend_list_find(link,&type);   /* check if the link is still there */
 974                         if (ptr && (type==le_link || type==le_plink)) {
 975                                 zend_list_addref(link);
 976                                 Z_LVAL_P(return_value) = link;
 977                                 php_mysql_set_default_link(link TSRMLS_CC);
 978                                 Z_TYPE_P(return_value) = IS_RESOURCE;
 979                                 efree(hashed_details);
 980                                 MYSQL_DO_CONNECT_CLEANUP();
 981                                 return;
 982                         } else {
 983                                 zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
 984                         }
 985                 }
 986                 if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
 987                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
 988                         efree(hashed_details);
 989                         MYSQL_DO_CONNECT_RETURN_FALSE();
 990                 }
 991 
 992                 mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
 993                 mysql->active_result_id = 0;
 994 #ifdef CLIENT_MULTI_STATEMENTS
 995                 mysql->multi_query = 1;
 996 #endif
 997 
 998 #ifndef MYSQL_USE_MYSQLND
 999                 mysql->conn = mysql_init(NULL);
1000 #else
1001                 mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
1002 #endif
1003                 if (!mysql->conn) {
1004                         MySG(connect_error) = estrdup("OOM");
1005                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM");
1006                         efree(hashed_details);
1007                         efree(mysql);
1008                         MYSQL_DO_CONNECT_RETURN_FALSE();
1009                 }
1010 
1011                 if (connect_timeout != -1) {
1012                         mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
1013                 }
1014 
1015 #ifndef MYSQL_USE_MYSQLND
1016                 if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
1017 #else
1018                 if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
1019 #endif
1020                 {
1021                         /* Populate connect error globals so that the error functions can read them */
1022                         if (MySG(connect_error) != NULL) {
1023                                 efree(MySG(connect_error));
1024                         }
1025                         MySG(connect_error) = estrdup(mysql_error(mysql->conn));
1026                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
1027 #if defined(HAVE_MYSQL_ERRNO)
1028                         MySG(connect_errno) = mysql_errno(mysql->conn);
1029 #endif
1030                         /* free mysql structure */
1031 #ifdef MYSQL_USE_MYSQLND
1032                         mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED);
1033 #endif
1034                         efree(hashed_details);
1035                         efree(mysql);
1036                         MYSQL_DO_CONNECT_RETURN_FALSE();
1037                 }
1038                 mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
1039 
1040                 /* add it to the list */
1041                 ZEND_REGISTER_RESOURCE(return_value, mysql, le_link);
1042 
1043                 /* add it to the hash */
1044                 new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
1045                 Z_TYPE(new_index_ptr) = le_index_ptr;
1046                 if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
1047                         efree(hashed_details);
1048                         MYSQL_DO_CONNECT_RETURN_FALSE();
1049                 }
1050                 MySG(num_links)++;
1051         }
1052 
1053         efree(hashed_details);
1054         php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
1055         MYSQL_DO_CONNECT_CLEANUP();
1056 }
1057 /* }}} */
1058 
1059 /* {{{ php_mysql_get_default_link
1060  */
1061 static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
1062 {
1063         if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */
1064                 ht = 0;
1065                 php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1066         }
1067         return MySG(default_link);
1068 }
1069 /* }}} */
1070 
1071 /* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])
1072    Opens a connection to a MySQL Server */
1073 PHP_FUNCTION(mysql_connect)
1074 {
1075         php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1076 }
1077 /* }}} */
1078 
1079 /* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])
1080    Opens a persistent connection to a MySQL Server */
1081 PHP_FUNCTION(mysql_pconnect)
1082 {
1083         php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1084 }
1085 /* }}} */
1086 
1087 /* {{{ proto bool mysql_close([int link_identifier])
1088    Close a MySQL connection */
1089 PHP_FUNCTION(mysql_close)
1090 {
1091         int resource_id;
1092         zval *mysql_link=NULL;
1093         php_mysql_conn *mysql;
1094 
1095         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1096                 return;
1097         }
1098 
1099         if (mysql_link) {
1100                 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink);
1101         } else {
1102                 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink);
1103         }
1104 
1105         resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link);
1106         PHPMY_UNBUFFERED_QUERY_CHECK();
1107 #ifdef MYSQL_USE_MYSQLND
1108         {
1109                 int tmp;
1110                 if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) {
1111                         mysqlnd_end_psession(mysql->conn);
1112                 }
1113         }
1114 #endif
1115         zend_list_delete(resource_id);
1116 
1117         if (!mysql_link
1118                 || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) {
1119                 MySG(default_link) = -1;
1120                 if (mysql_link) {
1121                         /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */
1122                         zend_list_delete(resource_id);
1123                 }
1124         }
1125 
1126         RETURN_TRUE;
1127 }
1128 /* }}} */
1129 
1130 /* {{{ proto bool mysql_select_db(string database_name [, int link_identifier])
1131    Selects a MySQL database */
1132 PHP_FUNCTION(mysql_select_db)
1133 {
1134         char *db;
1135         int db_len;
1136         zval *mysql_link = NULL;
1137         int id = -1;
1138         php_mysql_conn *mysql;
1139 
1140         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1141                 return;
1142         }
1143 
1144         if (!mysql_link) {
1145                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1146                 CHECK_LINK(id);
1147         }
1148 
1149         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1150 
1151         if (php_mysql_select_db(mysql, db TSRMLS_CC)) {
1152                 RETURN_TRUE;
1153         } else {
1154                 RETURN_FALSE;
1155         }
1156 }
1157 /* }}} */
1158 
1159 #ifdef HAVE_GETINFO_FUNCS
1160 
1161 /* {{{ proto string mysql_get_client_info(void)
1162    Returns a string that represents the client library version */
1163 PHP_FUNCTION(mysql_get_client_info)
1164 {
1165         if (zend_parse_parameters_none() == FAILURE) {
1166                 return;
1167         }
1168 
1169         RETURN_STRING((char *)mysql_get_client_info(),1);
1170 }
1171 /* }}} */
1172 
1173 /* {{{ proto string mysql_get_host_info([int link_identifier])
1174    Returns a string describing the type of connection in use, including the server host name */
1175 PHP_FUNCTION(mysql_get_host_info)
1176 {
1177         zval *mysql_link = NULL;
1178         int id = -1;
1179         php_mysql_conn *mysql;
1180 
1181         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1182                 return;
1183         }
1184 
1185         if (!mysql_link) {
1186                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1187                 CHECK_LINK(id);
1188         }
1189 
1190         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1191 
1192         RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1);
1193 }
1194 /* }}} */
1195 
1196 /* {{{ proto int mysql_get_proto_info([int link_identifier])
1197    Returns the protocol version used by current connection */
1198 PHP_FUNCTION(mysql_get_proto_info)
1199 {
1200         zval *mysql_link = NULL;
1201         int id = -1;
1202         php_mysql_conn *mysql;
1203 
1204         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1205                 return;
1206         }
1207 
1208         if (!mysql_link) {
1209                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1210                 CHECK_LINK(id);
1211         }
1212 
1213         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1214 
1215         RETURN_LONG(mysql_get_proto_info(mysql->conn));
1216 }
1217 /* }}} */
1218 
1219 /* {{{ proto string mysql_get_server_info([int link_identifier])
1220    Returns a string that represents the server version number */
1221 PHP_FUNCTION(mysql_get_server_info)
1222 {
1223         zval *mysql_link = NULL;
1224         int id = -1;
1225         php_mysql_conn *mysql;
1226 
1227         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1228                 return;
1229         }
1230 
1231         if (!mysql_link) {
1232                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1233                 CHECK_LINK(id);
1234         }
1235 
1236         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1237 
1238         RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1);
1239 }
1240 /* }}} */
1241 
1242 /* {{{ proto string mysql_info([int link_identifier])
1243    Returns a string containing information about the most recent query */
1244 PHP_FUNCTION(mysql_info)
1245 {
1246         zval *mysql_link = NULL;
1247         int id = -1;
1248         char *str;
1249         php_mysql_conn *mysql;
1250 
1251         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1252                 return;
1253         }
1254 
1255         if (ZEND_NUM_ARGS() == 0) {
1256                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1257                 CHECK_LINK(id);
1258         }
1259 
1260         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1261 
1262         if ((str = (char *)mysql_info(mysql->conn))) {
1263                 RETURN_STRING(str,1);
1264         } else {
1265                 RETURN_FALSE;
1266         }
1267 }
1268 /* }}} */
1269 
1270 /* {{{ proto int mysql_thread_id([int link_identifier])
1271         Returns the thread id of current connection */
1272 PHP_FUNCTION(mysql_thread_id)
1273 {
1274         zval *mysql_link = NULL;
1275         int  id = -1;
1276         php_mysql_conn *mysql;
1277 
1278         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1279                 return;
1280         }
1281 
1282         if (ZEND_NUM_ARGS() == 0) {
1283                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1284                 CHECK_LINK(id);
1285         }
1286         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1287 
1288         RETURN_LONG((long) mysql_thread_id(mysql->conn));
1289 }
1290 /* }}} */
1291 
1292 /* {{{ proto string mysql_stat([int link_identifier])
1293         Returns a string containing status information */
1294 PHP_FUNCTION(mysql_stat)
1295 {
1296         zval *mysql_link = NULL;
1297         int id = -1;
1298         php_mysql_conn *mysql;
1299         char *stat;
1300 #ifdef MYSQL_USE_MYSQLND
1301         uint stat_len;
1302 #endif
1303 
1304         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1305                 return;
1306         }
1307 
1308         if (ZEND_NUM_ARGS() == 0) {
1309                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1310                 CHECK_LINK(id);
1311         }
1312         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1313 
1314         PHPMY_UNBUFFERED_QUERY_CHECK();
1315 #ifndef MYSQL_USE_MYSQLND
1316         if ((stat = (char *)mysql_stat(mysql->conn))) {
1317                 RETURN_STRING(stat, 1);
1318 #else
1319         if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) {
1320                 RETURN_STRINGL(stat, stat_len, 0);
1321 #endif
1322         } else {
1323                 RETURN_FALSE;
1324         }
1325 }
1326 /* }}} */
1327 
1328 /* {{{ proto string mysql_client_encoding([int link_identifier])
1329         Returns the default character set for the current connection */
1330 PHP_FUNCTION(mysql_client_encoding)
1331 {
1332         zval *mysql_link = NULL;
1333         int id = -1;
1334         php_mysql_conn *mysql;
1335 
1336         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1337                 return;
1338         }
1339 
1340         if (ZEND_NUM_ARGS() == 0) {
1341                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1342                 CHECK_LINK(id);
1343         }
1344 
1345         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1346         RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1);
1347 }
1348 /* }}} */
1349 #endif
1350 
1351 #ifdef MYSQL_HAS_SET_CHARSET
1352 /* {{{ proto bool mysql_set_charset(string csname [, int link_identifier])
1353    sets client character set */
1354 PHP_FUNCTION(mysql_set_charset)
1355 {
1356         zval *mysql_link = NULL;
1357         char *csname;
1358         int id = -1, csname_len;
1359         php_mysql_conn *mysql;
1360 
1361         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
1362                 return;
1363         }
1364 
1365         if (ZEND_NUM_ARGS() == 1) {
1366                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1367                 CHECK_LINK(id);
1368         }
1369 
1370         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1371 
1372         if (!mysql_set_character_set(mysql->conn, csname)) {
1373                 RETURN_TRUE;
1374         } else {
1375                 RETURN_FALSE;
1376         }
1377 }
1378 /* }}} */
1379 #endif
1380 
1381 #ifndef NETWARE         /* The below two functions not supported on NetWare */
1382 #if MYSQL_VERSION_ID < 40000
1383 /* {{{ proto bool mysql_create_db(string database_name [, int link_identifier])
1384    Create a MySQL database */
1385 PHP_FUNCTION(mysql_create_db)
1386 {
1387         char *db;
1388         int db_len;
1389         zval *mysql_link = NULL;
1390         int id = -1;
1391         php_mysql_conn *mysql;
1392 
1393         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1394                 return;
1395         }
1396 
1397         if (!mysql_link) {
1398                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1399                 CHECK_LINK(id);
1400         }
1401 
1402         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1403 
1404         PHPMY_UNBUFFERED_QUERY_CHECK();
1405 
1406         if (mysql_create_db(mysql->conn, db)==0) {
1407                 RETURN_TRUE;
1408         } else {
1409                 RETURN_FALSE;
1410         }
1411 }
1412 /* }}} */
1413 
1414 /* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier])
1415    Drops (delete) a MySQL database */
1416 PHP_FUNCTION(mysql_drop_db)
1417 {
1418         char *db;
1419         int db_len;
1420         zval *mysql_link = NULL;
1421         int id = -1;
1422         php_mysql_conn *mysql;
1423 
1424         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1425                 return;
1426         }
1427 
1428         if (!mysql_link) {
1429                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1430                 CHECK_LINK(id);
1431         }
1432 
1433         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1434 
1435         if (mysql_drop_db(mysql->conn, db)==0) {
1436                 RETURN_TRUE;
1437         } else {
1438                 RETURN_FALSE;
1439         }
1440 }
1441 /* }}} */
1442 #endif
1443 #endif  /* NETWARE */
1444 
1445 /* {{{ php_mysql_do_query_general
1446  */
1447 static void php_mysql_do_query_general(char *query, int query_len, zval *mysql_link, int link_id, char *db, int use_store, zval *return_value TSRMLS_DC)
1448 {
1449         php_mysql_conn *mysql;
1450         MYSQL_RES *mysql_result;
1451 
1452         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink);
1453 
1454         if (db) {
1455                 if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1456                         RETURN_FALSE;
1457                 }
1458         }
1459 
1460         PHPMY_UNBUFFERED_QUERY_CHECK();
1461 
1462         MYSQL_DISABLE_MQ;
1463 
1464 #ifndef MYSQL_USE_MYSQLND
1465         /* check explain */
1466         if (MySG(trace_mode)) {
1467                 if (!strncasecmp("select", query, 6)){
1468                         MYSQL_ROW       row;
1469 
1470                         char *newquery;
1471                         int newql = spprintf (&newquery, 0, "EXPLAIN %s", query);
1472                         mysql_real_query(mysql->conn, newquery, newql);
1473                         efree (newquery);
1474                         if (mysql_errno(mysql->conn)) {
1475                                 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1476                                 RETURN_FALSE;
1477                         }
1478                         else {
1479                         mysql_result = mysql_use_result(mysql->conn);
1480                                 while ((row = mysql_fetch_row(mysql_result))) {
1481                                         if (!strcmp("ALL", row[1])) {
1482                                                 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full tablescan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
1483                                         } else if (!strcmp("INDEX", row[1])) {
1484                                                 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full indexscan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
1485                                         }
1486                                 }
1487                                 mysql_free_result(mysql_result);
1488                         }
1489                 }
1490         } /* end explain */
1491 #endif
1492 
1493         /* mysql_query is binary unsafe, use mysql_real_query */
1494 #if MYSQL_VERSION_ID > 32199
1495         if (mysql_real_query(mysql->conn, query, query_len)!=0) {
1496                 /* check possible error */
1497                 if (MySG(trace_mode)){
1498                         if (mysql_errno(mysql->conn)){
1499                                 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1500                         }
1501                 }
1502                 RETURN_FALSE;
1503         }
1504 #else
1505         if (mysql_query(mysql->conn, query)!=0) {
1506                 /* check possible error */
1507                 if (MySG(trace_mode)){
1508                         if (mysql_errno(mysql->conn)){
1509                                 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1510                         }
1511                 }
1512                 RETURN_FALSE;
1513         }
1514 #endif
1515         if(use_store == MYSQL_USE_RESULT) {
1516                 mysql_result=mysql_use_result(mysql->conn);
1517         } else {
1518                 mysql_result=mysql_store_result(mysql->conn);
1519         }
1520         if (!mysql_result) {
1521                 if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
1522                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
1523                         RETURN_FALSE;
1524                 } else {
1525                         RETURN_TRUE;
1526                 }
1527         }
1528         MySG(result_allocated)++;
1529         ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1530         if (use_store == MYSQL_USE_RESULT) {
1531                 mysql->active_result_id = Z_LVAL_P(return_value);
1532         }
1533 }
1534 /* }}} */
1535 
1536 /* {{{ php_mysql_do_query
1537  */
1538 static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store)
1539 {
1540         char *query;
1541         int query_len;
1542         zval *mysql_link = NULL;
1543         int id = -1;
1544 
1545         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) {
1546                 return;
1547         }
1548 
1549         if (!mysql_link) {
1550                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1551                 CHECK_LINK(id);
1552         }
1553 
1554         php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC);
1555 }
1556 /* }}} */
1557 
1558 /* {{{ proto resource mysql_query(string query [, int link_identifier])
1559    Sends an SQL query to MySQL */
1560 PHP_FUNCTION(mysql_query)
1561 {
1562         php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
1563 }
1564 /* }}} */
1565 
1566 
1567 /* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
1568    Sends an SQL query to MySQL, without fetching and buffering the result rows */
1569 PHP_FUNCTION(mysql_unbuffered_query)
1570 {
1571         php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
1572 }
1573 /* }}} */
1574 
1575 
1576 /* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier])
1577    Sends an SQL query to MySQL */
1578 PHP_FUNCTION(mysql_db_query)
1579 {
1580         char *db, *query;
1581         int db_len, query_len;
1582         zval *mysql_link = NULL;
1583         int id = -1;
1584 
1585         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) {
1586                 return;
1587         }
1588 
1589         if (!mysql_link) {
1590                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1591                 CHECK_LINK(id);
1592         }
1593 
1594         php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead");
1595 
1596         php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC);
1597 }
1598 /* }}} */
1599 
1600 
1601 /* {{{ proto resource mysql_list_dbs([int link_identifier])
1602    List databases available on a MySQL server */
1603 PHP_FUNCTION(mysql_list_dbs)
1604 {
1605         zval *mysql_link = NULL;
1606         int id = -1;
1607         php_mysql_conn *mysql;
1608         MYSQL_RES *mysql_result;
1609 
1610         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1611                 return;
1612         }
1613 
1614         if (!mysql_link) {
1615                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1616                 CHECK_LINK(id);
1617         }
1618         php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() with SHOW DATABASES instead");
1619 
1620         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1621 
1622         PHPMY_UNBUFFERED_QUERY_CHECK();
1623 
1624 
1625         if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) {
1626                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1627                 RETURN_FALSE;
1628         }
1629         MySG(result_allocated)++;
1630         ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1631 }
1632 /* }}} */
1633 
1634 
1635 /* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier])
1636    List tables in a MySQL database */
1637 PHP_FUNCTION(mysql_list_tables)
1638 {
1639         char *db;
1640         int db_len;
1641         zval *mysql_link = NULL;
1642         int id = -1;
1643         php_mysql_conn *mysql;
1644         MYSQL_RES *mysql_result;
1645 
1646         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1647                 return;
1648         }
1649 
1650         if (!mysql_link) {
1651                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1652                 CHECK_LINK(id);
1653         }
1654 
1655         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1656 
1657         if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1658                 RETURN_FALSE;
1659         }
1660 
1661         PHPMY_UNBUFFERED_QUERY_CHECK();
1662 
1663         if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) {
1664                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1665                 RETURN_FALSE;
1666         }
1667         MySG(result_allocated)++;
1668         ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1669 }
1670 /* }}} */
1671 
1672 
1673 /* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier])
1674    List MySQL result fields */
1675 PHP_FUNCTION(mysql_list_fields)
1676 {
1677         char *db, *table;
1678         int db_len, table_len;
1679         zval *mysql_link = NULL;
1680         int id = -1;
1681         php_mysql_conn *mysql;
1682         MYSQL_RES *mysql_result;
1683 
1684         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) {
1685                 return;
1686         }
1687 
1688         if (!mysql_link) {
1689                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1690                 CHECK_LINK(id);
1691         }
1692 
1693         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1694 
1695         if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1696                 RETURN_FALSE;
1697         }
1698 
1699         PHPMY_UNBUFFERED_QUERY_CHECK();
1700 
1701         if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) {
1702                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1703                 RETURN_FALSE;
1704         }
1705         MySG(result_allocated)++;
1706         ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1707 }
1708 /* }}} */
1709 
1710 /* {{{ proto resource mysql_list_processes([int link_identifier])
1711         Returns a result set describing the current server threads */
1712 PHP_FUNCTION(mysql_list_processes)
1713 {
1714         zval *mysql_link = NULL;
1715         int id = -1;
1716         php_mysql_conn *mysql;
1717         MYSQL_RES *mysql_result;
1718 
1719         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1720                 return;
1721         }
1722 
1723         if (ZEND_NUM_ARGS() == 0) {
1724                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1725                 CHECK_LINK(id);
1726         }
1727 
1728         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1729 
1730         PHPMY_UNBUFFERED_QUERY_CHECK();
1731 
1732         mysql_result = mysql_list_processes(mysql->conn);
1733         if (mysql_result == NULL) {
1734                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1735                 RETURN_FALSE;
1736         }
1737 
1738         MySG(result_allocated)++;
1739         ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1740 }
1741 /* }}} */
1742 
1743 
1744 /* {{{ proto string mysql_error([int link_identifier])
1745    Returns the text of the error message from previous MySQL operation */
1746 PHP_FUNCTION(mysql_error)
1747 {
1748         zval *mysql_link = NULL;
1749         int id = -1;
1750         php_mysql_conn *mysql;
1751 
1752         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1753                 return;
1754         }
1755 
1756         if (!mysql_link) {
1757                 id = MySG(default_link);
1758                 if (id==-1) {
1759                         if (MySG(connect_error)!=NULL){
1760                                 RETURN_STRING(MySG(connect_error),1);
1761                         } else {
1762                                 RETURN_FALSE;
1763                         }
1764                 }
1765         }
1766 
1767         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1768 
1769         RETURN_STRING((char *)mysql_error(mysql->conn), 1);
1770 }
1771 /* }}} */
1772 
1773 
1774 /* {{{ proto int mysql_errno([int link_identifier])
1775    Returns the number of the error message from previous MySQL operation */
1776 #ifdef HAVE_MYSQL_ERRNO
1777 PHP_FUNCTION(mysql_errno)
1778 {
1779         zval *mysql_link = NULL;
1780         int id = -1;
1781         php_mysql_conn *mysql;
1782 
1783         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1784                 return;
1785         }
1786 
1787         if (!mysql_link) {
1788                 id = MySG(default_link);
1789                 if (id==-1) {
1790                         if (MySG(connect_errno)!=0){
1791                                 RETURN_LONG(MySG(connect_errno));
1792                         } else {
1793                                 RETURN_FALSE;
1794                         }
1795                 }
1796         }
1797 
1798         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1799 
1800         RETURN_LONG(mysql_errno(mysql->conn));
1801 }
1802 #endif
1803 /* }}} */
1804 
1805 
1806 /* {{{ proto int mysql_affected_rows([int link_identifier])
1807    Gets number of affected rows in previous MySQL operation */
1808 PHP_FUNCTION(mysql_affected_rows)
1809 {
1810         zval *mysql_link = NULL;
1811         int id = -1;
1812         php_mysql_conn *mysql;
1813 
1814         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1815                 return;
1816         }
1817 
1818         if (!mysql_link) {
1819                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1820                 CHECK_LINK(id);
1821         }
1822 
1823         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1824 
1825         /* conversion from int64 to long happing here */
1826         Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn);
1827         Z_TYPE_P(return_value) = IS_LONG;
1828 }
1829 /* }}} */
1830 
1831 
1832 /* {{{ proto string mysql_escape_string(string to_be_escaped)
1833    Escape string for mysql query */
1834 PHP_FUNCTION(mysql_escape_string)
1835 {
1836         char *str;
1837         int str_len;
1838 
1839         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1840                 return;
1841         }
1842 
1843         /* assume worst case situation, which is 2x of the original string.
1844          * we don't realloc() down to the real size since it'd most probably not
1845          * be worth it
1846          */
1847 
1848         Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1);
1849         Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len);
1850         Z_TYPE_P(return_value) = IS_STRING;
1851 
1852         php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead.");
1853 }
1854 /* }}} */
1855 
1856 /* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier])
1857         Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
1858 PHP_FUNCTION(mysql_real_escape_string)
1859 {
1860         zval *mysql_link = NULL;
1861         char *str;
1862         char *new_str;
1863         int id = -1, str_len, new_str_len;
1864         php_mysql_conn *mysql;
1865 
1866 
1867         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {
1868                 return;
1869         }
1870 
1871         if (ZEND_NUM_ARGS() == 1) {
1872                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1873                 CHECK_LINK(id);
1874         }
1875 
1876         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1877 
1878         new_str = safe_emalloc(str_len, 2, 1);
1879         new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len);
1880         new_str = erealloc(new_str, new_str_len + 1);
1881 
1882         RETURN_STRINGL(new_str, new_str_len, 0);
1883 }
1884 /* }}} */
1885 
1886 /* {{{ proto int mysql_insert_id([int link_identifier])
1887    Gets the ID generated from the previous INSERT operation */
1888 PHP_FUNCTION(mysql_insert_id)
1889 {
1890         zval *mysql_link = NULL;
1891         int id = -1;
1892         php_mysql_conn *mysql;
1893 
1894         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1895                 return;
1896         }
1897 
1898         if (!mysql_link) {
1899                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1900                 CHECK_LINK(id);
1901         }
1902 
1903         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1904 
1905         /* conversion from int64 to long happing here */
1906         Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn);
1907         Z_TYPE_P(return_value) = IS_LONG;
1908 }
1909 /* }}} */
1910 
1911 
1912 /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
1913    Gets result data */
1914 PHP_FUNCTION(mysql_result)
1915 {
1916         zval *result, *field=NULL;
1917         long row;
1918         MYSQL_RES *mysql_result;
1919 #ifndef MYSQL_USE_MYSQLND
1920         MYSQL_ROW sql_row;
1921         mysql_row_length_type *sql_row_lengths;
1922 #endif
1923         int field_offset=0;
1924 
1925 /*
1926 johannes TODO:
1927 Do 2 zend_parse_parameters calls instead of type "z" and switch below
1928 Q: String or long first?
1929 */
1930         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) {
1931                 return;
1932         }
1933 
1934         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
1935 
1936         if (row<0 || row>=(int)mysql_num_rows(mysql_result)) {
1937                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result));
1938                 RETURN_FALSE;
1939         }
1940         mysql_data_seek(mysql_result, row);
1941 
1942         if (field) {
1943                 switch(Z_TYPE_P(field)) {
1944                         case IS_STRING: {
1945                                         int i=0;
1946                                         const MYSQL_FIELD *tmp_field;
1947                                         char *table_name, *field_name, *tmp;
1948 
1949                                         if ((tmp=strchr(Z_STRVAL_P(field), '.'))) {
1950                                                 table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field));
1951                                                 field_name = estrdup(tmp+1);
1952                                         } else {
1953                                                 table_name = NULL;
1954                                                 field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field));
1955                                         }
1956                                         mysql_field_seek(mysql_result, 0);
1957                                         while ((tmp_field=mysql_fetch_field(mysql_result))) {
1958                                                 if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
1959                                                         field_offset = i;
1960                                                         break;
1961                                                 }
1962                                                 i++;
1963                                         }
1964                                         if (!tmp_field) { /* no match found */
1965                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld",
1966                                                                         (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result));
1967                                                 efree(field_name);
1968                                                 if (table_name) {
1969                                                         efree(table_name);
1970                                                 }
1971                                                 RETURN_FALSE;
1972                                         }
1973                                         efree(field_name);
1974                                         if (table_name) {
1975                                                 efree(table_name);
1976                                         }
1977                                 }
1978                                 break;
1979                         default:
1980                                 convert_to_long_ex(&field);
1981                                 field_offset = Z_LVAL_P(field);
1982                                 if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) {
1983                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
1984                                         RETURN_FALSE;
1985                                 }
1986                                 break;
1987                 }
1988         }
1989 
1990 #ifndef MYSQL_USE_MYSQLND
1991         if ((sql_row=mysql_fetch_row(mysql_result))==NULL
1992                 || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */
1993                 RETURN_FALSE;
1994         }
1995         if (sql_row[field_offset]) {
1996                 Z_TYPE_P(return_value) = IS_STRING;
1997 
1998 #if PHP_API_VERSION < 20100412
1999                 if (PG(magic_quotes_runtime)) {
2000                         Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
2001                 } else {
2002 #endif
2003                         Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
2004                         Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
2005 #if PHP_API_VERSION < 20100412
2006                 }
2007 #endif
2008         } else {
2009                 Z_TYPE_P(return_value) = IS_NULL;
2010         }
2011 #else
2012         mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value);
2013 #endif
2014 }
2015 /* }}} */
2016 
2017 
2018 /* {{{ proto int mysql_num_rows(resource result)
2019    Gets number of rows in a result */
2020 PHP_FUNCTION(mysql_num_rows)
2021 {
2022         zval *result;
2023         MYSQL_RES *mysql_result;
2024 
2025         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2026                 return;
2027         }
2028 
2029         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2030 
2031         /* conversion from int64 to long happing here */
2032         Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result);
2033         Z_TYPE_P(return_value) = IS_LONG;
2034 }
2035 /* }}} */
2036 
2037 /* {{{ proto int mysql_num_fields(resource result)
2038    Gets number of fields in a result */
2039 PHP_FUNCTION(mysql_num_fields)
2040 {
2041         zval *result;
2042         MYSQL_RES *mysql_result;
2043 
2044         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2045                 return;
2046         }
2047 
2048         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2049 
2050         Z_LVAL_P(return_value) = mysql_num_fields(mysql_result);
2051         Z_TYPE_P(return_value) = IS_LONG;
2052 }
2053 /* }}} */
2054 
2055 /* {{{ php_mysql_fetch_hash
2056  */
2057 static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object)
2058 {
2059         MYSQL_RES *mysql_result;
2060         zval            *res, *ctor_params = NULL;
2061         zend_class_entry *ce = NULL;
2062 #ifndef MYSQL_USE_MYSQLND
2063         int i;
2064         MYSQL_FIELD *mysql_field;
2065         MYSQL_ROW mysql_row;
2066         mysql_row_length_type *mysql_row_lengths;
2067 #endif
2068 
2069 #ifdef ZEND_ENGINE_2
2070         if (into_object) {
2071                 char *class_name = NULL;
2072                 int class_name_len = 0;
2073 
2074                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) {
2075                         return;
2076                 }
2077 
2078                 if (ZEND_NUM_ARGS() < 2) {
2079                         ce = zend_standard_class_def;
2080                 } else {
2081                         ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
2082                 }
2083                 if (!ce) {
2084                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
2085                         return;
2086                 }
2087                 result_type = MYSQL_ASSOC;
2088         } else
2089 #endif
2090         {
2091                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) {
2092                         return;
2093                 }
2094                 if (!result_type) {
2095                         /* result_type might have been set outside, so only overwrite when not set */
2096                         result_type = MYSQL_BOTH;
2097                 }
2098         }
2099 
2100         if (result_type & ~MYSQL_BOTH) {
2101                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
2102                 result_type = MYSQL_BOTH;
2103         }
2104 
2105         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result);
2106 
2107 #ifndef MYSQL_USE_MYSQLND
2108         if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL  ||
2109                 (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) {
2110                 RETURN_FALSE;
2111         }
2112 
2113         array_init(return_value);
2114 
2115         mysql_field_seek(mysql_result, 0);
2116         for (mysql_field = mysql_fetch_field(mysql_result), i = 0;
2117                  mysql_field;
2118                  mysql_field = mysql_fetch_field(mysql_result), i++)
2119         {
2120                 if (mysql_row[i]) {
2121                         zval *data;
2122 
2123                         MAKE_STD_ZVAL(data);
2124 
2125 #if PHP_API_VERSION < 20100412
2126                         if (PG(magic_quotes_runtime)) {
2127                                 Z_TYPE_P(data) = IS_STRING;
2128                                 Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
2129                         } else {
2130 #endif
2131                                 ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
2132 #if PHP_API_VERSION < 20100412
2133                         }
2134 #endif
2135 
2136                         if (result_type & MYSQL_NUM) {
2137                                 add_index_zval(return_value, i, data);
2138                         }
2139                         if (result_type & MYSQL_ASSOC) {
2140                                 if (result_type & MYSQL_NUM) {
2141                                         Z_ADDREF_P(data);
2142                                 }
2143                                 add_assoc_zval(return_value, mysql_field->name, data);
2144                         }
2145                 } else {
2146                         /* NULL value. */
2147                         if (result_type & MYSQL_NUM) {
2148                                 add_index_null(return_value, i);
2149                         }
2150 
2151                         if (result_type & MYSQL_ASSOC) {
2152                                 add_assoc_null(return_value, mysql_field->name);
2153                         }
2154                 }
2155         }
2156 #else
2157         mysqlnd_fetch_into(mysql_result, ((result_type & MYSQL_NUM)? MYSQLND_FETCH_NUM:0) | ((result_type & MYSQL_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQL);
2158 #endif
2159 
2160 #ifdef ZEND_ENGINE_2
2161         /* mysqlnd might return FALSE if no more rows */
2162         if (into_object && Z_TYPE_P(return_value) != IS_BOOL) {
2163                 zval dataset = *return_value;
2164                 zend_fcall_info fci;
2165                 zend_fcall_info_cache fcc;
2166                 zval *retval_ptr;
2167 
2168                 object_and_properties_init(return_value, ce, NULL);
2169                 zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
2170 
2171                 if (ce->constructor) {
2172                         fci.size = sizeof(fci);
2173                         fci.function_table = &ce->function_table;
2174                         fci.function_name = NULL;
2175                         fci.symbol_table = NULL;
2176                         fci.object_ptr = return_value;
2177                         fci.retval_ptr_ptr = &retval_ptr;
2178                         fci.params = NULL;
2179                         fci.param_count = 0;
2180                         fci.no_separation = 1;
2181 
2182                         if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
2183                                 if (zend_fcall_info_args(&fci, ctor_params TSRMLS_CC) == FAILURE) {
2184                                         /* Two problems why we throw exceptions here: PHP is typeless
2185                                          * and hence passing one argument that's not an array could be
2186                                          * by mistake and the other way round is possible, too. The
2187                                          * single value is an array. Also we'd have to make that one
2188                                          * argument passed by reference.
2189                                          */
2190                                         zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
2191                                         return;
2192                                 }
2193                         }
2194 
2195                         fcc.initialized = 1;
2196                         fcc.function_handler = ce->constructor;
2197                         fcc.calling_scope = EG(scope);
2198                         fcc.called_scope = Z_OBJCE_P(return_value);
2199                         fcc.object_ptr = return_value;
2200 
2201                         if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
2202                                 zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
2203                         } else {
2204                                 if (retval_ptr) {
2205                                         zval_ptr_dtor(&retval_ptr);
2206                                 }
2207                         }
2208                         if (fci.params) {
2209                                 efree(fci.params);
2210                         }
2211                 } else if (ctor_params) {
2212                         zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
2213                 }
2214         }
2215 #endif
2216 
2217 }
2218 /* }}} */
2219 
2220 /* {{{ proto array mysql_fetch_row(resource result)
2221    Gets a result row as an enumerated array */
2222 PHP_FUNCTION(mysql_fetch_row)
2223 {
2224         php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0);
2225 }
2226 /* }}} */
2227 
2228 
2229 /* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])
2230    Fetch a result row as an object */
2231 PHP_FUNCTION(mysql_fetch_object)
2232 {
2233         php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1);
2234 
2235         if (Z_TYPE_P(return_value) == IS_ARRAY) {
2236                 object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
2237         }
2238 }
2239 /* }}} */
2240 
2241 
2242 /* {{{ proto array mysql_fetch_array(resource result [, int result_type])
2243    Fetch a result row as an array (associative, numeric or both) */
2244 PHP_FUNCTION(mysql_fetch_array)
2245 {
2246         php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
2247 }
2248 /* }}} */
2249 
2250 
2251 /* {{{ proto array mysql_fetch_assoc(resource result)
2252    Fetch a result row as an associative array */
2253 PHP_FUNCTION(mysql_fetch_assoc)
2254 {
2255         php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0);
2256 }
2257 /* }}} */
2258 
2259 /* {{{ proto bool mysql_data_seek(resource result, int row_number)
2260    Move internal result pointer */
2261 PHP_FUNCTION(mysql_data_seek)
2262 {
2263         zval *result;
2264         long offset;
2265         MYSQL_RES *mysql_result;
2266 
2267         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) {
2268                 return;
2269         }
2270 
2271         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2272 
2273         if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) {
2274                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset %ld is invalid for MySQL result index %ld (or the query data is unbuffered)", offset, Z_LVAL_P(result));
2275                 RETURN_FALSE;
2276         }
2277         mysql_data_seek(mysql_result, offset);
2278         RETURN_TRUE;
2279 }
2280 /* }}} */
2281 
2282 
2283 /* {{{ proto array mysql_fetch_lengths(resource result)
2284    Gets max data size of each column in a result */
2285 PHP_FUNCTION(mysql_fetch_lengths)
2286 {
2287         zval *result;
2288         MYSQL_RES *mysql_result;
2289         mysql_row_length_type *lengths;
2290         int num_fields;
2291         int i;
2292 
2293         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2294                 return;
2295         }
2296 
2297         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2298 
2299         if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) {
2300                 RETURN_FALSE;
2301         }
2302         array_init(return_value);
2303         num_fields = mysql_num_fields(mysql_result);
2304 
2305         for (i=0; i<num_fields; i++) {
2306                 add_index_long(return_value, i, lengths[i]);
2307         }
2308 }
2309 /* }}} */
2310 
2311 /* {{{ php_mysql_get_field_name
2312  */
2313 static char *php_mysql_get_field_name(int field_type)
2314 {
2315         switch(field_type) {
2316                 case FIELD_TYPE_STRING:
2317                 case FIELD_TYPE_VAR_STRING:
2318                         return "string";
2319                         break;
2320 #if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND)
2321                 case MYSQL_TYPE_BIT:
2322 #endif
2323 #ifdef MYSQL_HAS_TINY
2324                 case FIELD_TYPE_TINY:
2325 #endif
2326                 case FIELD_TYPE_SHORT:
2327                 case FIELD_TYPE_LONG:
2328                 case FIELD_TYPE_LONGLONG:
2329                 case FIELD_TYPE_INT24:
2330                         return "int";
2331                         break;
2332                 case FIELD_TYPE_FLOAT:
2333                 case FIELD_TYPE_DOUBLE:
2334                 case FIELD_TYPE_DECIMAL:
2335 #ifdef FIELD_TYPE_NEWDECIMAL
2336                 case FIELD_TYPE_NEWDECIMAL:
2337 #endif
2338                         return "real";
2339                         break;
2340                 case FIELD_TYPE_TIMESTAMP:
2341                         return "timestamp";
2342                         break;
2343 #ifdef MYSQL_HAS_YEAR
2344                 case FIELD_TYPE_YEAR:
2345                         return "year";
2346                         break;
2347 #endif
2348                 case FIELD_TYPE_DATE:
2349 #ifdef FIELD_TYPE_NEWDATE
2350                 case FIELD_TYPE_NEWDATE:
2351 #endif
2352                         return "date";
2353                         break;
2354                 case FIELD_TYPE_TIME:
2355                         return "time";
2356                         break;
2357                 case FIELD_TYPE_SET:
2358                         return "set";
2359                         break;
2360                 case FIELD_TYPE_ENUM:
2361                         return "enum";
2362                         break;
2363 #ifdef FIELD_TYPE_GEOMETRY
2364                 case FIELD_TYPE_GEOMETRY:
2365                         return "geometry";
2366                         break;
2367 #endif
2368                 case FIELD_TYPE_DATETIME:
2369                         return "datetime";
2370                         break;
2371                 case FIELD_TYPE_TINY_BLOB:
2372                 case FIELD_TYPE_MEDIUM_BLOB:
2373                 case FIELD_TYPE_LONG_BLOB:
2374                 case FIELD_TYPE_BLOB:
2375                         return "blob";
2376                         break;
2377                 case FIELD_TYPE_NULL:
2378                         return "null";
2379                         break;
2380                 default:
2381                         return "unknown";
2382                         break;
2383         }
2384 }
2385 /* }}} */
2386 
2387 /* {{{ proto object mysql_fetch_field(resource result [, int field_offset])
2388    Gets column information from a result and return as an object */
2389 PHP_FUNCTION(mysql_fetch_field)
2390 {
2391         zval *result;
2392         long field=0;
2393         MYSQL_RES *mysql_result;
2394         const MYSQL_FIELD *mysql_field;
2395 
2396         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) {
2397                 return;
2398         }
2399 
2400         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2401 
2402         if (ZEND_NUM_ARGS() > 1) {
2403                 if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
2404                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset");
2405                         RETURN_FALSE;
2406                 }
2407                 mysql_field_seek(mysql_result, field);
2408         }
2409         if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
2410                 RETURN_FALSE;
2411         }
2412         object_init(return_value);
2413 
2414         add_property_string(return_value, "name",(mysql_field->name?mysql_field->name:""), 1);
2415         add_property_string(return_value, "table",(mysql_field->table?mysql_field->table:""), 1);
2416         add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1);
2417         add_property_long(return_value, "max_length", mysql_field->max_length);
2418         add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
2419         add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
2420         add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
2421         add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
2422         add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0);
2423         add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0);
2424         add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1);
2425         add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
2426         add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
2427 }
2428 /* }}} */
2429 
2430 
2431 /* {{{ proto bool mysql_field_seek(resource result, int field_offset)
2432    Sets result pointer to a specific field offset */
2433 PHP_FUNCTION(mysql_field_seek)
2434 {
2435         zval *result;
2436         long offset;
2437         MYSQL_RES *mysql_result;
2438 
2439         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) {
2440                 return;
2441         }
2442         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2443 
2444         if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) {
2445                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result));
2446                 RETURN_FALSE;
2447         }
2448         mysql_field_seek(mysql_result, offset);
2449         RETURN_TRUE;
2450 }
2451 /* }}} */
2452 
2453 
2454 #define PHP_MYSQL_FIELD_NAME 1
2455 #define PHP_MYSQL_FIELD_TABLE 2
2456 #define PHP_MYSQL_FIELD_LEN 3
2457 #define PHP_MYSQL_FIELD_TYPE 4
2458 #define PHP_MYSQL_FIELD_FLAGS 5
2459 
2460 /* {{{ php_mysql_field_info
2461  */
2462 static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
2463 {
2464         zval *result;
2465         long field;
2466         MYSQL_RES *mysql_result;
2467         const MYSQL_FIELD *mysql_field = {0};
2468         char buf[512];
2469         int  len;
2470 
2471         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
2472                 return;
2473         }
2474 
2475         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2476 
2477         if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
2478                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result));
2479                 RETURN_FALSE;
2480         }
2481         mysql_field_seek(mysql_result, field);
2482         if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
2483                 RETURN_FALSE;
2484         }
2485 
2486         switch (entry_type) {
2487                 case PHP_MYSQL_FIELD_NAME:
2488                         Z_STRLEN_P(return_value) = strlen(mysql_field->name);
2489                         Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value));
2490                         Z_TYPE_P(return_value) = IS_STRING;
2491                         break;
2492                 case PHP_MYSQL_FIELD_TABLE:
2493                         Z_STRLEN_P(return_value) = strlen(mysql_field->table);
2494                         Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value));
2495                         Z_TYPE_P(return_value) = IS_STRING;
2496                         break;
2497                 case PHP_MYSQL_FIELD_LEN:
2498                         Z_LVAL_P(return_value) = mysql_field->length;
2499                         Z_TYPE_P(return_value) = IS_LONG;
2500                         break;
2501                 case PHP_MYSQL_FIELD_TYPE:
2502                         Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field));
2503                         Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
2504                         Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
2505                         Z_TYPE_P(return_value) = IS_STRING;
2506                         break;
2507                 case PHP_MYSQL_FIELD_FLAGS:
2508                         memcpy(buf, "", sizeof(""));
2509 #ifdef IS_NOT_NULL
2510                         if (IS_NOT_NULL(mysql_field->flags)) {
2511                                 strcat(buf, "not_null ");
2512                         }
2513 #endif
2514 #ifdef IS_PRI_KEY
2515                         if (IS_PRI_KEY(mysql_field->flags)) {
2516                                 strcat(buf, "primary_key ");
2517                         }
2518 #endif
2519 #ifdef UNIQUE_KEY_FLAG
2520                         if (mysql_field->flags&UNIQUE_KEY_FLAG) {
2521                                 strcat(buf, "unique_key ");
2522                         }
2523 #endif
2524 #ifdef MULTIPLE_KEY_FLAG
2525                         if (mysql_field->flags&MULTIPLE_KEY_FLAG) {
2526                                 strcat(buf, "multiple_key ");
2527                         }
2528 #endif
2529 #ifdef IS_BLOB
2530                         if (IS_BLOB(mysql_field->flags)) {
2531                                 strcat(buf, "blob ");
2532                         }
2533 #endif
2534 #ifdef UNSIGNED_FLAG
2535                         if (mysql_field->flags&UNSIGNED_FLAG) {
2536                                 strcat(buf, "unsigned ");
2537                         }
2538 #endif
2539 #ifdef ZEROFILL_FLAG
2540                         if (mysql_field->flags&ZEROFILL_FLAG) {
2541                                 strcat(buf, "zerofill ");
2542                         }
2543 #endif
2544 #ifdef BINARY_FLAG
2545                         if (mysql_field->flags&BINARY_FLAG) {
2546                                 strcat(buf, "binary ");
2547                         }
2548 #endif
2549 #ifdef ENUM_FLAG
2550                         if (mysql_field->flags&ENUM_FLAG) {
2551                                 strcat(buf, "enum ");
2552                         }
2553 #endif
2554 #ifdef SET_FLAG
2555                         if (mysql_field->flags&SET_FLAG) {
2556                                 strcat(buf, "set ");
2557                         }
2558 #endif
2559 #ifdef AUTO_INCREMENT_FLAG
2560                         if (mysql_field->flags&AUTO_INCREMENT_FLAG) {
2561                                 strcat(buf, "auto_increment ");
2562                         }
2563 #endif
2564 #ifdef TIMESTAMP_FLAG
2565                         if (mysql_field->flags&TIMESTAMP_FLAG) {
2566                                 strcat(buf, "timestamp ");
2567                         }
2568 #endif
2569                         len = strlen(buf);
2570                         /* remove trailing space, if present */
2571                         if (len && buf[len-1] == ' ') {
2572                                 buf[len-1] = 0;
2573                                 len--;
2574                         }
2575 
2576                         Z_STRLEN_P(return_value) = len;
2577                         Z_STRVAL_P(return_value) = estrndup(buf, len);
2578                         Z_TYPE_P(return_value) = IS_STRING;
2579                         break;
2580 
2581                 default:
2582                         RETURN_FALSE;
2583         }
2584 }
2585 /* }}} */
2586 
2587 /* {{{ proto string mysql_field_name(resource result, int field_index)
2588    Gets the name of the specified field in a result */
2589 PHP_FUNCTION(mysql_field_name)
2590 {
2591         php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME);
2592 }
2593 /* }}} */
2594 
2595 
2596 /* {{{ proto string mysql_field_table(resource result, int field_offset)
2597    Gets name of the table the specified field is in */
2598 PHP_FUNCTION(mysql_field_table)
2599 {
2600         php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE);
2601 }
2602 /* }}} */
2603 
2604 
2605 /* {{{ proto int mysql_field_len(resource result, int field_offset)
2606    Returns the length of the specified field */
2607 PHP_FUNCTION(mysql_field_len)
2608 {
2609         php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN);
2610 }
2611 /* }}} */
2612 
2613 
2614 /* {{{ proto string mysql_field_type(resource result, int field_offset)
2615    Gets the type of the specified field in a result */
2616 PHP_FUNCTION(mysql_field_type)
2617 {
2618         php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE);
2619 }
2620 /* }}} */
2621 
2622 
2623 /* {{{ proto string mysql_field_flags(resource result, int field_offset)
2624    Gets the flags associated with the specified field in a result */
2625 PHP_FUNCTION(mysql_field_flags)
2626 {
2627         php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS);
2628 }
2629 /* }}} */
2630 
2631 
2632 /* {{{ proto bool mysql_free_result(resource result)
2633    Free result memory */
2634 PHP_FUNCTION(mysql_free_result)
2635 {
2636         zval *result;
2637         MYSQL_RES *mysql_result;
2638 
2639         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2640                 return;
2641         }
2642 
2643         if (Z_LVAL_P(result)==0) {
2644                 RETURN_FALSE;
2645         }
2646 
2647         ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2648 
2649         zend_list_delete(Z_LVAL_P(result));
2650         RETURN_TRUE;
2651 }
2652 /* }}} */
2653 
2654 /* {{{ proto bool mysql_ping([int link_identifier])
2655    Ping a server connection. If no connection then reconnect. */
2656 PHP_FUNCTION(mysql_ping)
2657 {
2658         zval           *mysql_link = NULL;
2659         int             id         = -1;
2660         php_mysql_conn *mysql;
2661 
2662         if (0 == ZEND_NUM_ARGS()) {
2663                 id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
2664                 CHECK_LINK(id);
2665         } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) {
2666                 return;
2667         }
2668 
2669         ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
2670 
2671         PHPMY_UNBUFFERED_QUERY_CHECK();
2672 
2673         RETURN_BOOL(! mysql_ping(mysql->conn));
2674 }
2675 /* }}} */
2676 
2677 #endif
2678 
2679 /*
2680  * Local variables:
2681  * tab-width: 4
2682  * c-basic-offset: 4
2683  * End:
2684  * vim600: sw=4 ts=4 fdm=marker
2685  * vim<600: sw=4 ts=4
2686  */

/* [<][>][^][v][top][bottom][index][help] */