Annotation of embedaddon/php/ext/mysqli/mysqli_api.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 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: Georg Richter <georg@php.net> |
16: | Andrey Hristov <andrey@php.net> |
17: | Ulf Wendel <uw@php.net> |
18: +----------------------------------------------------------------------+
19:
1.1.1.2 misho 20: $Id$
1.1 misho 21: */
22:
23: #ifdef HAVE_CONFIG_H
24: #include "config.h"
25: #endif
26:
27: #include <signal.h>
28:
29: #include "php.h"
30: #include "php_ini.h"
31: #include "php_globals.h"
32: #include "ext/standard/info.h"
33: #include "php_mysqli_structs.h"
34: #include "mysqli_priv.h"
35:
36: /* {{{ proto mixed mysqli_affected_rows(object link)
37: Get number of affected rows in previous MySQL operation */
38: PHP_FUNCTION(mysqli_affected_rows)
39: {
40: MY_MYSQL *mysql;
41: zval *mysql_link;
42: my_ulonglong rc;
43:
44: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
45: return;
46: }
47:
48: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
49:
50: rc = mysql_affected_rows(mysql->mysql);
51: if (rc == (my_ulonglong) -1) {
52: RETURN_LONG(-1);
53: }
54: MYSQLI_RETURN_LONG_LONG(rc);
55: }
56: /* }}} */
57:
58:
59: /* {{{ proto bool mysqli_autocommit(object link, bool mode)
60: Turn auto commit on or of */
61: PHP_FUNCTION(mysqli_autocommit)
62: {
63: MY_MYSQL *mysql;
64: zval *mysql_link;
65: zend_bool automode;
66:
67: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
68: return;
69: }
70: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
71:
72: if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
73: RETURN_FALSE;
74: }
75: RETURN_TRUE;
76: }
77: /* }}} */
78:
79: /* {{{ mysqli_stmt_bind_param_do_bind */
80: #ifndef MYSQLI_USE_MYSQLND
81: static
82: int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
83: zval ***args, unsigned int start, const char * const types TSRMLS_DC)
84: {
85: int i, ofs;
86: MYSQL_BIND *bind;
87: unsigned long rc;
88:
89: /* prevent leak if variables are already bound */
90: if (stmt->param.var_cnt) {
91: php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
92: }
93:
94: stmt->param.is_null = ecalloc(num_vars, sizeof(char));
95: bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
96:
97: ofs = 0;
98: for (i = start; i < argc; i++) {
99:
100: /* set specified type */
101: switch (types[ofs]) {
102: case 'd': /* Double */
103: bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
104: bind[ofs].buffer = &Z_DVAL_PP(args[i]);
105: bind[ofs].is_null = &stmt->param.is_null[ofs];
106: break;
107:
108: case 'i': /* Integer */
109: #if SIZEOF_LONG==8
110: bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG;
111: #elif SIZEOF_LONG==4
112: bind[ofs].buffer_type = MYSQL_TYPE_LONG;
113: #endif
114: bind[ofs].buffer = &Z_LVAL_PP(args[i]);
115: bind[ofs].is_null = &stmt->param.is_null[ofs];
116: break;
117:
118: case 'b': /* Blob (send data) */
119: bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
120: /* don't initialize is_null and length to 0 because we use ecalloc */
121: break;
122:
123: case 's': /* string */
124: bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
125: /* don't initialize buffer and buffer_length because we use ecalloc */
126: bind[ofs].is_null = &stmt->param.is_null[ofs];
127: break;
128:
129: default:
130: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
131: rc = 1;
132: goto end_1;
133: }
134: ofs++;
135: }
136: rc = mysql_stmt_bind_param(stmt->stmt, bind);
137:
138: end_1:
139: if (rc) {
140: efree(stmt->param.is_null);
141: } else {
142: stmt->param.var_cnt = num_vars;
143: stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0);
144: for (i = 0; i < num_vars; i++) {
145: if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
146: Z_ADDREF_P(*args[i+start]);
147: stmt->param.vars[i] = *args[i+start];
148: } else {
149: stmt->param.vars[i] = NULL;
150: }
151: }
152: }
153: efree(bind);
154:
155: return rc;
156: }
157: #else
158: static
159: int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
160: zval ***args, unsigned int start, const char * const types TSRMLS_DC)
161: {
162: unsigned int i;
163: MYSQLND_PARAM_BIND *params;
164: enum_func_status ret = FAIL;
165:
166: /* If no params -> skip binding and return directly */
167: if (argc == start) {
168: return PASS;
169: }
170: params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
171: if (!params) {
172: goto end;
173: }
174: for (i = 0; i < (argc - start); i++) {
175: zend_uchar type;
176: switch (types[i]) {
177: case 'd': /* Double */
178: type = MYSQL_TYPE_DOUBLE;
179: break;
180: case 'i': /* Integer */
181: #if SIZEOF_LONG==8
182: type = MYSQL_TYPE_LONGLONG;
183: #elif SIZEOF_LONG==4
184: type = MYSQL_TYPE_LONG;
185: #endif
186: break;
187: case 'b': /* Blob (send data) */
188: type = MYSQL_TYPE_LONG_BLOB;
189: break;
190: case 's': /* string */
191: type = MYSQL_TYPE_VAR_STRING;
192: break;
193: default:
194: /* We count parameters from 1 */
195: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
196: ret = FAIL;
197: mysqlnd_stmt_free_param_bind(stmt->stmt, params);
198: goto end;
199: }
200: params[i].zv = *(args[i + start]);
201: params[i].type = type;
202: }
203: ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
204:
205: end:
206: return ret;
207: }
208: #endif
209: /* }}} */
210:
211: /* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U
212: Bind variables to a prepared statement as parameters */
213: PHP_FUNCTION(mysqli_stmt_bind_param)
214: {
215: zval ***args;
216: int argc = ZEND_NUM_ARGS();
217: int num_vars;
218: int start = 2;
219: MY_STMT *stmt;
220: zval *mysql_stmt;
221: char *types;
222: int types_len;
223: unsigned long rc;
224:
225: /* calculate and check number of parameters */
226: if (argc < 2) {
227: /* there has to be at least one pair */
228: WRONG_PARAM_COUNT;
229: }
230:
231: if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry,
232: &types, &types_len) == FAILURE) {
233: return;
234: }
235:
236: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
237:
238: num_vars = argc - 1;
239: if (getThis()) {
240: start = 1;
241: } else {
242: /* ignore handle parameter in procedural interface*/
243: --num_vars;
244: }
245: if (!types_len) {
246: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified");
247: RETURN_FALSE;
248: }
249:
250: if (types_len != argc - start) {
251: /* number of bind variables doesn't match number of elements in type definition string */
252: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
253: RETURN_FALSE;
254: }
255:
256: if (types_len != mysql_stmt_param_count(stmt->stmt)) {
257: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
258: RETURN_FALSE;
259: }
260:
261: args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
262:
263: if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
264: zend_wrong_param_count(TSRMLS_C);
265: rc = 1;
266: } else {
267: rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC);
268: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
269: }
270:
271: efree(args);
272:
273: RETURN_BOOL(!rc);
274: }
275: /* }}} */
276:
277: /* {{{ mysqli_stmt_bind_result_do_bind */
278: #ifndef MYSQLI_USE_MYSQLND
279: /* TODO:
280: do_alloca, free_alloca
281: */
282: static int
283: mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
284: {
285: MYSQL_BIND *bind;
286: int i, ofs;
287: int var_cnt = argc - start;
288: long col_type;
289: ulong rc;
290:
291: /* prevent leak if variables are already bound */
292: if (stmt->result.var_cnt) {
293: php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
294: }
295:
296: bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
297: {
298: int size;
299: char *p= emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
300: stmt->result.buf = (VAR_BUFFER *) p;
301: stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
302: memset(p, 0, size);
303: }
304:
305: for (i=start; i < var_cnt + start ; i++) {
306: ofs = i - start;
307: col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
308:
309: switch (col_type) {
310: case MYSQL_TYPE_DOUBLE:
311: case MYSQL_TYPE_FLOAT:
312: convert_to_double_ex(args[i]);
313: stmt->result.buf[ofs].type = IS_DOUBLE;
314: stmt->result.buf[ofs].buflen = sizeof(double);
315:
316: /* allocate buffer for double */
317: stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
318: bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
319: bind[ofs].buffer = stmt->result.buf[ofs].val;
320: bind[ofs].is_null = &stmt->result.is_null[ofs];
321: break;
322:
323: case MYSQL_TYPE_NULL:
324: stmt->result.buf[ofs].type = IS_NULL;
325: /*
326: don't initialize to 0 :
327: 1. stmt->result.buf[ofs].buflen
328: 2. bind[ofs].buffer
329: 3. bind[ofs].buffer_length
330: because memory was allocated with ecalloc
331: */
332: bind[ofs].buffer_type = MYSQL_TYPE_NULL;
333: bind[ofs].is_null = &stmt->result.is_null[ofs];
334: break;
335:
336: case MYSQL_TYPE_SHORT:
337: case MYSQL_TYPE_TINY:
338: case MYSQL_TYPE_LONG:
339: case MYSQL_TYPE_INT24:
340: case MYSQL_TYPE_YEAR:
341: convert_to_long_ex(args[i]);
342: stmt->result.buf[ofs].type = IS_LONG;
343: /* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
344: stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
345: bind[ofs].buffer_type = MYSQL_TYPE_LONG;
346: bind[ofs].buffer = stmt->result.buf[ofs].val;
347: bind[ofs].is_null = &stmt->result.is_null[ofs];
348: bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
349: break;
350:
351: case MYSQL_TYPE_LONGLONG:
352: #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
353: case MYSQL_TYPE_BIT:
354: #endif
355: stmt->result.buf[ofs].type = IS_STRING;
356: stmt->result.buf[ofs].buflen = sizeof(my_ulonglong);
357: stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
358: bind[ofs].buffer_type = col_type;
359: bind[ofs].buffer = stmt->result.buf[ofs].val;
360: bind[ofs].is_null = &stmt->result.is_null[ofs];
361: bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
362: bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
363: bind[ofs].length = &stmt->result.buf[ofs].output_len;
364: break;
365:
366: case MYSQL_TYPE_DATE:
367: case MYSQL_TYPE_TIME:
368: case MYSQL_TYPE_DATETIME:
369: case MYSQL_TYPE_NEWDATE:
370: case MYSQL_TYPE_VAR_STRING:
371: case MYSQL_TYPE_STRING:
372: case MYSQL_TYPE_TINY_BLOB:
373: case MYSQL_TYPE_BLOB:
374: case MYSQL_TYPE_MEDIUM_BLOB:
375: case MYSQL_TYPE_LONG_BLOB:
376: case MYSQL_TYPE_TIMESTAMP:
377: case MYSQL_TYPE_DECIMAL:
378: case MYSQL_TYPE_GEOMETRY:
379: #ifdef FIELD_TYPE_NEWDECIMAL
380: case MYSQL_TYPE_NEWDECIMAL:
381: #endif
382: {
383: #if MYSQL_VERSION_ID >= 50107
384: /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
385: my_bool tmp;
386: #else
387: uint tmp = 0;
388: #endif
389: stmt->result.buf[ofs].type = IS_STRING;
390: /*
391: If the user has called $stmt->store_result() then we have asked
392: max_length to be updated. this is done only for BLOBS because we don't want to allocate
393: big chunkgs of memory 2^16 or 2^24
394: */
395: if (stmt->stmt->fields[ofs].max_length == 0 &&
396: !mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
397: {
398: /*
399: Allocate directly 256 because it's easier to allocate a bit more
400: than update max length even for text columns. Try SELECT UNION SELECT UNION with
401: different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length
402: The just take 256 and saves us from realloc-ing.
403: */
404: stmt->result.buf[ofs].buflen =
405: (stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
406:
407: } else {
408: /*
409: the user has called store_result(). if he does not there is no way to determine the
410: libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
411: */
412: if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
413: ++stmt->result.buf[ofs].buflen;
414: }
415: stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
416: bind[ofs].buffer_type = MYSQL_TYPE_STRING;
417: bind[ofs].buffer = stmt->result.buf[ofs].val;
418: bind[ofs].is_null = &stmt->result.is_null[ofs];
419: bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
420: bind[ofs].length = &stmt->result.buf[ofs].output_len;
421: break;
422: }
423: default:
424: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type);
425: break;
426: }
427: }
428:
429: rc = mysql_stmt_bind_result(stmt->stmt, bind);
430: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
431:
432: if (rc) {
433: /* dont close the statement or subsequent usage (for example ->execute()) will lead to crash */
434: for (i=0; i < var_cnt ; i++) {
435: if (stmt->result.buf[i].val) {
436: efree(stmt->result.buf[i].val);
437: }
438: }
439: /* Don't free stmt->result.is_null because is_null & buf are one block of memory */
440: efree(stmt->result.buf);
441: } else {
442: stmt->result.var_cnt = var_cnt;
443: stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0);
444: for (i = start; i < var_cnt+start; i++) {
445: ofs = i-start;
446: Z_ADDREF_PP(args[i]);
447: stmt->result.vars[ofs] = *args[i];
448: }
449: }
450: efree(bind);
451:
452: return rc;
453: }
454: #else
455: static int
456: mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
457: {
458: unsigned int i;
459: MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
460: if (params) {
461: for (i = 0; i < (argc - start); i++) {
462: params[i].zv = *(args[i + start]);
463: }
464: return mysqlnd_stmt_bind_result(stmt->stmt, params);
465: }
466: return FAIL;
467: }
468: #endif
469: /* }}} */
470:
471: /* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U
472: Bind variables to a prepared statement for result storage */
473: PHP_FUNCTION(mysqli_stmt_bind_result)
474: {
475: zval ***args;
476: int argc = ZEND_NUM_ARGS();
477: int start = 1;
478: ulong rc;
479: MY_STMT *stmt;
480: zval *mysql_stmt;
481:
482: if (getThis()) {
483: start = 0;
484: }
485:
486: if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
487: return;
488: }
489:
490: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
491:
492: if (argc < (getThis() ? 1 : 2)) {
493: WRONG_PARAM_COUNT;
494: }
495:
496: if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) {
497: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement");
498: RETURN_FALSE;
499: }
500:
501: args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
502:
503: if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
504: efree(args);
505: WRONG_PARAM_COUNT;
506: }
507:
508: rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC);
509:
510: efree(args);
511:
512: RETURN_BOOL(!rc);
513: }
514: /* }}} */
515:
516: /* {{{ proto bool mysqli_change_user(object link, string user, string password, string database)
517: Change logged-in user of the active connection */
518: PHP_FUNCTION(mysqli_change_user)
519: {
520: MY_MYSQL *mysql;
521: zval *mysql_link = NULL;
522: char *user, *password, *dbname;
523: int user_len, password_len, dbname_len;
524: ulong rc;
525: #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
526: const CHARSET_INFO * old_charset;
527: #endif
528:
529: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
530: return;
531: }
532: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
533:
534: #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
535: old_charset = mysql->mysql->charset;
536: #endif
537:
1.1.1.2 misho 538: #if defined(MYSQLI_USE_MYSQLND)
539: rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, FALSE, (size_t) password_len);
540: #else
1.1 misho 541: rc = mysql_change_user(mysql->mysql, user, password, dbname);
1.1.1.2 misho 542: #endif
1.1 misho 543: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
544:
545: if (rc) {
546: RETURN_FALSE;
547: }
548: #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
549: if (mysql_get_server_version(mysql->mysql) < 501023L) {
550: /*
551: Request the current charset, or it will be reset to the system one.
552: 5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug :
553: Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call
554: */
555: rc = mysql_set_character_set(mysql->mysql, old_charset->csname);
556: }
557: #endif
558:
559: RETURN_TRUE;
560: }
561: /* }}} */
562:
563: /* {{{ proto string mysqli_character_set_name(object link)
564: Returns the name of the character set used for this connection */
565: PHP_FUNCTION(mysqli_character_set_name)
566: {
567: MY_MYSQL *mysql;
568: zval *mysql_link;
569:
570: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
571: return;
572: }
573:
574: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
575:
576: RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);
577: }
578: /* }}} */
579:
580:
581: /* {{{ php_mysqli_close */
582: void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC)
583: {
584: if (resource_status > MYSQLI_STATUS_INITIALIZED) {
585: MyG(num_links)--;
586: }
587:
588: if (!mysql->persistent) {
589: mysqli_close(mysql->mysql, close_type);
590: } else {
591: zend_rsrc_list_entry *le;
592: if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) {
593: if (Z_TYPE_P(le) == php_le_pmysqli()) {
594: mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
595: #if defined(MYSQLI_USE_MYSQLND)
596: mysqlnd_end_psession(mysql->mysql);
597: #endif
598: zend_ptr_stack_push(&plist->free_links, mysql->mysql);
599:
600: MyG(num_active_persistent)--;
601: MyG(num_inactive_persistent)++;
602: }
603: }
604: mysql->persistent = FALSE;
605: }
606: mysql->mysql = NULL;
607:
608: php_clear_mysql(mysql);
609: }
610: /* }}} */
611:
612:
613: /* {{{ proto bool mysqli_close(object link)
614: Close connection */
615: PHP_FUNCTION(mysqli_close)
616: {
617: zval *mysql_link;
618: MY_MYSQL *mysql;
619:
620: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
621: return;
622: }
623:
624: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
625:
626: php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status TSRMLS_CC);
627: ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status = MYSQLI_STATUS_UNKNOWN;
628:
629: MYSQLI_CLEAR_RESOURCE(&mysql_link);
630: efree(mysql);
631: RETURN_TRUE;
632: }
633: /* }}} */
634:
635: /* {{{ proto bool mysqli_commit(object link)
636: Commit outstanding actions and close transaction */
637: PHP_FUNCTION(mysqli_commit)
638: {
639: MY_MYSQL *mysql;
640: zval *mysql_link;
641:
642: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
643: return;
644: }
645: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
646: if (mysql_commit(mysql->mysql)) {
647: RETURN_FALSE;
648: }
649: RETURN_TRUE;
650: }
651: /* }}} */
652:
653: /* {{{ proto bool mysqli_data_seek(object result, int offset)
654: Move internal result pointer */
655: PHP_FUNCTION(mysqli_data_seek)
656: {
657: MYSQL_RES *result;
658: zval *mysql_result;
659: long offset;
660:
661: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
662: return;
663: }
664:
665: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
666:
667: if (mysqli_result_is_unbuffered(result)) {
668: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
669: RETURN_FALSE;
670: }
671:
672: if (offset < 0 || offset >= mysql_num_rows(result)) {
673: RETURN_FALSE;
674: }
675:
676: mysql_data_seek(result, offset);
677: RETURN_TRUE;
678: }
679: /* }}} */
680:
681: /* {{{ proto void mysqli_debug(string debug) U
682: */
683: PHP_FUNCTION(mysqli_debug)
684: {
685: char *debug;
686: int debug_len;
687:
688: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
689: return;
690: }
691:
692: mysql_debug(debug);
693: RETURN_TRUE;
694: }
695: /* }}} */
696:
697:
698: /* {{{ proto bool mysqli_dump_debug_info(object link)
699: */
700: PHP_FUNCTION(mysqli_dump_debug_info)
701: {
702: MY_MYSQL *mysql;
703: zval *mysql_link;
704:
705: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
706: return;
707: }
708: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
709:
710: RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))
711: }
712: /* }}} */
713:
714: /* {{{ proto int mysqli_errno(object link)
715: Returns the numerical value of the error message from previous MySQL operation */
716: PHP_FUNCTION(mysqli_errno)
717: {
718: MY_MYSQL *mysql;
719: zval *mysql_link;
720:
721: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
722: return;
723: }
724: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
725: RETURN_LONG(mysql_errno(mysql->mysql));
726: }
727: /* }}} */
728:
729: /* {{{ proto string mysqli_error(object link)
730: Returns the text of the error message from previous MySQL operation */
731: PHP_FUNCTION(mysqli_error)
732: {
733: MY_MYSQL *mysql;
734: zval *mysql_link;
735:
736: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
737: return;
738: }
739: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
740: RETURN_STRING((char *)mysql_error(mysql->mysql),1);
741: }
742: /* }}} */
743:
744: #ifndef MYSQLI_USE_MYSQLND
745: /* {{{ php_mysqli_stmt_copy_it */
746: static void
747: php_mysqli_stmt_copy_it(zval *** copies, zval *original, uint param_count, uint current)
748: {
749: if (!*copies) {
750: *copies = ecalloc(param_count, sizeof(zval *));
751: }
752: MAKE_STD_ZVAL((*copies)[current]);
753: *(*copies)[current] = *original;
754: Z_SET_REFCOUNT_P((*copies)[current], 1);
755: zval_copy_ctor((*copies)[current]);
756: }
757: /* }}} */
758: #endif
759:
760: /* {{{ proto bool mysqli_stmt_execute(object stmt)
761: Execute a prepared statement */
762: PHP_FUNCTION(mysqli_stmt_execute)
763: {
764: MY_STMT *stmt;
765: zval *mysql_stmt;
766: #ifndef MYSQLI_USE_MYSQLND
767: unsigned int i;
768: zval **copies = NULL;
769: #endif
770:
771: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
772: return;
773: }
774: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
775:
776: #ifndef MYSQLI_USE_MYSQLND
777: if (stmt->param.var_cnt) {
778: int j;
779: for (i = 0; i < stmt->param.var_cnt; i++) {
780: for (j = i + 1; j < stmt->param.var_cnt; j++) {
781: /* Oops, someone binding the same variable - clone */
782: if (stmt->param.vars[j] == stmt->param.vars[i] && stmt->param.vars[i]) {
783: php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
784: break;
785: }
786: }
787: }
788: }
789: for (i = 0; i < stmt->param.var_cnt; i++) {
790: if (stmt->param.vars[i]) {
791: if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) {
792: zval *the_var = copies && copies[i]? copies[i]:stmt->param.vars[i];
793: switch (stmt->stmt->params[i].buffer_type) {
794: case MYSQL_TYPE_VAR_STRING:
795: if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) {
796: php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
797: the_var = copies[i];
798: }
799: convert_to_string_ex(&the_var);
800: stmt->stmt->params[i].buffer = Z_STRVAL_P(the_var);
801: stmt->stmt->params[i].buffer_length = Z_STRLEN_P(the_var);
802: break;
803: case MYSQL_TYPE_DOUBLE:
804: if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_DOUBLE) {
805: php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
806: the_var = copies[i];
807: }
808: convert_to_double_ex(&the_var);
809: stmt->stmt->params[i].buffer = &Z_DVAL_P(the_var);
810: break;
811: case MYSQL_TYPE_LONGLONG:
812: case MYSQL_TYPE_LONG:
813: if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_LONG) {
814: php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
815: the_var = copies[i];
816: }
817: convert_to_long_ex(&the_var);
818: stmt->stmt->params[i].buffer = &Z_LVAL_P(the_var);
819: break;
820: default:
821: break;
822: }
823: }
824: }
825: }
826: #endif
827:
828: if (mysql_stmt_execute(stmt->stmt)) {
829: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
830: RETVAL_FALSE;
831: } else {
832: RETVAL_TRUE;
833: }
834:
835: #ifndef MYSQLI_USE_MYSQLND
836: if (copies) {
837: for (i = 0; i < stmt->param.var_cnt; i++) {
838: if (copies[i]) {
839: zval_ptr_dtor(&copies[i]);
840: }
841: }
842: efree(copies);
843: }
844: #endif
845:
846: if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
847: php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC);
848: }
849: }
850: /* }}} */
851:
852: #ifndef MYSQLI_USE_MYSQLND
853: /* {{{ void mysqli_stmt_fetch_libmysql
854: Fetch results from a prepared statement into the bound variables */
855: void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
856: {
857: MY_STMT *stmt;
858: zval *mysql_stmt;
859: unsigned int i;
860: ulong ret;
861: unsigned int uval;
862: my_ulonglong llval;
863:
864:
865: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
866: return;
867: }
868: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
869:
870: /* reset buffers */
871: for (i = 0; i < stmt->result.var_cnt; i++) {
872: if (stmt->result.buf[i].type == IS_STRING) {
873: memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
874: }
875: }
876: ret = mysql_stmt_fetch(stmt->stmt);
877: #ifdef MYSQL_DATA_TRUNCATED
878: if (!ret || ret == MYSQL_DATA_TRUNCATED) {
879: #else
880: if (!ret) {
881: #endif
882: for (i = 0; i < stmt->result.var_cnt; i++) {
883: /*
884: QQ: Isn't it quite better to call zval_dtor(). What if the user has
885: assigned a resource, or an array to the bound variable? We are going
886: to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode.
887: */
888: /* Even if the string is of length zero there is one byte alloced so efree() in all cases */
889: if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) {
1.1.1.2 misho 890: STR_FREE(stmt->result.vars[i]->value.str.val);
1.1 misho 891: }
892: if (!stmt->result.is_null[i]) {
893: switch (stmt->result.buf[i].type) {
894: case IS_LONG:
895: if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)
896: && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
897: {
898: /* unsigned int (11) */
899: uval= *(unsigned int *) stmt->result.buf[i].val;
900: #if SIZEOF_LONG==4
901: if (uval > INT_MAX) {
902: char *tmp, *p;
903: int j=10;
904: tmp= emalloc(11);
905: p= &tmp[9];
906: do {
907: *p-- = (uval % 10) + 48;
908: uval = uval / 10;
909: } while (--j > 0);
910: tmp[10]= '\0';
911: /* unsigned int > INT_MAX is 10 digits - ALWAYS */
912: ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0);
913: break;
914: }
915: #endif
916: }
917: if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
918: ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val);
919: } else {
920: ZVAL_LONG(stmt->result.vars[i], *(int *)stmt->result.buf[i].val);
921: }
922: break;
923: case IS_DOUBLE:
924: ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val);
925: break;
926: case IS_STRING:
927: if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
928: #if MYSQL_VERSION_ID > 50002
929: || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
930: #endif
931: ) {
932: my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
933: #if MYSQL_VERSION_ID > 50002
934: if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
935: switch (stmt->result.buf[i].output_len) {
936: case 8:llval = (my_ulonglong) bit_uint8korr(stmt->result.buf[i].val);break;
937: case 7:llval = (my_ulonglong) bit_uint7korr(stmt->result.buf[i].val);break;
938: case 6:llval = (my_ulonglong) bit_uint6korr(stmt->result.buf[i].val);break;
939: case 5:llval = (my_ulonglong) bit_uint5korr(stmt->result.buf[i].val);break;
940: case 4:llval = (my_ulonglong) bit_uint4korr(stmt->result.buf[i].val);break;
941: case 3:llval = (my_ulonglong) bit_uint3korr(stmt->result.buf[i].val);break;
942: case 2:llval = (my_ulonglong) bit_uint2korr(stmt->result.buf[i].val);break;
943: case 1:llval = (my_ulonglong) uint1korr(stmt->result.buf[i].val);break;
944: }
945: } else
946: #endif
947: {
948: llval= *(my_ulonglong *) stmt->result.buf[i].val;
949: }
950: #if SIZEOF_LONG==8
951: if (uns && llval > 9223372036854775807L) {
952: #elif SIZEOF_LONG==4
953: if ((uns && llval > L64(2147483647)) ||
954: (!uns && (( L64(2147483647) < (my_longlong) llval) ||
955: (L64(-2147483648) > (my_longlong) llval))))
956: {
957: #endif
958: char tmp[22];
959: /* even though lval is declared as unsigned, the value
960: * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
961: * use MYSQLI_LL_SPEC.
962: */
963: snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
964: ZVAL_STRING(stmt->result.vars[i], tmp, 1);
965: } else {
966: ZVAL_LONG(stmt->result.vars[i], llval);
967: }
968: } else {
969: #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
970: if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
971: /* result was truncated */
972: ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
973: stmt->stmt->bind[i].buffer_length, 1);
974: } else {
975: #else
976: {
977: #endif
978: ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
979: stmt->result.buf[i].output_len, 1);
980: }
981: }
982: break;
983: default:
984: break;
985: }
986: } else {
987: ZVAL_NULL(stmt->result.vars[i]);
988: }
989: }
990: } else {
991: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
992: }
993:
994: switch (ret) {
995: case 0:
996: #ifdef MYSQL_DATA_TRUNCATED
997: /* according to SQL standard truncation (e.g. loss of precision is
998: not an error) - for detecting possible truncation you have to
999: check mysqli_stmt_warning
1000: */
1001: case MYSQL_DATA_TRUNCATED:
1002: #endif
1003: RETURN_TRUE;
1004: break;
1005: case 1:
1006: RETURN_FALSE;
1007: break;
1008: default:
1009: RETURN_NULL();
1010: break;
1011: }
1012: }
1013: /* }}} */
1014: #else
1015: /* {{{ mixed mysqli_stmt_fetch_mysqlnd */
1016: void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
1017: {
1018: MY_STMT *stmt;
1019: zval *mysql_stmt;
1020: zend_bool fetched_anything;
1021:
1022: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1023: return;
1024: }
1025: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1026:
1027: if (FAIL == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
1028: RETURN_BOOL(FALSE);
1029: } else if (fetched_anything == TRUE) {
1030: RETURN_BOOL(TRUE);
1031: } else {
1032: RETURN_NULL();
1033: }
1034: }
1035: #endif
1036: /* }}} */
1037:
1038:
1039: /* {{{ proto mixed mysqli_stmt_fetch(object stmt) U
1040: Fetch results from a prepared statement into the bound variables */
1041: PHP_FUNCTION(mysqli_stmt_fetch)
1042: {
1043: #if !defined(MYSQLI_USE_MYSQLND)
1044: mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1045: #else
1046: mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1047: #endif
1048: }
1049: /* }}} */
1050:
1051: /* {{{ php_add_field_properties */
1052: static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC)
1053: {
1.1.1.2 misho 1054: add_property_string(value, "name",(field->name ? field->name : ""), 1);
1055: add_property_string(value, "orgname",(field->org_name ? field->org_name : ""), 1);
1056: add_property_string(value, "table",(field->table ? field->table : ""), 1);
1057: add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""), 1);
1058: add_property_string(value, "def",(field->def ? field->def : ""), 1);
1059: add_property_string(value, "db",(field->db ? field->db : ""), 1);
1.1 misho 1060:
1061: /* FIXME: manually set the catalog to "def" due to bug in
1062: * libmysqlclient which does not initialize field->catalog
1063: * and in addition, the catalog is always be "def"
1064: */
1065: add_property_string(value, "catalog", "def", 1);
1066:
1067: add_property_long(value, "max_length", field->max_length);
1068: add_property_long(value, "length", field->length);
1069: add_property_long(value, "charsetnr", field->charsetnr);
1070: add_property_long(value, "flags", field->flags);
1071: add_property_long(value, "type", field->type);
1072: add_property_long(value, "decimals", field->decimals);
1073: }
1074: /* }}} */
1075:
1076: /* {{{ proto mixed mysqli_fetch_field (object result)
1077: Get column information from a result and return as an object */
1078: PHP_FUNCTION(mysqli_fetch_field)
1079: {
1080: MYSQL_RES *result;
1081: zval *mysql_result;
1082: const MYSQL_FIELD *field;
1083:
1084: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1085: return;
1086: }
1087:
1088: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1089:
1090: if (!(field = mysql_fetch_field(result))) {
1091: RETURN_FALSE;
1092: }
1093:
1094: object_init(return_value);
1095: php_add_field_properties(return_value, field TSRMLS_CC);
1096: }
1097: /* }}} */
1098:
1099: /* {{{ proto mixed mysqli_fetch_fields (object result)
1100: Return array of objects containing field meta-data */
1101: PHP_FUNCTION(mysqli_fetch_fields)
1102: {
1103: MYSQL_RES *result;
1104: zval *mysql_result;
1105: zval *obj;
1106:
1107: unsigned int i;
1108:
1109: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1110: return;
1111: }
1112:
1113: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1114:
1115: array_init(return_value);
1116:
1117: for (i = 0; i < mysql_num_fields(result); i++) {
1118: const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
1119:
1120: MAKE_STD_ZVAL(obj);
1121: object_init(obj);
1122:
1123: php_add_field_properties(obj, field TSRMLS_CC);
1124: add_index_zval(return_value, i, obj);
1125: }
1126: }
1127: /* }}} */
1128:
1129: /* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset)
1130: Fetch meta-data for a single field */
1131: PHP_FUNCTION(mysqli_fetch_field_direct)
1132: {
1133: MYSQL_RES *result;
1134: zval *mysql_result;
1135: const MYSQL_FIELD *field;
1136: long offset;
1137:
1138: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
1139: return;
1140: }
1141:
1142: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1143:
1144: if (offset < 0 || offset >= (long) mysql_num_fields(result)) {
1145: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field offset is invalid for resultset");
1146: RETURN_FALSE;
1147: }
1148:
1149: if (!(field = mysql_fetch_field_direct(result,offset))) {
1150: RETURN_FALSE;
1151: }
1152:
1153: object_init(return_value);
1154: php_add_field_properties(return_value, field TSRMLS_CC);
1155: }
1156: /* }}} */
1157:
1158: /* {{{ proto mixed mysqli_fetch_lengths (object result)
1159: Get the length of each output in a result */
1160: PHP_FUNCTION(mysqli_fetch_lengths)
1161: {
1162: MYSQL_RES *result;
1163: zval *mysql_result;
1164: unsigned int i;
1165: unsigned long *ret;
1166:
1167: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1168: return;
1169: }
1170:
1171: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1172:
1173: if (!(ret = mysql_fetch_lengths(result))) {
1174: RETURN_FALSE;
1175: }
1176:
1177: array_init(return_value);
1178:
1179: for (i = 0; i < mysql_num_fields(result); i++) {
1180: add_index_long(return_value, i, ret[i]);
1181: }
1182: }
1183: /* }}} */
1184:
1185: /* {{{ proto array mysqli_fetch_row (object result)
1186: Get a result row as an enumerated array */
1187: PHP_FUNCTION(mysqli_fetch_row)
1188: {
1189: php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
1190: }
1191: /* }}} */
1192:
1193: /* {{{ proto int mysqli_field_count(object link)
1194: Fetch the number of fields returned by the last query for the given link
1195: */
1196: PHP_FUNCTION(mysqli_field_count)
1197: {
1198: MY_MYSQL *mysql;
1199: zval *mysql_link;
1200:
1201: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1202: return;
1203: }
1204: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1205:
1206: RETURN_LONG(mysql_field_count(mysql->mysql));
1207: }
1208: /* }}} */
1209:
1210: /* {{{ proto int mysqli_field_seek(object result, int fieldnr)
1211: Set result pointer to a specified field offset
1212: */
1213: PHP_FUNCTION(mysqli_field_seek)
1214: {
1215: MYSQL_RES *result;
1216: zval *mysql_result;
1217: unsigned long fieldnr;
1218:
1219: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
1220: return;
1221: }
1222: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1223:
1224: if (fieldnr < 0 || fieldnr >= mysql_num_fields(result)) {
1225: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");
1226: RETURN_FALSE;
1227: }
1228:
1229: mysql_field_seek(result, fieldnr);
1230: RETURN_TRUE;
1231: }
1232: /* }}} */
1233:
1234: /* {{{ proto int mysqli_field_tell(object result)
1235: Get current field offset of result pointer */
1236: PHP_FUNCTION(mysqli_field_tell)
1237: {
1238: MYSQL_RES *result;
1239: zval *mysql_result;
1240:
1241: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1242: return;
1243: }
1244: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1245:
1246: RETURN_LONG(mysql_field_tell(result));
1247: }
1248: /* }}} */
1249:
1250: /* {{{ proto void mysqli_free_result(object result)
1251: Free query result memory for the given result handle */
1252: PHP_FUNCTION(mysqli_free_result)
1253: {
1254: MYSQL_RES *result;
1255: zval *mysql_result;
1256:
1257: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1258: return;
1259: }
1260: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1261:
1262: mysqli_free_result(result, FALSE);
1263: MYSQLI_CLEAR_RESOURCE(&mysql_result);
1264: }
1265: /* }}} */
1266:
1267: /* {{{ proto string mysqli_get_client_info(void)
1268: Get MySQL client info */
1269: PHP_FUNCTION(mysqli_get_client_info)
1270: {
1271: RETURN_STRING((char *)mysql_get_client_info(), 1);
1272: }
1273: /* }}} */
1274:
1275: /* {{{ proto int mysqli_get_client_version(void)
1276: Get MySQL client info */
1277: PHP_FUNCTION(mysqli_get_client_version)
1278: {
1279: RETURN_LONG((long)mysql_get_client_version());
1280: }
1281: /* }}} */
1282:
1283: /* {{{ proto string mysqli_get_host_info (object link)
1284: Get MySQL host info */
1285: PHP_FUNCTION(mysqli_get_host_info)
1286: {
1287: MY_MYSQL *mysql;
1288: zval *mysql_link = NULL;
1289:
1290: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1291: return;
1292: }
1293: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1.1.1.2 misho 1294: #if !defined(MYSQLI_USE_MYSQLND)
1.1 misho 1295: RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1);
1.1.1.2 misho 1296: #else
1297: RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "", 1);
1298: #endif
1.1 misho 1299: }
1300: /* }}} */
1301:
1302: /* {{{ proto int mysqli_get_proto_info(object link)
1303: Get MySQL protocol information */
1304: PHP_FUNCTION(mysqli_get_proto_info)
1305: {
1306: MY_MYSQL *mysql;
1307: zval *mysql_link = NULL;
1308:
1309: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1310: return;
1311: }
1312: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1313: RETURN_LONG(mysql_get_proto_info(mysql->mysql));
1314: }
1315: /* }}} */
1316:
1317: /* {{{ proto string mysqli_get_server_info(object link)
1318: Get MySQL server info */
1319: PHP_FUNCTION(mysqli_get_server_info)
1320: {
1321: MY_MYSQL *mysql;
1322: zval *mysql_link = NULL;
1323:
1324: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1325: return;
1326: }
1327: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1328:
1329: RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1);
1330: }
1331:
1332: /* }}} */
1333:
1334: /* {{{ proto int mysqli_get_server_version(object link)
1335: Return the MySQL version for the server referenced by the given link */
1336: PHP_FUNCTION(mysqli_get_server_version)
1337: {
1338: MY_MYSQL *mysql;
1339: zval *mysql_link = NULL;
1340:
1341: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1342: return;
1343: }
1344: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1345:
1346: RETURN_LONG(mysql_get_server_version(mysql->mysql));
1347: }
1348: /* }}} */
1349:
1350: /* {{{ proto string mysqli_info(object link)
1351: Get information about the most recent query */
1352: PHP_FUNCTION(mysqli_info)
1353: {
1354: MY_MYSQL *mysql;
1355: zval *mysql_link = NULL;
1356: const char *info;
1357:
1358: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1359: return;
1360: }
1361: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1362:
1363: info = mysql_info(mysql->mysql);
1364: RETURN_STRING((info) ? (char *)info : "", 1);
1365: }
1366: /* }}} */
1367:
1368:
1369: /* {{{ php_mysqli_init() */
1370: void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS)
1371: {
1372: MYSQLI_RESOURCE *mysqli_resource;
1373: MY_MYSQL *mysql;
1374:
1375: if (getThis() && ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr) {
1376: return;
1377: }
1378:
1379: mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
1380:
1381: #if !defined(MYSQLI_USE_MYSQLND)
1382: if (!(mysql->mysql = mysql_init(NULL)))
1383: #else
1384: /*
1385: We create always persistent, as if the user want to connecto
1386: to p:somehost, we can't convert the handle then
1387: */
1388: if (!(mysql->mysql = mysql_init(TRUE)))
1389: #endif
1390: {
1391: efree(mysql);
1392: RETURN_FALSE;
1393: }
1394:
1395: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1396: mysqli_resource->ptr = (void *)mysql;
1397: mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
1398:
1399: if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC)) {
1400: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
1401: } else {
1402: ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
1403: }
1404: }
1405: /* }}} */
1406:
1407:
1408: /* {{{ proto resource mysqli_init(void)
1409: Initialize mysqli and return a resource for use with mysql_real_connect */
1410: PHP_FUNCTION(mysqli_init)
1411: {
1412: php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1413: }
1414: /* }}} */
1415:
1416: /* {{{ proto mixed mysqli_insert_id(object link)
1417: Get the ID generated from the previous INSERT operation */
1418: PHP_FUNCTION(mysqli_insert_id)
1419: {
1420: MY_MYSQL *mysql;
1421: my_ulonglong rc;
1422: zval *mysql_link;
1423:
1424: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1425: return;
1426: }
1427: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1428: rc = mysql_insert_id(mysql->mysql);
1429: MYSQLI_RETURN_LONG_LONG(rc)
1430: }
1431: /* }}} */
1432:
1433: /* {{{ proto bool mysqli_kill(object link, int processid)
1434: Kill a mysql process on the server */
1435: PHP_FUNCTION(mysqli_kill)
1436: {
1437: MY_MYSQL *mysql;
1438: zval *mysql_link;
1439: long processid;
1440:
1441: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
1442: return;
1443: }
1444: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1445:
1446: if (processid <= 0) {
1447: php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value");
1448: RETURN_FALSE;
1449: }
1450:
1451: if (mysql_kill(mysql->mysql, processid)) {
1452: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1453: RETURN_FALSE;
1454: }
1455: RETURN_TRUE;
1456: }
1457: /* }}} */
1458:
1459: /* {{{ proto void mysqli_set_local_infile_default(object link)
1460: unsets user defined handler for load local infile command */
1461: #if !defined(MYSQLI_USE_MYSQLND)
1462: PHP_FUNCTION(mysqli_set_local_infile_default)
1463: {
1464: MY_MYSQL *mysql;
1465: zval *mysql_link;
1466:
1467: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1468: return;
1469: }
1470:
1471: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1472:
1473: if (mysql->li_read) {
1474: zval_ptr_dtor(&(mysql->li_read));
1475: mysql->li_read = NULL;
1476: }
1477: }
1478: /* }}} */
1479:
1480: /* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
1481: Set callback functions for LOAD DATA LOCAL INFILE */
1482: PHP_FUNCTION(mysqli_set_local_infile_handler)
1483: {
1484: MY_MYSQL *mysql;
1485: zval *mysql_link;
1486: char *callback_name;
1487: zval *callback_func;
1488:
1489: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
1490: &callback_func) == FAILURE) {
1491: return;
1492: }
1493:
1494: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1495:
1496: /* check callback function */
1497: if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
1498: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
1499: efree(callback_name);
1500: RETURN_FALSE;
1501: }
1502: efree(callback_name);
1503:
1504: /* save callback function */
1505: if (!mysql->li_read) {
1506: MAKE_STD_ZVAL(mysql->li_read);
1507: } else {
1508: zval_dtor(mysql->li_read);
1509: }
1510: ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0);
1511:
1512: RETURN_TRUE;
1513: }
1514: #endif
1515: /* }}} */
1516:
1517: /* {{{ proto bool mysqli_more_results(object link)
1518: check if there any more query results from a multi query */
1519: PHP_FUNCTION(mysqli_more_results)
1520: {
1521: MY_MYSQL *mysql;
1522: zval *mysql_link;
1523:
1524: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1525: return;
1526: }
1527: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1528:
1529: RETURN_BOOL(mysql_more_results(mysql->mysql));
1530: }
1531: /* }}} */
1532:
1533: /* {{{ proto bool mysqli_next_result(object link)
1534: read next result from multi_query */
1535: PHP_FUNCTION(mysqli_next_result) {
1536: MY_MYSQL *mysql;
1537: zval *mysql_link;
1538:
1539: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1540: return;
1541: }
1542: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1543:
1544: if (!mysql_more_results(mysql->mysql)) {
1545: php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
1546: "Please, call mysqli_more_results()/mysqli::more_results() to check "
1547: "whether to call this function/method");
1548: }
1549:
1550: RETURN_BOOL(!mysql_next_result(mysql->mysql));
1551: }
1552: /* }}} */
1553:
1554: #if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND)
1555: /* {{{ proto bool mysqli_stmt_next_result(object link)
1556: check if there any more query results from a multi query */
1557: PHP_FUNCTION(mysqli_stmt_more_results)
1558: {
1559: MY_STMT *stmt;
1560: zval *mysql_stmt;
1561:
1562: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1563: return;
1564: }
1565: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1566:
1567: RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
1568: }
1569: /* }}} */
1570:
1571:
1572: /* {{{ proto bool mysqli_stmt_next_result(object link)
1573: read next result from multi_query */
1574: PHP_FUNCTION(mysqli_stmt_next_result) {
1575: MY_STMT *stmt;
1576: zval *mysql_stmt;
1577:
1578: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1579: return;
1580: }
1581: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1582:
1583: if (!mysqlnd_stmt_more_results(stmt->stmt)) {
1584: php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
1585: "Please, call mysqli_stmt_more_results()/mysqli_stmt::more_results() to check "
1586: "whether to call this function/method");
1587: }
1588:
1589: RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt));
1590: }
1591: /* }}} */
1592: #endif
1593:
1594:
1595: /* {{{ proto int mysqli_num_fields(object result)
1596: Get number of fields in result */
1597: PHP_FUNCTION(mysqli_num_fields)
1598: {
1599: MYSQL_RES *result;
1600: zval *mysql_result;
1601:
1602: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1603: return;
1604: }
1605: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1606:
1607: RETURN_LONG(mysql_num_fields(result));
1608: }
1609: /* }}} */
1610:
1611: /* {{{ proto mixed mysqli_num_rows(object result)
1612: Get number of rows in result */
1613: PHP_FUNCTION(mysqli_num_rows)
1614: {
1615: MYSQL_RES *result;
1616: zval *mysql_result;
1617:
1618: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1619: return;
1620: }
1621: MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1622:
1623: if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
1624: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
1625: RETURN_LONG(0);
1626: }
1627:
1628: MYSQLI_RETURN_LONG_LONG(mysql_num_rows(result));
1629: }
1630: /* }}} */
1631:
1632: /* {{{ mysqli_options_get_option_zval_type */
1633: static int mysqli_options_get_option_zval_type(int option)
1634: {
1635: switch (option) {
1636: #ifdef MYSQLI_USE_MYSQLND
1637: #if PHP_MAJOR_VERSION >= 6
1638: case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
1639: #endif
1640: case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
1641: case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
1642: #ifdef MYSQLND_STRING_TO_INT_CONVERSION
1643: case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
1644: #endif
1645: #endif /* MYSQLI_USE_MYSQLND */
1646: case MYSQL_OPT_CONNECT_TIMEOUT:
1647: #ifdef MYSQL_REPORT_DATA_TRUNCATION
1648: case MYSQL_REPORT_DATA_TRUNCATION:
1649: #endif
1650: case MYSQL_OPT_LOCAL_INFILE:
1651: case MYSQL_OPT_NAMED_PIPE:
1652: #ifdef MYSQL_OPT_PROTOCOL
1653: case MYSQL_OPT_PROTOCOL:
1654: #endif /* MySQL 4.1.0 */
1655: #ifdef MYSQL_OPT_READ_TIMEOUT
1656: case MYSQL_OPT_READ_TIMEOUT:
1657: case MYSQL_OPT_WRITE_TIMEOUT:
1658: case MYSQL_OPT_GUESS_CONNECTION:
1659: case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
1660: case MYSQL_OPT_USE_REMOTE_CONNECTION:
1661: case MYSQL_SECURE_AUTH:
1662: #endif /* MySQL 4.1.1 */
1663: #ifdef MYSQL_OPT_RECONNECT
1664: case MYSQL_OPT_RECONNECT:
1665: #endif /* MySQL 5.0.13 */
1666: #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
1667: case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
1668: #endif /* MySQL 5.0.23 */
1669: #ifdef MYSQL_OPT_COMPRESS
1670: case MYSQL_OPT_COMPRESS:
1671: #endif /* mysqlnd @ PHP 5.3.2 */
1672: #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
1673: REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
1674: #endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */
1.1.1.3 ! misho 1675: #if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
! 1676: case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
! 1677: #endif
1.1 misho 1678: return IS_LONG;
1679:
1680: #ifdef MYSQL_SHARED_MEMORY_BASE_NAME
1681: case MYSQL_SHARED_MEMORY_BASE_NAME:
1682: #endif /* MySQL 4.1.0 */
1683: #ifdef MYSQL_SET_CLIENT_IP
1684: case MYSQL_SET_CLIENT_IP:
1685: #endif /* MySQL 4.1.1 */
1686: case MYSQL_READ_DEFAULT_FILE:
1687: case MYSQL_READ_DEFAULT_GROUP:
1688: case MYSQL_INIT_COMMAND:
1689: case MYSQL_SET_CHARSET_NAME:
1690: case MYSQL_SET_CHARSET_DIR:
1691: return IS_STRING;
1692:
1693: default:
1694: return IS_NULL;
1695: }
1696: }
1697: /* }}} */
1698:
1699:
1700: /* {{{ proto bool mysqli_options(object link, int flags, mixed values)
1701: Set options */
1702: PHP_FUNCTION(mysqli_options)
1703: {
1704: MY_MYSQL *mysql;
1705: zval *mysql_link = NULL;
1706: zval **mysql_value;
1707: long mysql_option;
1708: unsigned int l_value;
1709: long ret;
1710: int expected_type;
1711:
1712: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OlZ", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
1713: return;
1714: }
1715: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
1716:
1717: #if PHP_API_VERSION < 20100412
1718: if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
1719: #else
1720: if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
1721: #endif
1722: if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
1723: RETURN_FALSE;
1724: }
1725: }
1726: expected_type = mysqli_options_get_option_zval_type(mysql_option);
1727: if (expected_type != Z_TYPE_PP(mysql_value)) {
1728: switch (expected_type) {
1729: case IS_STRING:
1730: convert_to_string_ex(mysql_value);
1731: break;
1732: case IS_LONG:
1733: convert_to_long_ex(mysql_value);
1734: break;
1735: default:
1736: break;
1737: }
1738: }
1739: switch (expected_type) {
1740: case IS_STRING:
1741: ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(mysql_value));
1742: break;
1743: case IS_LONG:
1744: l_value = Z_LVAL_PP(mysql_value);
1745: ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
1746: break;
1747: default:
1748: ret = 1;
1749: break;
1750: }
1751:
1752: RETURN_BOOL(!ret);
1753: }
1754: /* }}} */
1755:
1756:
1757: /* {{{ proto bool mysqli_ping(object link)
1758: Ping a server connection or reconnect if there is no connection */
1759: PHP_FUNCTION(mysqli_ping)
1760: {
1761: MY_MYSQL *mysql;
1762: zval *mysql_link;
1763: long rc;
1764:
1765: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1766: return;
1767: }
1768: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1769: rc = mysql_ping(mysql->mysql);
1770: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1771:
1772: RETURN_BOOL(!rc);
1773: }
1774: /* }}} */
1775:
1776: /* {{{ proto mixed mysqli_prepare(object link, string query)
1777: Prepare a SQL statement for execution */
1778: PHP_FUNCTION(mysqli_prepare)
1779: {
1780: MY_MYSQL *mysql;
1781: MY_STMT *stmt;
1782: char *query = NULL;
1783: int query_len;
1784: zval *mysql_link;
1785: MYSQLI_RESOURCE *mysqli_resource;
1786:
1787: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1788: return;
1789: }
1790: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1791:
1792: #if !defined(MYSQLI_USE_MYSQLND)
1793: if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
1794: php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");
1795: RETURN_FALSE;
1796: }
1797: #endif
1798:
1799: stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
1800:
1801: if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
1802: if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
1803: /* mysql_stmt_close() clears errors, so we have to store them temporarily */
1804: #if !defined(MYSQLI_USE_MYSQLND)
1805: char last_error[MYSQL_ERRMSG_SIZE];
1806: char sqlstate[SQLSTATE_LENGTH+1];
1807: unsigned int last_errno;
1808:
1809: last_errno = stmt->stmt->last_errno;
1810: memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
1811: memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
1812: #else
1.1.1.2 misho 1813: MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
1.1 misho 1814: #endif
1815: mysqli_stmt_close(stmt->stmt, FALSE);
1816: stmt->stmt = NULL;
1817:
1818: /* restore error messages */
1819: #if !defined(MYSQLI_USE_MYSQLND)
1820: mysql->mysql->net.last_errno = last_errno;
1821: memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
1822: memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
1823: #else
1.1.1.2 misho 1824: *mysql->mysql->data->error_info = error_info;
1.1 misho 1825: #endif
1826: }
1827: }
1828:
1829: /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
1830: /* Get performance boost if reporting is switched off */
1831: if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
1832: stmt->query = (char *)emalloc(query_len + 1);
1833: memcpy(stmt->query, query, query_len);
1834: stmt->query[query_len] = '\0';
1835: }
1836:
1837: /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
1838: if (!stmt->stmt) {
1839: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1840: efree(stmt);
1841: RETURN_FALSE;
1842: }
1843:
1844: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1845: mysqli_resource->ptr = (void *)stmt;
1846:
1847: /* change status */
1848: mysqli_resource->status = MYSQLI_STATUS_VALID;
1849: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
1850: }
1851: /* }}} */
1852:
1853:
1854: /* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])
1855: Open a connection to a mysql server */
1856: PHP_FUNCTION(mysqli_real_connect)
1857: {
1858: mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE, FALSE);
1859: }
1860: /* }}} */
1861:
1862:
1863: /* {{{ proto bool mysqli_real_query(object link, string query)
1864: Binary-safe version of mysql_query() */
1865: PHP_FUNCTION(mysqli_real_query)
1866: {
1867: MY_MYSQL *mysql;
1868: zval *mysql_link;
1869: char *query = NULL;
1870: int query_len;
1871:
1872: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1873: return;
1874: }
1875: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1876:
1877: MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
1878:
1879: if (mysql_real_query(mysql->mysql, query, query_len)) {
1880: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1881: RETURN_FALSE;
1882: }
1883:
1884: if (!mysql_field_count(mysql->mysql)) {
1885: if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1886: php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
1887: }
1888: }
1889:
1890: RETURN_TRUE;
1891: }
1892: /* }}} */
1893:
1894: /* {{{ proto string mysqli_real_escape_string(object link, string escapestr)
1895: Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
1896: PHP_FUNCTION(mysqli_real_escape_string) {
1897: MY_MYSQL *mysql;
1898: zval *mysql_link = NULL;
1899: char *escapestr, *newstr;
1900: int escapestr_len, newstr_len;
1901:
1902: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
1903: return;
1904: }
1905: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1906:
1907: newstr = safe_emalloc(2, escapestr_len, 1);
1908: newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len);
1909: newstr = erealloc(newstr, newstr_len + 1);
1910:
1911: RETURN_STRINGL(newstr, newstr_len, 0);
1912: }
1913: /* }}} */
1914:
1915: /* {{{ proto bool mysqli_rollback(object link)
1916: Undo actions from current transaction */
1917: PHP_FUNCTION(mysqli_rollback)
1918: {
1919: MY_MYSQL *mysql;
1920: zval *mysql_link;
1921:
1922: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1923: return;
1924: }
1925: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
1926:
1927: if (mysql_rollback(mysql->mysql)) {
1928: RETURN_FALSE;
1929: }
1930: RETURN_TRUE;
1931: }
1932: /* }}} */
1933:
1934: /* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)
1935: */
1936: PHP_FUNCTION(mysqli_stmt_send_long_data)
1937: {
1938: MY_STMT *stmt;
1939: zval *mysql_stmt;
1940: char *data;
1941: long param_nr;
1942: int data_len;
1943:
1944: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) {
1945: return;
1946: }
1947: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1948:
1949: if (param_nr < 0) {
1950: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number");
1951: RETURN_FALSE;
1952: }
1953: if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
1954: RETURN_FALSE;
1955: }
1956: RETURN_TRUE;
1957: }
1958: /* }}} */
1959:
1960:
1961: /* {{{ proto mixed mysqli_stmt_affected_rows(object stmt)
1962: Return the number of rows affected in the last query for the given link */
1963: PHP_FUNCTION(mysqli_stmt_affected_rows)
1964: {
1965: MY_STMT *stmt;
1966: zval *mysql_stmt;
1967: my_ulonglong rc;
1968:
1969: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1970: return;
1971: }
1972: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1973:
1974: rc = mysql_stmt_affected_rows(stmt->stmt);
1975: if (rc == (my_ulonglong) -1) {
1976: RETURN_LONG(-1);
1977: }
1978: MYSQLI_RETURN_LONG_LONG(rc)
1979: }
1980: /* }}} */
1981:
1982: /* {{{ proto bool mysqli_stmt_close(object stmt)
1983: Close statement */
1984: PHP_FUNCTION(mysqli_stmt_close)
1985: {
1986: MY_STMT *stmt;
1987: zval *mysql_stmt;
1988:
1989: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1990: return;
1991: }
1992: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
1993:
1994: mysqli_stmt_close(stmt->stmt, FALSE);
1995: stmt->stmt = NULL;
1996: php_clear_stmt_bind(stmt TSRMLS_CC);
1997: MYSQLI_CLEAR_RESOURCE(&mysql_stmt);
1998: RETURN_TRUE;
1999: }
2000: /* }}} */
2001:
2002: /* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset)
2003: Move internal result pointer */
2004: PHP_FUNCTION(mysqli_stmt_data_seek)
2005: {
2006: MY_STMT *stmt;
2007: zval *mysql_stmt;
2008: long offset;
2009:
2010: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
2011: return;
2012: }
2013: if (offset < 0) {
2014: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be positive");
2015: RETURN_FALSE;
2016: }
2017:
2018: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2019:
2020: mysql_stmt_data_seek(stmt->stmt, offset);
2021: }
2022: /* }}} */
2023:
2024: /* {{{ proto int mysqli_stmt_field_count(object stmt) {
2025: Return the number of result columns for the given statement */
2026: PHP_FUNCTION(mysqli_stmt_field_count)
2027: {
2028: MY_STMT *stmt;
2029: zval *mysql_stmt;
2030:
2031: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2032: return;
2033: }
2034: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2035:
2036: RETURN_LONG(mysql_stmt_field_count(stmt->stmt));
2037: }
2038: /* }}} */
2039:
2040: /* {{{ proto void mysqli_stmt_free_result(object stmt)
2041: Free stored result memory for the given statement handle */
2042: PHP_FUNCTION(mysqli_stmt_free_result)
2043: {
2044: MY_STMT *stmt;
2045: zval *mysql_stmt;
2046:
2047: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2048: return;
2049: }
2050:
2051: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2052:
2053: mysql_stmt_free_result(stmt->stmt);
2054: }
2055: /* }}} */
2056:
2057: /* {{{ proto mixed mysqli_stmt_insert_id(object stmt)
2058: Get the ID generated from the previous INSERT operation */
2059: PHP_FUNCTION(mysqli_stmt_insert_id)
2060: {
2061: MY_STMT *stmt;
2062: my_ulonglong rc;
2063: zval *mysql_stmt;
2064:
2065: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2066: return;
2067: }
2068: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2069: rc = mysql_stmt_insert_id(stmt->stmt);
2070: MYSQLI_RETURN_LONG_LONG(rc)
2071: }
2072: /* }}} */
2073:
2074: /* {{{ proto int mysqli_stmt_param_count(object stmt)
2075: Return the number of parameter for the given statement */
2076: PHP_FUNCTION(mysqli_stmt_param_count)
2077: {
2078: MY_STMT *stmt;
2079: zval *mysql_stmt;
2080:
2081: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2082: return;
2083: }
2084: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2085:
2086: RETURN_LONG(mysql_stmt_param_count(stmt->stmt));
2087: }
2088: /* }}} */
2089:
2090: /* {{{ proto bool mysqli_stmt_reset(object stmt)
2091: reset a prepared statement */
2092: PHP_FUNCTION(mysqli_stmt_reset)
2093: {
2094: MY_STMT *stmt;
2095: zval *mysql_stmt;
2096:
2097: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2098: return;
2099: }
2100:
2101: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2102:
2103: if (mysql_stmt_reset(stmt->stmt)) {
2104: RETURN_FALSE;
2105: }
2106: RETURN_TRUE;
2107: }
2108: /* }}} */
2109:
2110: /* {{{ proto mixed mysqli_stmt_num_rows(object stmt)
2111: Return the number of rows in statements result set */
2112: PHP_FUNCTION(mysqli_stmt_num_rows)
2113: {
2114: MY_STMT *stmt;
2115: zval *mysql_stmt;
2116: my_ulonglong rc;
2117:
2118: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2119: return;
2120: }
2121:
2122: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2123:
2124: rc = mysql_stmt_num_rows(stmt->stmt);
2125: MYSQLI_RETURN_LONG_LONG(rc)
2126: }
2127: /* }}} */
2128:
2129: /* {{{ proto bool mysqli_select_db(object link, string dbname)
2130: Select a MySQL database */
2131: PHP_FUNCTION(mysqli_select_db)
2132: {
2133: MY_MYSQL *mysql;
2134: zval *mysql_link;
2135: char *dbname;
2136: int dbname_len;
2137:
2138: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
2139: return;
2140: }
2141: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2142:
2143: if (mysql_select_db(mysql->mysql, dbname)) {
2144: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2145: RETURN_FALSE;
2146: }
2147: RETURN_TRUE;
2148: }
2149: /* }}} */
2150:
2151: /* {{{ proto string mysqli_sqlstate(object link)
2152: Returns the SQLSTATE error from previous MySQL operation */
2153: PHP_FUNCTION(mysqli_sqlstate)
2154: {
2155: MY_MYSQL *mysql;
2156: zval *mysql_link;
2157:
2158: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2159: return;
2160: }
2161: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2162: RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1);
2163: }
2164: /* }}} */
2165:
2166: /* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U
2167: */
2168: PHP_FUNCTION(mysqli_ssl_set)
2169: {
2170: MY_MYSQL *mysql;
2171: zval *mysql_link;
2172: char *ssl_parm[5];
2173: int ssl_parm_len[5], i;
2174:
2175: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4]) == FAILURE) {
2176: return;
2177: }
2178: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
2179:
2180: for (i = 0; i < 5; i++) {
2181: if (!ssl_parm_len[i]) {
2182: ssl_parm[i] = NULL;
2183: }
2184: }
2185:
2186: mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]);
2187:
2188: RETURN_TRUE;
2189: }
2190: /* }}} */
2191:
2192: /* {{{ proto mixed mysqli_stat(object link)
2193: Get current system status */
2194: PHP_FUNCTION(mysqli_stat)
2195: {
2196: MY_MYSQL *mysql;
2197: zval *mysql_link;
2198: char *stat;
2199: #if defined(MYSQLI_USE_MYSQLND)
2200: uint stat_len;
2201: #endif
2202:
2203: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2204: return;
2205: }
2206: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2207:
2208: #if !defined(MYSQLI_USE_MYSQLND)
2209: if ((stat = (char *)mysql_stat(mysql->mysql)))
2210: {
2211: RETURN_STRING(stat, 1);
2212: #else
2213: if (mysqlnd_stat(mysql->mysql, &stat, &stat_len) == PASS)
2214: {
2215: RETURN_STRINGL(stat, stat_len, 0);
2216: #endif
2217: } else {
2218: RETURN_FALSE;
2219: }
2220: }
2221:
2222: /* }}} */
2223:
2224: /* {{{ proto bool mysqli_refresh(object link, long options)
2225: Flush tables or caches, or reset replication server information */
2226: PHP_FUNCTION(mysqli_refresh)
2227: {
2228: MY_MYSQL *mysql;
2229: zval *mysql_link = NULL;
2230: long options;
2231:
2232: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) {
2233: return;
2234: }
2235: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
2236: #ifdef MYSQLI_USE_MYSQLND
2237: RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
2238: #else
2239: RETURN_BOOL(!mysql_refresh(mysql->mysql, options));
2240: #endif
2241: }
2242: /* }}} */
2243:
2244: /* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode)
2245: */
2246: PHP_FUNCTION(mysqli_stmt_attr_set)
2247: {
2248: MY_STMT *stmt;
2249: zval *mysql_stmt;
2250: long mode_in;
2251: #if MYSQL_VERSION_ID >= 50107
2252: my_bool mode_b;
2253: #endif
2254: ulong mode;
2255: ulong attr;
2256: void *mode_p;
2257:
2258: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
2259: return;
2260: }
2261: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2262:
2263: if (mode_in < 0) {
2264: php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %ld passed", mode_in);
2265: RETURN_FALSE;
2266: }
2267:
2268: switch (attr) {
2269: #if MYSQL_VERSION_ID >= 50107
2270: case STMT_ATTR_UPDATE_MAX_LENGTH:
2271: mode_b = (my_bool) mode_in;
2272: mode_p = &mode_b;
2273: break;
2274: #endif
2275: default:
2276: mode = mode_in;
2277: mode_p = &mode;
2278: break;
2279: }
2280: #if !defined(MYSQLI_USE_MYSQLND)
2281: if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
2282: #else
2283: if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
2284: #endif
2285: RETURN_FALSE;
2286: }
2287: RETURN_TRUE;
2288: }
2289: /* }}} */
2290:
2291: /* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr)
2292: */
2293: PHP_FUNCTION(mysqli_stmt_attr_get)
2294: {
2295: MY_STMT *stmt;
2296: zval *mysql_stmt;
2297: ulong value = 0;
2298: ulong attr;
2299: int rc;
2300:
2301: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
2302: return;
2303: }
2304: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2305:
2306: if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
2307: RETURN_FALSE;
2308: }
2309:
2310: #if MYSQL_VERSION_ID >= 50107
2311: if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
2312: value = *((my_bool *)&value);
2313: #endif
2314: RETURN_LONG((long)value);
2315: }
2316: /* }}} */
2317:
2318: /* {{{ proto int mysqli_stmt_errno(object stmt)
2319: */
2320: PHP_FUNCTION(mysqli_stmt_errno)
2321: {
2322: MY_STMT *stmt;
2323: zval *mysql_stmt;
2324:
2325: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2326: return;
2327: }
2328: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2329:
2330: RETURN_LONG(mysql_stmt_errno(stmt->stmt));
2331: }
2332: /* }}} */
2333:
2334: /* {{{ proto string mysqli_stmt_error(object stmt)
2335: */
2336: PHP_FUNCTION(mysqli_stmt_error)
2337: {
2338: MY_STMT *stmt;
2339: zval *mysql_stmt;
2340:
2341: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2342: return;
2343: }
2344: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2345:
2346: RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1);
2347: }
2348: /* }}} */
2349:
2350: /* {{{ proto mixed mysqli_stmt_init(object link)
2351: Initialize statement object
2352: */
2353: PHP_FUNCTION(mysqli_stmt_init)
2354: {
2355: MY_MYSQL *mysql;
2356: MY_STMT *stmt;
2357: zval *mysql_link;
2358: MYSQLI_RESOURCE *mysqli_resource;
2359:
2360: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
2361: return;
2362: }
2363: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2364:
2365: stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
2366:
2367: if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
2368: efree(stmt);
2369: RETURN_FALSE;
2370: }
2371:
2372: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2373: mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
2374: mysqli_resource->ptr = (void *)stmt;
2375: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
2376: }
2377: /* }}} */
2378:
2379: /* {{{ proto bool mysqli_stmt_prepare(object stmt, string query)
2380: prepare server side statement with query
2381: */
2382: PHP_FUNCTION(mysqli_stmt_prepare)
2383: {
2384: MY_STMT *stmt;
2385: zval *mysql_stmt;
2386: char *query;
2387: int query_len;
2388:
2389: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) {
2390: return;
2391: }
2392: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
2393:
2394: if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
2395: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2396: RETURN_FALSE;
2397: }
2398: /* change status */
2399: MYSQLI_SET_STATUS(&mysql_stmt, MYSQLI_STATUS_VALID);
2400: RETURN_TRUE;
2401: }
2402: /* }}} */
2403:
2404: /* {{{ proto mixed mysqli_stmt_result_metadata(object stmt)
2405: return result set from statement */
2406: PHP_FUNCTION(mysqli_stmt_result_metadata)
2407: {
2408: MY_STMT *stmt;
2409: MYSQL_RES *result;
2410: zval *mysql_stmt;
2411: MYSQLI_RESOURCE *mysqli_resource;
2412:
2413: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2414: return;
2415: }
2416: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2417:
2418: if (!(result = mysql_stmt_result_metadata(stmt->stmt))){
2419: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2420: RETURN_FALSE;
2421: }
2422:
2423: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2424: mysqli_resource->ptr = (void *)result;
2425: mysqli_resource->status = MYSQLI_STATUS_VALID;
2426: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2427: }
2428: /* }}} */
2429:
2430: /* {{{ proto bool mysqli_stmt_store_result(stmt)
2431: */
2432: PHP_FUNCTION(mysqli_stmt_store_result)
2433: {
2434: MY_STMT *stmt;
2435: zval *mysql_stmt;
2436:
2437: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2438: return;
2439: }
2440: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2441:
2442: #if !defined(MYSQLI_USE_MYSQLND)
2443: {
2444: /*
2445: If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
2446: not the maximal length of the type (which is 16MB even for LONGBLOB) but
2447: the maximal length of the field in the result set. If he/she has quite big
2448: BLOB/TEXT columns after calling store_result() the memory usage of PHP will
2449: double - but this is a known problem of the simple MySQL API ;)
2450: */
2451: int i = 0;
2452:
2453: for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
2454: if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
2455: stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
2456: stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
2457: stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
2458: {
2459: #if MYSQL_VERSION_ID >= 50107
2460: my_bool tmp=1;
2461: #else
2462: uint tmp=1;
2463: #endif
2464: mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
2465: break;
2466: }
2467: }
2468: }
2469: #endif
2470:
2471: if (mysql_stmt_store_result(stmt->stmt)){
2472: MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
2473: RETURN_FALSE;
2474: }
2475: RETURN_TRUE;
2476: }
2477: /* }}} */
2478:
2479: /* {{{ proto string mysqli_stmt_sqlstate(object stmt)
2480: */
2481: PHP_FUNCTION(mysqli_stmt_sqlstate)
2482: {
2483: MY_STMT *stmt;
2484: zval *mysql_stmt;
2485:
2486: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
2487: return;
2488: }
2489: MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
2490:
2491: RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);
2492: }
2493: /* }}} */
2494:
2495: /* {{{ proto object mysqli_store_result(object link)
2496: Buffer result set on client */
2497: PHP_FUNCTION(mysqli_store_result)
2498: {
2499: MY_MYSQL *mysql;
2500: MYSQL_RES *result;
2501: zval *mysql_link;
2502: MYSQLI_RESOURCE *mysqli_resource;
2503:
2504: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2505: return;
2506: }
2507: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2508:
2509: if (!(result = mysql_store_result(mysql->mysql))) {
2510: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2511: RETURN_FALSE;
2512: }
2513: if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
2514: php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
2515: }
2516:
2517: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2518: mysqli_resource->ptr = (void *)result;
2519: mysqli_resource->status = MYSQLI_STATUS_VALID;
2520: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2521: }
2522: /* }}} */
2523:
2524:
2525: /* {{{ proto int mysqli_thread_id(object link)
2526: Return the current thread ID */
2527: PHP_FUNCTION(mysqli_thread_id)
2528: {
2529: MY_MYSQL *mysql;
2530: zval *mysql_link;
2531:
2532: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2533: return;
2534: }
2535: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2536:
2537: RETURN_LONG((long) mysql_thread_id(mysql->mysql));
2538: }
2539: /* }}} */
2540:
2541: /* {{{ proto bool mysqli_thread_safe(void)
2542: Return whether thread safety is given or not */
2543: PHP_FUNCTION(mysqli_thread_safe)
2544: {
2545: RETURN_BOOL(mysql_thread_safe());
2546: }
2547: /* }}} */
2548:
2549: /* {{{ proto mixed mysqli_use_result(object link)
2550: Directly retrieve query results - do not buffer results on client side */
2551: PHP_FUNCTION(mysqli_use_result)
2552: {
2553: MY_MYSQL *mysql;
2554: MYSQL_RES *result;
2555: zval *mysql_link;
2556: MYSQLI_RESOURCE *mysqli_resource;
2557:
2558: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2559: return;
2560: }
2561: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2562:
2563: if (!(result = mysql_use_result(mysql->mysql))) {
2564: MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
2565: RETURN_FALSE;
2566: }
2567:
2568: if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
2569: php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
2570: }
2571: mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
2572: mysqli_resource->ptr = (void *)result;
2573: mysqli_resource->status = MYSQLI_STATUS_VALID;
2574: MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
2575: }
2576: /* }}} */
2577:
2578: /* {{{ proto int mysqli_warning_count (object link)
2579: Return number of warnings from the last query for the given link */
2580: PHP_FUNCTION(mysqli_warning_count)
2581: {
2582: MY_MYSQL *mysql;
2583: zval *mysql_link;
2584:
2585: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
2586: return;
2587: }
2588: MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
2589:
2590: RETURN_LONG(mysql_warning_count(mysql->mysql));
2591: }
2592: /* }}} */
2593:
2594: /*
2595: * Local variables:
2596: * tab-width: 4
2597: * c-basic-offset: 4
2598: * End:
2599: * vim600: noet sw=4 ts=4 fdm=marker
2600: * vim<600: noet sw=4 ts=4
2601: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>