Annotation of embedaddon/php/ext/mysql/php_mysql.c, revision 1.1.1.5
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.5 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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:
1.1.1.2 misho 21: /* $Id$ */
1.1 misho 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)
1.1.1.2 misho 255: PHP_DEP_FE(mysql_list_dbs, arginfo__optional_mysql_link)
1.1 misho 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
1.1.1.4 misho 299: /* for downwards compatibility */
1.1 misho 300: PHP_FALIAS(mysql, mysql_db_query, arginfo_mysql_db_query)
301: PHP_FALIAS(mysql_fieldname, mysql_field_name, arginfo_mysql_field_name)
302: PHP_FALIAS(mysql_fieldtable, mysql_field_table, arginfo_mysql_field_seek)
303: PHP_FALIAS(mysql_fieldlen, mysql_field_len, arginfo_mysql_field_seek)
304: PHP_FALIAS(mysql_fieldtype, mysql_field_type, arginfo_mysql_field_seek)
305: PHP_FALIAS(mysql_fieldflags, mysql_field_flags, arginfo_mysql_field_seek)
306: PHP_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_FALIAS(mysql_freeresult, mysql_free_result, arginfo__result_mysql_arg)
314: PHP_FALIAS(mysql_numfields, mysql_num_fields, arginfo__result_mysql_arg)
315: PHP_FALIAS(mysql_numrows, mysql_num_rows, arginfo__result_mysql_arg)
316: PHP_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_FALIAS(mysql_listfields, mysql_list_fields, arginfo_mysql_list_fields)
319: PHP_FALIAS(mysql_db_name, mysql_result, arginfo_mysql_result)
320: PHP_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:
1.1.1.2 misho 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:
1.1 misho 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:
1.1.1.2 misho 586: #ifdef MYSQL_USE_MYSQLND
587: mysqlnd_reverse_api_register_api(&mysql_reverse_api TSRMLS_CC);
588: #endif
589:
1.1 misho 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;
1.1.1.3 misho 723: int user_len = 0, passwd_len = 0, host_len = 0;
1.1 misho 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: #if !defined(MYSQL_USE_MYSQLND)
735: if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
736: php_error_docref(NULL TSRMLS_CC, E_WARNING,
737: "Headers and client library minor version mismatch. Headers:%d Library:%ld",
738: MYSQL_VERSION_ID, mysql_get_client_version());
739: }
740: #endif
741:
742: connect_timeout = MySG(connect_timeout);
743:
744: socket = MySG(default_socket);
745:
746: if (MySG(default_port) < 0) {
747: #if !defined(PHP_WIN32) && !defined(NETWARE)
748: struct servent *serv_ptr;
749: char *env;
750:
751: MySG(default_port) = MYSQL_PORT;
752: if ((serv_ptr = getservbyname("mysql", "tcp"))) {
753: MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
754: }
755: if ((env = getenv("MYSQL_TCP_PORT"))) {
756: MySG(default_port) = (uint) atoi(env);
757: }
758: #else
759: MySG(default_port) = MYSQL_PORT;
760: #endif
761: }
762:
763: if (PG(sql_safe_mode)) {
764: if (ZEND_NUM_ARGS()>0) {
765: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
766: }
767: host_and_port=passwd=NULL;
1.1.1.2 misho 768: user=php_get_current_user(TSRMLS_C);
1.1 misho 769: hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user);
770: client_flags = CLIENT_INTERACTIVE;
771: } else {
772: /* mysql_pconnect does not support new_link parameter */
773: if (persistent) {
774: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len,
775: &user, &user_len, &passwd, &passwd_len,
776: &client_flags)==FAILURE) {
777: return;
778: }
779: } else {
780: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len,
781: &user, &user_len, &passwd, &passwd_len,
782: &new_link, &client_flags)==FAILURE) {
783: return;
784: }
785: }
786:
787: if (!host_and_port) {
788: host_and_port = MySG(default_host);
789: }
790: if (!user) {
791: user = MySG(default_user);
792: }
793: if (!passwd) {
794: passwd = MySG(default_password);
795: passwd_len = passwd? strlen(passwd):0;
796: }
797:
798: /* disable local infile option for open_basedir */
799: #if PHP_API_VERSION < 20100412
800: if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
801: #else
802: if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) {
803: #endif
804: client_flags ^= CLIENT_LOCAL_FILES;
805: }
806:
807: #ifdef CLIENT_MULTI_RESULTS
808: client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
809: #endif
810: #ifdef CLIENT_MULTI_STATEMENTS
811: client_flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
812: #endif
813: 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);
814: }
815:
816: /* We cannot use mysql_port anymore in windows, need to use
817: * mysql_real_connect() to set the port.
818: */
819: if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
820: host = estrndup(host_and_port, tmp-host_and_port);
821: free_host = 1;
822: tmp++;
823: if (tmp[0] != '/') {
824: port = atoi(tmp);
825: if ((tmp=strchr(tmp, ':'))) {
826: tmp++;
827: socket=tmp;
828: }
829: } else {
830: socket = tmp;
831: }
832: } else {
833: host = host_and_port;
834: port = MySG(default_port);
835: }
836:
837: #if MYSQL_VERSION_ID < 32200
838: mysql_port = port;
839: #endif
840:
841: if (!MySG(allow_persistent)) {
842: persistent=0;
843: }
844: if (persistent) {
845: zend_rsrc_list_entry *le;
846:
847: /* try to find if we already have this link in our persistent list */
848: if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */
849: zend_rsrc_list_entry new_le;
850:
851: if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
852: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
853: efree(hashed_details);
854: MYSQL_DO_CONNECT_RETURN_FALSE();
855: }
856: if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) {
857: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
858: efree(hashed_details);
859: MYSQL_DO_CONNECT_RETURN_FALSE();
860: }
861: /* create the link */
862: mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
863: if (!mysql) {
864: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link");
865: }
866: mysql->active_result_id = 0;
867: #ifdef CLIENT_MULTI_STATEMENTS
868: mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
869: #else
870: mysql->multi_query = 0;
871: #endif
872:
873: #ifndef MYSQL_USE_MYSQLND
874: mysql->conn = mysql_init(NULL);
875: #else
876: mysql->conn = mysql_init(persistent);
877: #endif
878:
879: if (connect_timeout != -1) {
880: mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
881: }
882: #ifndef MYSQL_USE_MYSQLND
883: if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
884: #else
885: if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
886: #endif
887: {
888: /* Populate connect error globals so that the error functions can read them */
889: if (MySG(connect_error) != NULL) {
890: efree(MySG(connect_error));
891: }
892: MySG(connect_error) = estrdup(mysql_error(mysql->conn));
893: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
894: #if defined(HAVE_MYSQL_ERRNO)
895: MySG(connect_errno) = mysql_errno(mysql->conn);
896: #endif
897: free(mysql);
898: efree(hashed_details);
899: MYSQL_DO_CONNECT_RETURN_FALSE();
900: }
901: mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
902:
903: /* hash it up */
904: Z_TYPE(new_le) = le_plink;
905: new_le.ptr = mysql;
906: if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
907: free(mysql);
908: efree(hashed_details);
909: MYSQL_DO_CONNECT_RETURN_FALSE();
910: }
911: MySG(num_persistent)++;
912: MySG(num_links)++;
913: } else { /* The link is in our list of persistent connections */
914: if (Z_TYPE_P(le) != le_plink) {
915: MYSQL_DO_CONNECT_RETURN_FALSE();
916: }
917: mysql = (php_mysql_conn *) le->ptr;
918: mysql->active_result_id = 0;
919: #ifdef CLIENT_MULTI_STATEMENTS
920: mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
921: #else
922: mysql->multi_query = 0;
923: #endif
924: /* ensure that the link did not die */
925: #if defined(A0) && MYSQL_USE_MYSQLND
926: mysqlnd_end_psession(mysql->conn);
927: #endif
928: if (mysql_ping(mysql->conn)) {
929: if (mysql_errno(mysql->conn) == 2006) {
930: #ifndef MYSQL_USE_MYSQLND
931: if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
932: #else
933: if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
934: #endif
935: {
936: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
937: zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
938: efree(hashed_details);
939: MYSQL_DO_CONNECT_RETURN_FALSE();
940: }
941: mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
942: }
943: } else {
944: #ifdef MYSQL_USE_MYSQLND
945: mysqlnd_restart_psession(mysql->conn);
946: #endif
947: }
948: }
949: ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
950: } else { /* non persistent */
951: zend_rsrc_list_entry *index_ptr, new_index_ptr;
952:
953: /* first we check the hash for the hashed_details key. if it exists,
954: * it should point us to the right offset where the actual mysql link sits.
955: * if it doesn't, open a new mysql link, add it to the resource list,
956: * and add a pointer to it with hashed_details as the key.
957: */
958: if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
959: int type;
960: long link;
961: void *ptr;
962:
963: if (Z_TYPE_P(index_ptr) != le_index_ptr) {
964: MYSQL_DO_CONNECT_RETURN_FALSE();
965: }
966: link = (long) index_ptr->ptr;
967: ptr = zend_list_find(link,&type); /* check if the link is still there */
968: if (ptr && (type==le_link || type==le_plink)) {
969: zend_list_addref(link);
970: Z_LVAL_P(return_value) = link;
971: php_mysql_set_default_link(link TSRMLS_CC);
972: Z_TYPE_P(return_value) = IS_RESOURCE;
973: efree(hashed_details);
974: MYSQL_DO_CONNECT_CLEANUP();
975: return;
976: } else {
977: zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
978: }
979: }
980: if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
981: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
982: efree(hashed_details);
983: MYSQL_DO_CONNECT_RETURN_FALSE();
984: }
985:
986: mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
987: mysql->active_result_id = 0;
988: #ifdef CLIENT_MULTI_STATEMENTS
989: mysql->multi_query = 1;
990: #endif
991:
992: #ifndef MYSQL_USE_MYSQLND
993: mysql->conn = mysql_init(NULL);
994: #else
995: mysql->conn = mysql_init(persistent);
996: #endif
997: if (!mysql->conn) {
998: MySG(connect_error) = estrdup("OOM");
999: php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM");
1000: efree(hashed_details);
1001: efree(mysql);
1002: MYSQL_DO_CONNECT_RETURN_FALSE();
1003: }
1004:
1005: if (connect_timeout != -1) {
1006: mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
1007: }
1008:
1009: #ifndef MYSQL_USE_MYSQLND
1010: if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
1011: #else
1012: if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
1013: #endif
1014: {
1015: /* Populate connect error globals so that the error functions can read them */
1016: if (MySG(connect_error) != NULL) {
1017: efree(MySG(connect_error));
1018: }
1019: MySG(connect_error) = estrdup(mysql_error(mysql->conn));
1020: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
1021: #if defined(HAVE_MYSQL_ERRNO)
1022: MySG(connect_errno) = mysql_errno(mysql->conn);
1023: #endif
1024: /* free mysql structure */
1025: #ifdef MYSQL_USE_MYSQLND
1026: mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED);
1027: #endif
1028: efree(hashed_details);
1029: efree(mysql);
1030: MYSQL_DO_CONNECT_RETURN_FALSE();
1031: }
1032: mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
1033:
1034: /* add it to the list */
1035: ZEND_REGISTER_RESOURCE(return_value, mysql, le_link);
1036:
1037: /* add it to the hash */
1038: new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
1039: Z_TYPE(new_index_ptr) = le_index_ptr;
1040: if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
1041: efree(hashed_details);
1042: MYSQL_DO_CONNECT_RETURN_FALSE();
1043: }
1044: MySG(num_links)++;
1045: }
1046:
1047: efree(hashed_details);
1048: php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
1049: MYSQL_DO_CONNECT_CLEANUP();
1050: }
1051: /* }}} */
1052:
1053: /* {{{ php_mysql_get_default_link
1054: */
1055: static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
1056: {
1057: if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */
1058: ht = 0;
1059: php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1060: }
1061: return MySG(default_link);
1062: }
1063: /* }}} */
1064:
1065: /* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])
1066: Opens a connection to a MySQL Server */
1067: PHP_FUNCTION(mysql_connect)
1068: {
1069: php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1070: }
1071: /* }}} */
1072:
1073: /* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])
1074: Opens a persistent connection to a MySQL Server */
1075: PHP_FUNCTION(mysql_pconnect)
1076: {
1077: php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1078: }
1079: /* }}} */
1080:
1081: /* {{{ proto bool mysql_close([int link_identifier])
1082: Close a MySQL connection */
1083: PHP_FUNCTION(mysql_close)
1084: {
1085: int resource_id;
1086: zval *mysql_link=NULL;
1087: php_mysql_conn *mysql;
1088:
1089: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1090: return;
1091: }
1092:
1093: if (mysql_link) {
1094: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink);
1095: } else {
1096: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink);
1097: }
1098:
1099: resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link);
1100: PHPMY_UNBUFFERED_QUERY_CHECK();
1101: #ifdef MYSQL_USE_MYSQLND
1102: {
1103: int tmp;
1104: if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) {
1105: mysqlnd_end_psession(mysql->conn);
1106: }
1107: }
1108: #endif
1109: zend_list_delete(resource_id);
1110:
1111: if (!mysql_link
1112: || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) {
1113: MySG(default_link) = -1;
1114: if (mysql_link) {
1115: /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */
1116: zend_list_delete(resource_id);
1117: }
1118: }
1119:
1120: RETURN_TRUE;
1121: }
1122: /* }}} */
1123:
1124: /* {{{ proto bool mysql_select_db(string database_name [, int link_identifier])
1125: Selects a MySQL database */
1126: PHP_FUNCTION(mysql_select_db)
1127: {
1128: char *db;
1129: int db_len;
1130: zval *mysql_link = NULL;
1131: int id = -1;
1132: php_mysql_conn *mysql;
1133:
1134: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1135: return;
1136: }
1137:
1138: if (!mysql_link) {
1139: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1140: CHECK_LINK(id);
1141: }
1142:
1143: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1144:
1145: if (php_mysql_select_db(mysql, db TSRMLS_CC)) {
1146: RETURN_TRUE;
1147: } else {
1148: RETURN_FALSE;
1149: }
1150: }
1151: /* }}} */
1152:
1153: #ifdef HAVE_GETINFO_FUNCS
1154:
1155: /* {{{ proto string mysql_get_client_info(void)
1156: Returns a string that represents the client library version */
1157: PHP_FUNCTION(mysql_get_client_info)
1158: {
1159: if (zend_parse_parameters_none() == FAILURE) {
1160: return;
1161: }
1162:
1163: RETURN_STRING((char *)mysql_get_client_info(),1);
1164: }
1165: /* }}} */
1166:
1167: /* {{{ proto string mysql_get_host_info([int link_identifier])
1168: Returns a string describing the type of connection in use, including the server host name */
1169: PHP_FUNCTION(mysql_get_host_info)
1170: {
1171: zval *mysql_link = NULL;
1172: int id = -1;
1173: php_mysql_conn *mysql;
1174:
1175: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1176: return;
1177: }
1178:
1179: if (!mysql_link) {
1180: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1181: CHECK_LINK(id);
1182: }
1183:
1184: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1185:
1186: RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1);
1187: }
1188: /* }}} */
1189:
1190: /* {{{ proto int mysql_get_proto_info([int link_identifier])
1191: Returns the protocol version used by current connection */
1192: PHP_FUNCTION(mysql_get_proto_info)
1193: {
1194: zval *mysql_link = NULL;
1195: int id = -1;
1196: php_mysql_conn *mysql;
1197:
1198: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1199: return;
1200: }
1201:
1202: if (!mysql_link) {
1203: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1204: CHECK_LINK(id);
1205: }
1206:
1207: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1208:
1209: RETURN_LONG(mysql_get_proto_info(mysql->conn));
1210: }
1211: /* }}} */
1212:
1213: /* {{{ proto string mysql_get_server_info([int link_identifier])
1214: Returns a string that represents the server version number */
1215: PHP_FUNCTION(mysql_get_server_info)
1216: {
1217: zval *mysql_link = NULL;
1218: int id = -1;
1219: php_mysql_conn *mysql;
1220:
1221: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1222: return;
1223: }
1224:
1225: if (!mysql_link) {
1226: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1227: CHECK_LINK(id);
1228: }
1229:
1230: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1231:
1232: RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1);
1233: }
1234: /* }}} */
1235:
1236: /* {{{ proto string mysql_info([int link_identifier])
1237: Returns a string containing information about the most recent query */
1238: PHP_FUNCTION(mysql_info)
1239: {
1240: zval *mysql_link = NULL;
1241: int id = -1;
1242: char *str;
1243: php_mysql_conn *mysql;
1244:
1245: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1246: return;
1247: }
1248:
1249: if (ZEND_NUM_ARGS() == 0) {
1250: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1251: CHECK_LINK(id);
1252: }
1253:
1254: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1255:
1256: if ((str = (char *)mysql_info(mysql->conn))) {
1257: RETURN_STRING(str,1);
1258: } else {
1259: RETURN_FALSE;
1260: }
1261: }
1262: /* }}} */
1263:
1264: /* {{{ proto int mysql_thread_id([int link_identifier])
1265: Returns the thread id of current connection */
1266: PHP_FUNCTION(mysql_thread_id)
1267: {
1268: zval *mysql_link = NULL;
1269: int id = -1;
1270: php_mysql_conn *mysql;
1271:
1272: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1273: return;
1274: }
1275:
1276: if (ZEND_NUM_ARGS() == 0) {
1277: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1278: CHECK_LINK(id);
1279: }
1280: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1281:
1282: RETURN_LONG((long) mysql_thread_id(mysql->conn));
1283: }
1284: /* }}} */
1285:
1286: /* {{{ proto string mysql_stat([int link_identifier])
1287: Returns a string containing status information */
1288: PHP_FUNCTION(mysql_stat)
1289: {
1290: zval *mysql_link = NULL;
1291: int id = -1;
1292: php_mysql_conn *mysql;
1293: char *stat;
1294: #ifdef MYSQL_USE_MYSQLND
1295: uint stat_len;
1296: #endif
1297:
1298: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1299: return;
1300: }
1301:
1302: if (ZEND_NUM_ARGS() == 0) {
1303: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1304: CHECK_LINK(id);
1305: }
1306: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1307:
1308: PHPMY_UNBUFFERED_QUERY_CHECK();
1309: #ifndef MYSQL_USE_MYSQLND
1310: if ((stat = (char *)mysql_stat(mysql->conn))) {
1311: RETURN_STRING(stat, 1);
1312: #else
1313: if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) {
1314: RETURN_STRINGL(stat, stat_len, 0);
1315: #endif
1316: } else {
1317: RETURN_FALSE;
1318: }
1319: }
1320: /* }}} */
1321:
1322: /* {{{ proto string mysql_client_encoding([int link_identifier])
1323: Returns the default character set for the current connection */
1324: PHP_FUNCTION(mysql_client_encoding)
1325: {
1326: zval *mysql_link = NULL;
1327: int id = -1;
1328: php_mysql_conn *mysql;
1329:
1330: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1331: return;
1332: }
1333:
1334: if (ZEND_NUM_ARGS() == 0) {
1335: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1336: CHECK_LINK(id);
1337: }
1338:
1339: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1340: RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1);
1341: }
1342: /* }}} */
1343: #endif
1344:
1345: #ifdef MYSQL_HAS_SET_CHARSET
1346: /* {{{ proto bool mysql_set_charset(string csname [, int link_identifier])
1347: sets client character set */
1348: PHP_FUNCTION(mysql_set_charset)
1349: {
1350: zval *mysql_link = NULL;
1351: char *csname;
1352: int id = -1, csname_len;
1353: php_mysql_conn *mysql;
1354:
1355: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
1356: return;
1357: }
1358:
1359: if (ZEND_NUM_ARGS() == 1) {
1360: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1361: CHECK_LINK(id);
1362: }
1363:
1364: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1365:
1366: if (!mysql_set_character_set(mysql->conn, csname)) {
1367: RETURN_TRUE;
1368: } else {
1369: RETURN_FALSE;
1370: }
1371: }
1372: /* }}} */
1373: #endif
1374:
1375: #ifndef NETWARE /* The below two functions not supported on NetWare */
1376: #if MYSQL_VERSION_ID < 40000
1377: /* {{{ proto bool mysql_create_db(string database_name [, int link_identifier])
1378: Create a MySQL database */
1379: PHP_FUNCTION(mysql_create_db)
1380: {
1381: char *db;
1382: int db_len;
1383: zval *mysql_link = NULL;
1384: int id = -1;
1385: php_mysql_conn *mysql;
1386:
1387: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1388: return;
1389: }
1390:
1391: if (!mysql_link) {
1392: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1393: CHECK_LINK(id);
1394: }
1395:
1396: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1397:
1398: PHPMY_UNBUFFERED_QUERY_CHECK();
1399:
1400: if (mysql_create_db(mysql->conn, db)==0) {
1401: RETURN_TRUE;
1402: } else {
1403: RETURN_FALSE;
1404: }
1405: }
1406: /* }}} */
1407:
1408: /* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier])
1409: Drops (delete) a MySQL database */
1410: PHP_FUNCTION(mysql_drop_db)
1411: {
1412: char *db;
1413: int db_len;
1414: zval *mysql_link = NULL;
1415: int id = -1;
1416: php_mysql_conn *mysql;
1417:
1418: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1419: return;
1420: }
1421:
1422: if (!mysql_link) {
1423: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1424: CHECK_LINK(id);
1425: }
1426:
1427: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1428:
1429: if (mysql_drop_db(mysql->conn, db)==0) {
1430: RETURN_TRUE;
1431: } else {
1432: RETURN_FALSE;
1433: }
1434: }
1435: /* }}} */
1436: #endif
1437: #endif /* NETWARE */
1438:
1439: /* {{{ php_mysql_do_query_general
1440: */
1441: 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)
1442: {
1443: php_mysql_conn *mysql;
1444: MYSQL_RES *mysql_result;
1445:
1446: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink);
1447:
1448: if (db) {
1449: if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1450: RETURN_FALSE;
1451: }
1452: }
1453:
1454: PHPMY_UNBUFFERED_QUERY_CHECK();
1455:
1456: MYSQL_DISABLE_MQ;
1457:
1458: #ifndef MYSQL_USE_MYSQLND
1459: /* check explain */
1460: if (MySG(trace_mode)) {
1461: if (!strncasecmp("select", query, 6)){
1462: MYSQL_ROW row;
1463:
1464: char *newquery;
1465: int newql = spprintf (&newquery, 0, "EXPLAIN %s", query);
1466: mysql_real_query(mysql->conn, newquery, newql);
1467: efree (newquery);
1468: if (mysql_errno(mysql->conn)) {
1469: php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1470: RETURN_FALSE;
1471: }
1472: else {
1473: mysql_result = mysql_use_result(mysql->conn);
1474: while ((row = mysql_fetch_row(mysql_result))) {
1475: if (!strcmp("ALL", row[1])) {
1476: 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]);
1477: } else if (!strcmp("INDEX", row[1])) {
1478: 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]);
1479: }
1480: }
1481: mysql_free_result(mysql_result);
1482: }
1483: }
1484: } /* end explain */
1485: #endif
1486:
1487: /* mysql_query is binary unsafe, use mysql_real_query */
1488: #if MYSQL_VERSION_ID > 32199
1489: if (mysql_real_query(mysql->conn, query, query_len)!=0) {
1490: /* check possible error */
1491: if (MySG(trace_mode)){
1492: if (mysql_errno(mysql->conn)){
1493: php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1494: }
1495: }
1496: RETURN_FALSE;
1497: }
1498: #else
1499: if (mysql_query(mysql->conn, query)!=0) {
1500: /* check possible error */
1501: if (MySG(trace_mode)){
1502: if (mysql_errno(mysql->conn)){
1503: php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
1504: }
1505: }
1506: RETURN_FALSE;
1507: }
1508: #endif
1509: if(use_store == MYSQL_USE_RESULT) {
1510: mysql_result=mysql_use_result(mysql->conn);
1511: } else {
1512: mysql_result=mysql_store_result(mysql->conn);
1513: }
1514: if (!mysql_result) {
1515: if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
1516: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
1517: RETURN_FALSE;
1518: } else {
1519: RETURN_TRUE;
1520: }
1521: }
1522: MySG(result_allocated)++;
1523: ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1524: if (use_store == MYSQL_USE_RESULT) {
1525: mysql->active_result_id = Z_LVAL_P(return_value);
1526: }
1527: }
1528: /* }}} */
1529:
1530: /* {{{ php_mysql_do_query
1531: */
1532: static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store)
1533: {
1534: char *query;
1535: int query_len;
1536: zval *mysql_link = NULL;
1537: int id = -1;
1538:
1539: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) {
1540: return;
1541: }
1542:
1543: if (!mysql_link) {
1544: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1545: CHECK_LINK(id);
1546: }
1547:
1548: php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC);
1549: }
1550: /* }}} */
1551:
1552: /* {{{ proto resource mysql_query(string query [, int link_identifier])
1553: Sends an SQL query to MySQL */
1554: PHP_FUNCTION(mysql_query)
1555: {
1556: php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
1557: }
1558: /* }}} */
1559:
1560:
1561: /* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
1562: Sends an SQL query to MySQL, without fetching and buffering the result rows */
1563: PHP_FUNCTION(mysql_unbuffered_query)
1564: {
1565: php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
1566: }
1567: /* }}} */
1568:
1569:
1570: /* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier])
1571: Sends an SQL query to MySQL */
1572: PHP_FUNCTION(mysql_db_query)
1573: {
1574: char *db, *query;
1575: int db_len, query_len;
1576: zval *mysql_link = NULL;
1577: int id = -1;
1578:
1579: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) {
1580: return;
1581: }
1582:
1583: if (!mysql_link) {
1584: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1585: CHECK_LINK(id);
1586: }
1587:
1588: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead");
1589:
1590: php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC);
1591: }
1592: /* }}} */
1593:
1594:
1595: /* {{{ proto resource mysql_list_dbs([int link_identifier])
1596: List databases available on a MySQL server */
1597: PHP_FUNCTION(mysql_list_dbs)
1598: {
1599: zval *mysql_link = NULL;
1600: int id = -1;
1601: php_mysql_conn *mysql;
1602: MYSQL_RES *mysql_result;
1603:
1604: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1605: return;
1606: }
1607:
1608: if (!mysql_link) {
1609: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1610: CHECK_LINK(id);
1611: }
1.1.1.2 misho 1612: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() with SHOW DATABASES instead");
1.1 misho 1613:
1614: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1615:
1616: PHPMY_UNBUFFERED_QUERY_CHECK();
1617:
1.1.1.2 misho 1618:
1.1 misho 1619: if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) {
1620: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1621: RETURN_FALSE;
1622: }
1623: MySG(result_allocated)++;
1624: ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1625: }
1626: /* }}} */
1627:
1628:
1629: /* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier])
1630: List tables in a MySQL database */
1631: PHP_FUNCTION(mysql_list_tables)
1632: {
1633: char *db;
1634: int db_len;
1635: zval *mysql_link = NULL;
1636: int id = -1;
1637: php_mysql_conn *mysql;
1638: MYSQL_RES *mysql_result;
1639:
1640: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
1641: return;
1642: }
1643:
1644: if (!mysql_link) {
1645: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1646: CHECK_LINK(id);
1647: }
1648:
1649: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1650:
1651: if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1652: RETURN_FALSE;
1653: }
1654:
1655: PHPMY_UNBUFFERED_QUERY_CHECK();
1656:
1657: if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) {
1658: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1659: RETURN_FALSE;
1660: }
1661: MySG(result_allocated)++;
1662: ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1663: }
1664: /* }}} */
1665:
1666:
1667: /* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier])
1668: List MySQL result fields */
1669: PHP_FUNCTION(mysql_list_fields)
1670: {
1671: char *db, *table;
1672: int db_len, table_len;
1673: zval *mysql_link = NULL;
1674: int id = -1;
1675: php_mysql_conn *mysql;
1676: MYSQL_RES *mysql_result;
1677:
1678: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) {
1679: return;
1680: }
1681:
1682: if (!mysql_link) {
1683: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1684: CHECK_LINK(id);
1685: }
1686:
1687: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1688:
1689: if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
1690: RETURN_FALSE;
1691: }
1692:
1693: PHPMY_UNBUFFERED_QUERY_CHECK();
1694:
1695: if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) {
1696: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1697: RETURN_FALSE;
1698: }
1699: MySG(result_allocated)++;
1700: ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1701: }
1702: /* }}} */
1703:
1704: /* {{{ proto resource mysql_list_processes([int link_identifier])
1705: Returns a result set describing the current server threads */
1706: PHP_FUNCTION(mysql_list_processes)
1707: {
1708: zval *mysql_link = NULL;
1709: int id = -1;
1710: php_mysql_conn *mysql;
1711: MYSQL_RES *mysql_result;
1712:
1713: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1714: return;
1715: }
1716:
1717: if (ZEND_NUM_ARGS() == 0) {
1718: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1719: CHECK_LINK(id);
1720: }
1721:
1722: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1723:
1724: PHPMY_UNBUFFERED_QUERY_CHECK();
1725:
1726: mysql_result = mysql_list_processes(mysql->conn);
1727: if (mysql_result == NULL) {
1728: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
1729: RETURN_FALSE;
1730: }
1731:
1732: MySG(result_allocated)++;
1733: ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
1734: }
1735: /* }}} */
1736:
1737:
1738: /* {{{ proto string mysql_error([int link_identifier])
1739: Returns the text of the error message from previous MySQL operation */
1740: PHP_FUNCTION(mysql_error)
1741: {
1742: zval *mysql_link = NULL;
1743: int id = -1;
1744: php_mysql_conn *mysql;
1745:
1746: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1747: return;
1748: }
1749:
1750: if (!mysql_link) {
1751: id = MySG(default_link);
1752: if (id==-1) {
1753: if (MySG(connect_error)!=NULL){
1754: RETURN_STRING(MySG(connect_error),1);
1755: } else {
1756: RETURN_FALSE;
1757: }
1758: }
1759: }
1760:
1761: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1762:
1763: RETURN_STRING((char *)mysql_error(mysql->conn), 1);
1764: }
1765: /* }}} */
1766:
1767:
1768: /* {{{ proto int mysql_errno([int link_identifier])
1769: Returns the number of the error message from previous MySQL operation */
1770: #ifdef HAVE_MYSQL_ERRNO
1771: PHP_FUNCTION(mysql_errno)
1772: {
1773: zval *mysql_link = NULL;
1774: int id = -1;
1775: php_mysql_conn *mysql;
1776:
1777: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1778: return;
1779: }
1780:
1781: if (!mysql_link) {
1782: id = MySG(default_link);
1783: if (id==-1) {
1784: if (MySG(connect_errno)!=0){
1785: RETURN_LONG(MySG(connect_errno));
1786: } else {
1787: RETURN_FALSE;
1788: }
1789: }
1790: }
1791:
1792: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1793:
1794: RETURN_LONG(mysql_errno(mysql->conn));
1795: }
1796: #endif
1797: /* }}} */
1798:
1799:
1800: /* {{{ proto int mysql_affected_rows([int link_identifier])
1801: Gets number of affected rows in previous MySQL operation */
1802: PHP_FUNCTION(mysql_affected_rows)
1803: {
1804: zval *mysql_link = NULL;
1805: int id = -1;
1806: php_mysql_conn *mysql;
1807:
1808: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1809: return;
1810: }
1811:
1812: if (!mysql_link) {
1813: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1814: CHECK_LINK(id);
1815: }
1816:
1817: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1818:
1819: /* conversion from int64 to long happing here */
1820: Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn);
1821: Z_TYPE_P(return_value) = IS_LONG;
1822: }
1823: /* }}} */
1824:
1825:
1826: /* {{{ proto string mysql_escape_string(string to_be_escaped)
1827: Escape string for mysql query */
1828: PHP_FUNCTION(mysql_escape_string)
1829: {
1830: char *str;
1831: int str_len;
1832:
1833: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1834: return;
1835: }
1836:
1837: /* assume worst case situation, which is 2x of the original string.
1838: * we don't realloc() down to the real size since it'd most probably not
1839: * be worth it
1840: */
1841:
1842: Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1);
1843: Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len);
1844: Z_TYPE_P(return_value) = IS_STRING;
1845:
1.1.1.2 misho 1846: php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead.");
1.1 misho 1847: }
1848: /* }}} */
1849:
1850: /* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier])
1851: Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
1852: PHP_FUNCTION(mysql_real_escape_string)
1853: {
1854: zval *mysql_link = NULL;
1855: char *str;
1856: char *new_str;
1857: int id = -1, str_len, new_str_len;
1858: php_mysql_conn *mysql;
1859:
1860:
1861: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {
1862: return;
1863: }
1864:
1865: if (ZEND_NUM_ARGS() == 1) {
1866: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1867: CHECK_LINK(id);
1868: }
1869:
1870: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1871:
1872: new_str = safe_emalloc(str_len, 2, 1);
1873: new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len);
1874: new_str = erealloc(new_str, new_str_len + 1);
1875:
1876: RETURN_STRINGL(new_str, new_str_len, 0);
1877: }
1878: /* }}} */
1879:
1880: /* {{{ proto int mysql_insert_id([int link_identifier])
1881: Gets the ID generated from the previous INSERT operation */
1882: PHP_FUNCTION(mysql_insert_id)
1883: {
1884: zval *mysql_link = NULL;
1885: int id = -1;
1886: php_mysql_conn *mysql;
1887:
1888: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
1889: return;
1890: }
1891:
1892: if (!mysql_link) {
1893: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1894: CHECK_LINK(id);
1895: }
1896:
1897: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
1898:
1899: /* conversion from int64 to long happing here */
1900: Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn);
1901: Z_TYPE_P(return_value) = IS_LONG;
1902: }
1903: /* }}} */
1904:
1905:
1906: /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
1907: Gets result data */
1908: PHP_FUNCTION(mysql_result)
1909: {
1910: zval *result, *field=NULL;
1911: long row;
1912: MYSQL_RES *mysql_result;
1913: #ifndef MYSQL_USE_MYSQLND
1914: MYSQL_ROW sql_row;
1915: mysql_row_length_type *sql_row_lengths;
1916: #endif
1917: int field_offset=0;
1918:
1919: /*
1920: johannes TODO:
1.1.1.4 misho 1921: Do 2 zend_parse_parameters calls instead of type "z" and switch below
1.1 misho 1922: Q: String or long first?
1923: */
1924: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) {
1925: return;
1926: }
1927:
1928: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
1929:
1930: if (row<0 || row>=(int)mysql_num_rows(mysql_result)) {
1931: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result));
1932: RETURN_FALSE;
1933: }
1934: mysql_data_seek(mysql_result, row);
1935:
1936: if (field) {
1937: switch(Z_TYPE_P(field)) {
1938: case IS_STRING: {
1939: int i=0;
1940: const MYSQL_FIELD *tmp_field;
1941: char *table_name, *field_name, *tmp;
1942:
1943: if ((tmp=strchr(Z_STRVAL_P(field), '.'))) {
1944: table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field));
1945: field_name = estrdup(tmp+1);
1946: } else {
1947: table_name = NULL;
1948: field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field));
1949: }
1950: mysql_field_seek(mysql_result, 0);
1951: while ((tmp_field=mysql_fetch_field(mysql_result))) {
1952: if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
1953: field_offset = i;
1954: break;
1955: }
1956: i++;
1957: }
1958: if (!tmp_field) { /* no match found */
1959: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld",
1960: (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result));
1961: efree(field_name);
1962: if (table_name) {
1963: efree(table_name);
1964: }
1965: RETURN_FALSE;
1966: }
1967: efree(field_name);
1968: if (table_name) {
1969: efree(table_name);
1970: }
1971: }
1972: break;
1973: default:
1974: convert_to_long_ex(&field);
1975: field_offset = Z_LVAL_P(field);
1976: if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) {
1977: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
1978: RETURN_FALSE;
1979: }
1980: break;
1981: }
1982: }
1983:
1984: #ifndef MYSQL_USE_MYSQLND
1985: if ((sql_row=mysql_fetch_row(mysql_result))==NULL
1986: || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */
1987: RETURN_FALSE;
1988: }
1989: if (sql_row[field_offset]) {
1990: Z_TYPE_P(return_value) = IS_STRING;
1991:
1.1.1.2 misho 1992: #if PHP_API_VERSION < 20100412
1.1 misho 1993: if (PG(magic_quotes_runtime)) {
1994: Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
1995: } else {
1.1.1.2 misho 1996: #endif
1.1 misho 1997: Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
1998: Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
1.1.1.2 misho 1999: #if PHP_API_VERSION < 20100412
1.1 misho 2000: }
1.1.1.2 misho 2001: #endif
1.1 misho 2002: } else {
2003: Z_TYPE_P(return_value) = IS_NULL;
2004: }
2005: #else
2006: mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value);
2007: #endif
2008: }
2009: /* }}} */
2010:
2011:
2012: /* {{{ proto int mysql_num_rows(resource result)
2013: Gets number of rows in a result */
2014: PHP_FUNCTION(mysql_num_rows)
2015: {
2016: zval *result;
2017: MYSQL_RES *mysql_result;
2018:
2019: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2020: return;
2021: }
2022:
2023: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2024:
2025: /* conversion from int64 to long happing here */
2026: Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result);
2027: Z_TYPE_P(return_value) = IS_LONG;
2028: }
2029: /* }}} */
2030:
2031: /* {{{ proto int mysql_num_fields(resource result)
2032: Gets number of fields in a result */
2033: PHP_FUNCTION(mysql_num_fields)
2034: {
2035: zval *result;
2036: MYSQL_RES *mysql_result;
2037:
2038: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2039: return;
2040: }
2041:
2042: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2043:
2044: Z_LVAL_P(return_value) = mysql_num_fields(mysql_result);
2045: Z_TYPE_P(return_value) = IS_LONG;
2046: }
2047: /* }}} */
2048:
2049: /* {{{ php_mysql_fetch_hash
2050: */
2051: static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object)
2052: {
2053: MYSQL_RES *mysql_result;
2054: zval *res, *ctor_params = NULL;
2055: zend_class_entry *ce = NULL;
2056: #ifndef MYSQL_USE_MYSQLND
2057: int i;
2058: MYSQL_FIELD *mysql_field;
2059: MYSQL_ROW mysql_row;
2060: mysql_row_length_type *mysql_row_lengths;
2061: #endif
2062:
2063: #ifdef ZEND_ENGINE_2
2064: if (into_object) {
2065: char *class_name = NULL;
2066: int class_name_len = 0;
2067:
2068: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) {
2069: return;
2070: }
2071:
2072: if (ZEND_NUM_ARGS() < 2) {
2073: ce = zend_standard_class_def;
2074: } else {
2075: ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
2076: }
2077: if (!ce) {
2078: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
2079: return;
2080: }
2081: result_type = MYSQL_ASSOC;
2082: } else
2083: #endif
2084: {
2085: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) {
2086: return;
2087: }
2088: if (!result_type) {
2089: /* result_type might have been set outside, so only overwrite when not set */
2090: result_type = MYSQL_BOTH;
2091: }
2092: }
2093:
2094: if (result_type & ~MYSQL_BOTH) {
2095: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
2096: result_type = MYSQL_BOTH;
2097: }
2098:
2099: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result);
2100:
2101: #ifndef MYSQL_USE_MYSQLND
2102: if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL ||
2103: (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) {
2104: RETURN_FALSE;
2105: }
2106:
2107: array_init(return_value);
2108:
2109: mysql_field_seek(mysql_result, 0);
2110: for (mysql_field = mysql_fetch_field(mysql_result), i = 0;
2111: mysql_field;
2112: mysql_field = mysql_fetch_field(mysql_result), i++)
2113: {
2114: if (mysql_row[i]) {
2115: zval *data;
2116:
2117: MAKE_STD_ZVAL(data);
2118:
1.1.1.2 misho 2119: #if PHP_API_VERSION < 20100412
1.1 misho 2120: if (PG(magic_quotes_runtime)) {
2121: Z_TYPE_P(data) = IS_STRING;
2122: Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
2123: } else {
1.1.1.2 misho 2124: #endif
1.1 misho 2125: ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
1.1.1.2 misho 2126: #if PHP_API_VERSION < 20100412
1.1 misho 2127: }
1.1.1.2 misho 2128: #endif
1.1 misho 2129:
2130: if (result_type & MYSQL_NUM) {
2131: add_index_zval(return_value, i, data);
2132: }
2133: if (result_type & MYSQL_ASSOC) {
2134: if (result_type & MYSQL_NUM) {
2135: Z_ADDREF_P(data);
2136: }
2137: add_assoc_zval(return_value, mysql_field->name, data);
2138: }
2139: } else {
2140: /* NULL value. */
2141: if (result_type & MYSQL_NUM) {
2142: add_index_null(return_value, i);
2143: }
2144:
2145: if (result_type & MYSQL_ASSOC) {
2146: add_assoc_null(return_value, mysql_field->name);
2147: }
2148: }
2149: }
2150: #else
2151: 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);
2152: #endif
2153:
2154: #ifdef ZEND_ENGINE_2
2155: /* mysqlnd might return FALSE if no more rows */
2156: if (into_object && Z_TYPE_P(return_value) != IS_BOOL) {
2157: zval dataset = *return_value;
2158: zend_fcall_info fci;
2159: zend_fcall_info_cache fcc;
2160: zval *retval_ptr;
2161:
2162: object_and_properties_init(return_value, ce, NULL);
2163: zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
2164:
2165: if (ce->constructor) {
2166: fci.size = sizeof(fci);
2167: fci.function_table = &ce->function_table;
2168: fci.function_name = NULL;
2169: fci.symbol_table = NULL;
2170: fci.object_ptr = return_value;
2171: fci.retval_ptr_ptr = &retval_ptr;
2172: if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
2173: if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
2174: HashTable *htl = Z_ARRVAL_P(ctor_params);
2175: Bucket *p;
2176:
2177: fci.param_count = 0;
2178: fci.params = safe_emalloc(sizeof(zval*), htl->nNumOfElements, 0);
2179: p = htl->pListHead;
2180: while (p != NULL) {
2181: fci.params[fci.param_count++] = (zval**)p->pData;
2182: p = p->pListNext;
2183: }
2184: } else {
2185: /* Two problems why we throw exceptions here: PHP is typeless
2186: * and hence passing one argument that's not an array could be
2187: * by mistake and the other way round is possible, too. The
2188: * single value is an array. Also we'd have to make that one
2189: * argument passed by reference.
2190: */
2191: zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
2192: return;
2193: }
2194: } else {
2195: fci.param_count = 0;
2196: fci.params = NULL;
2197: }
2198: fci.no_separation = 1;
2199:
2200: fcc.initialized = 1;
2201: fcc.function_handler = ce->constructor;
2202: fcc.calling_scope = EG(scope);
2203: fcc.called_scope = Z_OBJCE_P(return_value);
2204: fcc.object_ptr = return_value;
2205:
2206: if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
2207: 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);
2208: } else {
2209: if (retval_ptr) {
2210: zval_ptr_dtor(&retval_ptr);
2211: }
2212: }
2213: if (fci.params) {
2214: efree(fci.params);
2215: }
2216: } else if (ctor_params) {
2217: 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);
2218: }
2219: }
2220: #endif
2221:
2222: }
2223: /* }}} */
2224:
2225: /* {{{ proto array mysql_fetch_row(resource result)
2226: Gets a result row as an enumerated array */
2227: PHP_FUNCTION(mysql_fetch_row)
2228: {
2229: php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0);
2230: }
2231: /* }}} */
2232:
2233:
2234: /* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])
2235: Fetch a result row as an object */
2236: PHP_FUNCTION(mysql_fetch_object)
2237: {
2238: php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1);
2239:
2240: if (Z_TYPE_P(return_value) == IS_ARRAY) {
2241: object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
2242: }
2243: }
2244: /* }}} */
2245:
2246:
2247: /* {{{ proto array mysql_fetch_array(resource result [, int result_type])
2248: Fetch a result row as an array (associative, numeric or both) */
2249: PHP_FUNCTION(mysql_fetch_array)
2250: {
2251: php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
2252: }
2253: /* }}} */
2254:
2255:
2256: /* {{{ proto array mysql_fetch_assoc(resource result)
2257: Fetch a result row as an associative array */
2258: PHP_FUNCTION(mysql_fetch_assoc)
2259: {
2260: php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0);
2261: }
2262: /* }}} */
2263:
2264: /* {{{ proto bool mysql_data_seek(resource result, int row_number)
2265: Move internal result pointer */
2266: PHP_FUNCTION(mysql_data_seek)
2267: {
2268: zval *result;
2269: long offset;
2270: MYSQL_RES *mysql_result;
2271:
2272: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) {
2273: return;
2274: }
2275:
2276: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2277:
2278: if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) {
2279: 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));
2280: RETURN_FALSE;
2281: }
2282: mysql_data_seek(mysql_result, offset);
2283: RETURN_TRUE;
2284: }
2285: /* }}} */
2286:
2287:
2288: /* {{{ proto array mysql_fetch_lengths(resource result)
2289: Gets max data size of each column in a result */
2290: PHP_FUNCTION(mysql_fetch_lengths)
2291: {
2292: zval *result;
2293: MYSQL_RES *mysql_result;
2294: mysql_row_length_type *lengths;
2295: int num_fields;
2296: int i;
2297:
2298: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2299: return;
2300: }
2301:
2302: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2303:
2304: if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) {
2305: RETURN_FALSE;
2306: }
2307: array_init(return_value);
2308: num_fields = mysql_num_fields(mysql_result);
2309:
2310: for (i=0; i<num_fields; i++) {
2311: add_index_long(return_value, i, lengths[i]);
2312: }
2313: }
2314: /* }}} */
2315:
2316: /* {{{ php_mysql_get_field_name
2317: */
2318: static char *php_mysql_get_field_name(int field_type)
2319: {
2320: switch(field_type) {
2321: case FIELD_TYPE_STRING:
2322: case FIELD_TYPE_VAR_STRING:
2323: return "string";
2324: break;
2325: #if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND)
2326: case MYSQL_TYPE_BIT:
2327: #endif
2328: #ifdef MYSQL_HAS_TINY
2329: case FIELD_TYPE_TINY:
2330: #endif
2331: case FIELD_TYPE_SHORT:
2332: case FIELD_TYPE_LONG:
2333: case FIELD_TYPE_LONGLONG:
2334: case FIELD_TYPE_INT24:
2335: return "int";
2336: break;
2337: case FIELD_TYPE_FLOAT:
2338: case FIELD_TYPE_DOUBLE:
2339: case FIELD_TYPE_DECIMAL:
2340: #ifdef FIELD_TYPE_NEWDECIMAL
2341: case FIELD_TYPE_NEWDECIMAL:
2342: #endif
2343: return "real";
2344: break;
2345: case FIELD_TYPE_TIMESTAMP:
2346: return "timestamp";
2347: break;
2348: #ifdef MYSQL_HAS_YEAR
2349: case FIELD_TYPE_YEAR:
2350: return "year";
2351: break;
2352: #endif
2353: case FIELD_TYPE_DATE:
2354: #ifdef FIELD_TYPE_NEWDATE
2355: case FIELD_TYPE_NEWDATE:
2356: #endif
2357: return "date";
2358: break;
2359: case FIELD_TYPE_TIME:
2360: return "time";
2361: break;
2362: case FIELD_TYPE_SET:
2363: return "set";
2364: break;
2365: case FIELD_TYPE_ENUM:
2366: return "enum";
2367: break;
2368: #ifdef FIELD_TYPE_GEOMETRY
2369: case FIELD_TYPE_GEOMETRY:
2370: return "geometry";
2371: break;
2372: #endif
2373: case FIELD_TYPE_DATETIME:
2374: return "datetime";
2375: break;
2376: case FIELD_TYPE_TINY_BLOB:
2377: case FIELD_TYPE_MEDIUM_BLOB:
2378: case FIELD_TYPE_LONG_BLOB:
2379: case FIELD_TYPE_BLOB:
2380: return "blob";
2381: break;
2382: case FIELD_TYPE_NULL:
2383: return "null";
2384: break;
2385: default:
2386: return "unknown";
2387: break;
2388: }
2389: }
2390: /* }}} */
2391:
2392: /* {{{ proto object mysql_fetch_field(resource result [, int field_offset])
2393: Gets column information from a result and return as an object */
2394: PHP_FUNCTION(mysql_fetch_field)
2395: {
2396: zval *result;
2397: long field=0;
2398: MYSQL_RES *mysql_result;
2399: const MYSQL_FIELD *mysql_field;
2400:
2401: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) {
2402: return;
2403: }
2404:
2405: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2406:
2407: if (ZEND_NUM_ARGS() > 1) {
2408: if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
2409: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset");
2410: RETURN_FALSE;
2411: }
2412: mysql_field_seek(mysql_result, field);
2413: }
2414: if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
2415: RETURN_FALSE;
2416: }
2417: object_init(return_value);
2418:
1.1.1.2 misho 2419: add_property_string(return_value, "name",(mysql_field->name?mysql_field->name:""), 1);
2420: add_property_string(return_value, "table",(mysql_field->table?mysql_field->table:""), 1);
1.1 misho 2421: add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1);
2422: add_property_long(return_value, "max_length", mysql_field->max_length);
2423: add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
2424: add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
2425: add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
2426: add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
2427: add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0);
2428: add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0);
2429: add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1);
2430: add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
2431: add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
2432: }
2433: /* }}} */
2434:
2435:
2436: /* {{{ proto bool mysql_field_seek(resource result, int field_offset)
2437: Sets result pointer to a specific field offset */
2438: PHP_FUNCTION(mysql_field_seek)
2439: {
2440: zval *result;
2441: long offset;
2442: MYSQL_RES *mysql_result;
2443:
2444: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) {
2445: return;
2446: }
2447: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2448:
2449: if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) {
2450: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result));
2451: RETURN_FALSE;
2452: }
2453: mysql_field_seek(mysql_result, offset);
2454: RETURN_TRUE;
2455: }
2456: /* }}} */
2457:
2458:
2459: #define PHP_MYSQL_FIELD_NAME 1
2460: #define PHP_MYSQL_FIELD_TABLE 2
2461: #define PHP_MYSQL_FIELD_LEN 3
2462: #define PHP_MYSQL_FIELD_TYPE 4
2463: #define PHP_MYSQL_FIELD_FLAGS 5
2464:
2465: /* {{{ php_mysql_field_info
2466: */
2467: static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
2468: {
2469: zval *result;
2470: long field;
2471: MYSQL_RES *mysql_result;
2472: const MYSQL_FIELD *mysql_field = {0};
2473: char buf[512];
2474: int len;
2475:
2476: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
2477: return;
2478: }
2479:
2480: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2481:
2482: if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
2483: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result));
2484: RETURN_FALSE;
2485: }
2486: mysql_field_seek(mysql_result, field);
2487: if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
2488: RETURN_FALSE;
2489: }
2490:
2491: switch (entry_type) {
2492: case PHP_MYSQL_FIELD_NAME:
2493: Z_STRLEN_P(return_value) = strlen(mysql_field->name);
2494: Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value));
2495: Z_TYPE_P(return_value) = IS_STRING;
2496: break;
2497: case PHP_MYSQL_FIELD_TABLE:
2498: Z_STRLEN_P(return_value) = strlen(mysql_field->table);
2499: Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value));
2500: Z_TYPE_P(return_value) = IS_STRING;
2501: break;
2502: case PHP_MYSQL_FIELD_LEN:
2503: Z_LVAL_P(return_value) = mysql_field->length;
2504: Z_TYPE_P(return_value) = IS_LONG;
2505: break;
2506: case PHP_MYSQL_FIELD_TYPE:
2507: Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field));
2508: Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
2509: Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
2510: Z_TYPE_P(return_value) = IS_STRING;
2511: break;
2512: case PHP_MYSQL_FIELD_FLAGS:
2513: memcpy(buf, "", sizeof(""));
2514: #ifdef IS_NOT_NULL
2515: if (IS_NOT_NULL(mysql_field->flags)) {
2516: strcat(buf, "not_null ");
2517: }
2518: #endif
2519: #ifdef IS_PRI_KEY
2520: if (IS_PRI_KEY(mysql_field->flags)) {
2521: strcat(buf, "primary_key ");
2522: }
2523: #endif
2524: #ifdef UNIQUE_KEY_FLAG
2525: if (mysql_field->flags&UNIQUE_KEY_FLAG) {
2526: strcat(buf, "unique_key ");
2527: }
2528: #endif
2529: #ifdef MULTIPLE_KEY_FLAG
2530: if (mysql_field->flags&MULTIPLE_KEY_FLAG) {
2531: strcat(buf, "multiple_key ");
2532: }
2533: #endif
2534: #ifdef IS_BLOB
2535: if (IS_BLOB(mysql_field->flags)) {
2536: strcat(buf, "blob ");
2537: }
2538: #endif
2539: #ifdef UNSIGNED_FLAG
2540: if (mysql_field->flags&UNSIGNED_FLAG) {
2541: strcat(buf, "unsigned ");
2542: }
2543: #endif
2544: #ifdef ZEROFILL_FLAG
2545: if (mysql_field->flags&ZEROFILL_FLAG) {
2546: strcat(buf, "zerofill ");
2547: }
2548: #endif
2549: #ifdef BINARY_FLAG
2550: if (mysql_field->flags&BINARY_FLAG) {
2551: strcat(buf, "binary ");
2552: }
2553: #endif
2554: #ifdef ENUM_FLAG
2555: if (mysql_field->flags&ENUM_FLAG) {
2556: strcat(buf, "enum ");
2557: }
2558: #endif
2559: #ifdef SET_FLAG
2560: if (mysql_field->flags&SET_FLAG) {
2561: strcat(buf, "set ");
2562: }
2563: #endif
2564: #ifdef AUTO_INCREMENT_FLAG
2565: if (mysql_field->flags&AUTO_INCREMENT_FLAG) {
2566: strcat(buf, "auto_increment ");
2567: }
2568: #endif
2569: #ifdef TIMESTAMP_FLAG
2570: if (mysql_field->flags&TIMESTAMP_FLAG) {
2571: strcat(buf, "timestamp ");
2572: }
2573: #endif
2574: len = strlen(buf);
2575: /* remove trailing space, if present */
2576: if (len && buf[len-1] == ' ') {
2577: buf[len-1] = 0;
2578: len--;
2579: }
2580:
2581: Z_STRLEN_P(return_value) = len;
2582: Z_STRVAL_P(return_value) = estrndup(buf, len);
2583: Z_TYPE_P(return_value) = IS_STRING;
2584: break;
2585:
2586: default:
2587: RETURN_FALSE;
2588: }
2589: }
2590: /* }}} */
2591:
2592: /* {{{ proto string mysql_field_name(resource result, int field_index)
2593: Gets the name of the specified field in a result */
2594: PHP_FUNCTION(mysql_field_name)
2595: {
2596: php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME);
2597: }
2598: /* }}} */
2599:
2600:
2601: /* {{{ proto string mysql_field_table(resource result, int field_offset)
2602: Gets name of the table the specified field is in */
2603: PHP_FUNCTION(mysql_field_table)
2604: {
2605: php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE);
2606: }
2607: /* }}} */
2608:
2609:
2610: /* {{{ proto int mysql_field_len(resource result, int field_offset)
2611: Returns the length of the specified field */
2612: PHP_FUNCTION(mysql_field_len)
2613: {
2614: php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN);
2615: }
2616: /* }}} */
2617:
2618:
2619: /* {{{ proto string mysql_field_type(resource result, int field_offset)
2620: Gets the type of the specified field in a result */
2621: PHP_FUNCTION(mysql_field_type)
2622: {
2623: php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE);
2624: }
2625: /* }}} */
2626:
2627:
2628: /* {{{ proto string mysql_field_flags(resource result, int field_offset)
2629: Gets the flags associated with the specified field in a result */
2630: PHP_FUNCTION(mysql_field_flags)
2631: {
2632: php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS);
2633: }
2634: /* }}} */
2635:
2636:
2637: /* {{{ proto bool mysql_free_result(resource result)
2638: Free result memory */
2639: PHP_FUNCTION(mysql_free_result)
2640: {
2641: zval *result;
2642: MYSQL_RES *mysql_result;
2643:
2644: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
2645: return;
2646: }
2647:
2648: if (Z_LVAL_P(result)==0) {
2649: RETURN_FALSE;
2650: }
2651:
2652: ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
2653:
2654: zend_list_delete(Z_LVAL_P(result));
2655: RETURN_TRUE;
2656: }
2657: /* }}} */
2658:
2659: /* {{{ proto bool mysql_ping([int link_identifier])
2660: Ping a server connection. If no connection then reconnect. */
2661: PHP_FUNCTION(mysql_ping)
2662: {
2663: zval *mysql_link = NULL;
2664: int id = -1;
2665: php_mysql_conn *mysql;
2666:
2667: if (0 == ZEND_NUM_ARGS()) {
2668: id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
2669: CHECK_LINK(id);
2670: } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) {
2671: return;
2672: }
2673:
2674: ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
2675:
2676: PHPMY_UNBUFFERED_QUERY_CHECK();
2677:
2678: RETURN_BOOL(! mysql_ping(mysql->conn));
2679: }
2680: /* }}} */
2681:
2682: #endif
2683:
2684: /*
2685: * Local variables:
2686: * tab-width: 4
2687: * c-basic-offset: 4
2688: * End:
2689: * vim600: sw=4 ts=4 fdm=marker
2690: * vim<600: sw=4 ts=4
2691: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>