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