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