1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Georg Richter <georg@php.net> |
14 | Andrey Hristov <andrey@php.net> |
15 | Ulf Wendel <uw@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <signal.h>
24
25 #include "php.h"
26 #include "zend_smart_str.h"
27 #include "php_mysqli_structs.h"
28 #include "mysqli_priv.h"
29 #include "ext/mysqlnd/mysql_float_to_double.h"
30
31 #define ERROR_ARG_POS(arg_num) (hasThis() ? (arg_num-1) : (arg_num))
32
33 /* {{{ Get number of affected rows in previous MySQL operation */
PHP_FUNCTION(mysqli_affected_rows)34 PHP_FUNCTION(mysqli_affected_rows)
35 {
36 MY_MYSQL *mysql;
37 zval *mysql_link;
38 my_ulonglong rc;
39
40 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
41 RETURN_THROWS();
42 }
43
44 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
45
46 rc = mysql_affected_rows(mysql->mysql);
47 if (rc == (my_ulonglong) -1) {
48 RETURN_LONG(-1);
49 }
50 MYSQLI_RETURN_LONG_INT(rc);
51 }
52 /* }}} */
53
54 /* {{{ Turn auto commit on or of */
PHP_FUNCTION(mysqli_autocommit)55 PHP_FUNCTION(mysqli_autocommit)
56 {
57 MY_MYSQL *mysql;
58 zval *mysql_link;
59 bool automode;
60
61 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
62 RETURN_THROWS();
63 }
64 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
65
66 if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
67 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
68 RETURN_FALSE;
69 }
70 RETURN_TRUE;
71 }
72 /* }}} */
73
74 /* {{{ mysqli_stmt_bind_param_do_bind */
mysqli_stmt_bind_param_do_bind(MY_STMT * stmt,uint32_t num_vars,zval * args,const char * const types,unsigned int arg_num)75 static enum_func_status mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, uint32_t num_vars, zval *args, const char * const types, unsigned int arg_num)
76 {
77 MYSQLND_PARAM_BIND *params;
78 enum_func_status ret = FAIL;
79
80 /* If no params -> skip binding and return directly */
81 if (num_vars == 0) {
82 return PASS;
83 }
84 params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
85 if (!params) {
86 goto end;
87 }
88 for (uint32_t i = 0; i < num_vars; i++) {
89 uint8_t type;
90 switch (types[i]) {
91 case 'd': /* Double */
92 type = MYSQL_TYPE_DOUBLE;
93 break;
94 case 'i': /* Integer */
95 #if SIZEOF_ZEND_LONG==8
96 type = MYSQL_TYPE_LONGLONG;
97 #elif SIZEOF_ZEND_LONG==4
98 type = MYSQL_TYPE_LONG;
99 #endif
100 break;
101 case 'b': /* Blob (send data) */
102 type = MYSQL_TYPE_LONG_BLOB;
103 break;
104 case 's': /* string */
105 type = MYSQL_TYPE_VAR_STRING;
106 break;
107 default:
108 zend_argument_value_error(arg_num, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers");
109 ret = FAIL;
110 mysqlnd_stmt_free_param_bind(stmt->stmt, params);
111 goto end;
112 }
113 ZVAL_COPY_VALUE(¶ms[i].zv, &args[i]);
114 params[i].type = type;
115 }
116 ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
117
118 end:
119 return ret;
120 }
121 /* }}} */
122
123 /* {{{ Bind variables to a prepared statement as parameters */
PHP_FUNCTION(mysqli_stmt_bind_param)124 PHP_FUNCTION(mysqli_stmt_bind_param)
125 {
126 zval *args;
127 uint32_t argc;
128 MY_STMT *stmt;
129 zval *mysql_stmt;
130 char *types;
131 size_t types_len;
132
133 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os*", &mysql_stmt, mysqli_stmt_class_entry, &types, &types_len, &args, &argc) == FAILURE) {
134 RETURN_THROWS();
135 }
136
137 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
138
139 if (!types_len) {
140 zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2));
141 RETURN_THROWS();
142 }
143
144 if (types_len != (size_t) argc) {
145 /* number of bind variables doesn't match number of elements in type definition string */
146 zend_argument_count_error("The number of elements in the type definition string must match the number of bind variables");
147 RETURN_THROWS();
148 }
149
150 if (types_len != mysql_stmt_param_count(stmt->stmt)) {
151 zend_argument_count_error("The number of variables must match the number of parameters in the prepared statement");
152 RETURN_THROWS();
153 }
154
155 RETVAL_BOOL(mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, ERROR_ARG_POS(2)) == PASS);
156 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
157 }
158 /* }}} */
159
160 /* {{{ mysqli_stmt_bind_result_do_bind */
mysqli_stmt_bind_result_do_bind(MY_STMT * stmt,zval * args,uint32_t argc)161 static enum_func_status mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, uint32_t argc)
162 {
163 MYSQLND_RESULT_BIND *params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
164 if (params) {
165 for (uint32_t i = 0; i < argc; i++) {
166 ZVAL_COPY_VALUE(¶ms[i].zv, &args[i]);
167 }
168 return mysqlnd_stmt_bind_result(stmt->stmt, params);
169 }
170 return FAIL;
171 }
172 /* }}} */
173
174 /* {{{ Bind variables to a prepared statement for result storage */
PHP_FUNCTION(mysqli_stmt_bind_result)175 PHP_FUNCTION(mysqli_stmt_bind_result)
176 {
177 zval *args;
178 uint32_t argc;
179 MY_STMT *stmt;
180 zval *mysql_stmt;
181
182 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O+", &mysql_stmt, mysqli_stmt_class_entry, &args, &argc) == FAILURE) {
183 RETURN_THROWS();
184 }
185
186 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
187
188 if (argc != mysql_stmt_field_count(stmt->stmt)) {
189 zend_argument_count_error("Number of bind variables doesn't match number of fields in prepared statement");
190 RETURN_THROWS();
191 }
192
193 enum_func_status rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc);
194 RETURN_BOOL(rc == PASS);
195 }
196 /* }}} */
197
198 /* {{{ Change logged-in user of the active connection */
PHP_FUNCTION(mysqli_change_user)199 PHP_FUNCTION(mysqli_change_user)
200 {
201 MY_MYSQL *mysql;
202 zval *mysql_link = NULL;
203 char *user, *password, *dbname;
204 size_t user_len, password_len, dbname_len;
205
206 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osss!", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
207 RETURN_THROWS();
208 }
209 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
210
211 enum_func_status rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len);
212 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
213
214 RETURN_BOOL(rc == PASS);
215 }
216 /* }}} */
217
218 /* {{{ Returns the name of the character set used for this connection */
PHP_FUNCTION(mysqli_character_set_name)219 PHP_FUNCTION(mysqli_character_set_name)
220 {
221 MY_MYSQL *mysql;
222 zval *mysql_link;
223
224 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
225 RETURN_THROWS();
226 }
227
228 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
229 RETURN_STRING(mysql_character_set_name(mysql->mysql));
230 }
231 /* }}} */
232
233 /* {{{ php_mysqli_close */
php_mysqli_close(MY_MYSQL * mysql,int close_type,int resource_status)234 void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status)
235 {
236 if (resource_status > MYSQLI_STATUS_INITIALIZED) {
237 MyG(num_links)--;
238 }
239
240 if (!mysql->persistent) {
241 mysqli_close(mysql->mysql, close_type);
242 } else {
243 zend_resource *le;
244 if ((le = zend_hash_find_ptr(&EG(persistent_list), mysql->hash_key)) != NULL) {
245 if (le->type == php_le_pmysqli()) {
246 mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
247 mysqlnd_end_psession(mysql->mysql);
248
249 if (MyG(rollback_on_cached_plink) &&
250 FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
251 {
252 mysqli_close(mysql->mysql, close_type);
253 } else {
254 zend_ptr_stack_push(&plist->free_links, mysql->mysql);
255 MyG(num_inactive_persistent)++;
256 }
257 MyG(num_active_persistent)--;
258 }
259 }
260 mysql->persistent = false;
261 }
262 mysql->mysql = NULL;
263
264 php_clear_mysql(mysql);
265 }
266 /* }}} */
267
268 /* {{{ Close connection */
PHP_FUNCTION(mysqli_close)269 PHP_FUNCTION(mysqli_close)
270 {
271 zval *mysql_link;
272 MY_MYSQL *mysql;
273
274 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
275 RETURN_THROWS();
276 }
277
278 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
279
280 php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status);
281 ((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status = MYSQLI_STATUS_UNKNOWN;
282
283 MYSQLI_CLEAR_RESOURCE(mysql_link);
284 efree(mysql);
285 RETURN_TRUE;
286 }
287 /* }}} */
288
289 /* {{{ Commit outstanding actions and close transaction */
PHP_FUNCTION(mysqli_commit)290 PHP_FUNCTION(mysqli_commit)
291 {
292 MY_MYSQL *mysql;
293 zval *mysql_link;
294 zend_long flags = TRANS_COR_NO_OPT;
295 char * name = NULL;
296 size_t name_len;
297
298 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls!", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
299 RETURN_THROWS();
300 }
301 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
302
303 if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
304 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
305 RETURN_FALSE;
306 }
307 RETURN_TRUE;
308 }
309 /* }}} */
310
311 /* {{{ Move internal result pointer */
PHP_FUNCTION(mysqli_data_seek)312 PHP_FUNCTION(mysqli_data_seek)
313 {
314 MYSQL_RES *result;
315 zval *mysql_result;
316 zend_long offset;
317
318 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
319 RETURN_THROWS();
320 }
321
322 if (offset < 0) {
323 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0");
324 RETURN_THROWS();
325 }
326
327 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
328
329 if (mysqli_result_is_unbuffered(result)) {
330 if (getThis()) {
331 zend_throw_error(NULL, "mysqli_result::data_seek() cannot be used in MYSQLI_USE_RESULT mode");
332 } else {
333 zend_throw_error(NULL, "mysqli_data_seek() cannot be used in MYSQLI_USE_RESULT mode");
334 }
335 RETURN_THROWS();
336 }
337
338 if ((uint64_t)offset >= mysql_num_rows(result)) {
339 RETURN_FALSE;
340 }
341
342 mysql_data_seek(result, offset);
343 RETURN_TRUE;
344 }
345 /* }}} */
346
347 /* {{{ */
PHP_FUNCTION(mysqli_debug)348 PHP_FUNCTION(mysqli_debug)
349 {
350 char *debug;
351 size_t debug_len;
352
353 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &debug, &debug_len) == FAILURE) {
354 RETURN_THROWS();
355 }
356
357 mysql_debug(debug);
358 RETURN_TRUE;
359 }
360 /* }}} */
361
362 /* {{{ */
PHP_FUNCTION(mysqli_dump_debug_info)363 PHP_FUNCTION(mysqli_dump_debug_info)
364 {
365 MY_MYSQL *mysql;
366 zval *mysql_link;
367
368 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
369 RETURN_THROWS();
370 }
371 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
372
373 RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql));
374 }
375 /* }}} */
376
377 /* {{{ Returns the numerical value of the error message from previous MySQL operation */
PHP_FUNCTION(mysqli_errno)378 PHP_FUNCTION(mysqli_errno)
379 {
380 MY_MYSQL *mysql;
381 zval *mysql_link;
382
383 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
384 RETURN_THROWS();
385 }
386 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
387 RETURN_LONG(mysql_errno(mysql->mysql));
388 }
389 /* }}} */
390
391 /* {{{ Returns the text of the error message from previous MySQL operation */
PHP_FUNCTION(mysqli_error)392 PHP_FUNCTION(mysqli_error)
393 {
394 MY_MYSQL *mysql;
395 zval *mysql_link;
396
397 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
398 RETURN_THROWS();
399 }
400 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
401 RETURN_STRING(mysql_error(mysql->mysql));
402 }
403 /* }}} */
404
405 /* {{{ Execute a prepared statement */
PHP_FUNCTION(mysqli_stmt_execute)406 PHP_FUNCTION(mysqli_stmt_execute)
407 {
408 MY_STMT *stmt;
409 zval *mysql_stmt;
410 HashTable *input_params = NULL;
411
412 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|h!", &mysql_stmt, mysqli_stmt_class_entry, &input_params) == FAILURE) {
413 RETURN_THROWS();
414 }
415 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
416
417 // bind-in-execute
418 if (input_params) {
419 zval *tmp;
420 unsigned int index;
421 unsigned int hash_num_elements;
422 unsigned int param_count;
423 MYSQLND_PARAM_BIND *params;
424
425 if (!zend_array_is_list(input_params)) {
426 zend_argument_value_error(ERROR_ARG_POS(2), "must be a list array");
427 RETURN_THROWS();
428 }
429
430 hash_num_elements = zend_hash_num_elements(input_params);
431 param_count = mysql_stmt_param_count(stmt->stmt);
432 if (hash_num_elements != param_count) {
433 zend_argument_value_error(ERROR_ARG_POS(2), "must consist of exactly %d elements, %d present", param_count, hash_num_elements);
434 RETURN_THROWS();
435 }
436
437 params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
438 ZEND_ASSERT(params);
439
440 index = 0;
441 ZEND_HASH_FOREACH_VAL(input_params, tmp) {
442 ZVAL_COPY_VALUE(¶ms[index].zv, tmp);
443 params[index].type = MYSQL_TYPE_VAR_STRING;
444 index++;
445 } ZEND_HASH_FOREACH_END();
446
447 if (mysqlnd_stmt_bind_param(stmt->stmt, params)) {
448 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
449 RETVAL_FALSE;
450 }
451 }
452
453 if (mysql_stmt_execute(stmt->stmt)) {
454 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
455 RETVAL_FALSE;
456 } else {
457 RETVAL_TRUE;
458 }
459
460 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
461 php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt));
462 }
463 }
464 /* }}} */
465
close_stmt_and_copy_errors(MY_STMT * stmt,MY_MYSQL * mysql)466 void close_stmt_and_copy_errors(MY_STMT *stmt, MY_MYSQL *mysql)
467 {
468 /* mysql_stmt_close() clears errors, so we have to store them temporarily */
469 MYSQLND_ERROR_INFO error_info = *stmt->stmt->data->error_info;
470 stmt->stmt->data->error_info->error_list.head = NULL;
471 stmt->stmt->data->error_info->error_list.tail = NULL;
472 stmt->stmt->data->error_info->error_list.count = 0;
473
474 /* we also remember affected_rows which gets cleared too */
475 uint64_t affected_rows = mysql->mysql->data->upsert_status->affected_rows;
476
477 mysqli_stmt_close(stmt->stmt, false);
478 stmt->stmt = NULL;
479 php_clear_stmt_bind(stmt);
480
481 /* restore error messages, but into the mysql object */
482 zend_llist_clean(&mysql->mysql->data->error_info->error_list);
483 *mysql->mysql->data->error_info = error_info;
484 mysql->mysql->data->upsert_status->affected_rows = affected_rows;
485 }
486
PHP_FUNCTION(mysqli_execute_query)487 PHP_FUNCTION(mysqli_execute_query)
488 {
489 MY_MYSQL *mysql;
490 MY_STMT *stmt;
491 char *query = NULL;
492 size_t query_len;
493 zval *mysql_link;
494 HashTable *input_params = NULL;
495 MYSQL_RES *result;
496 MYSQLI_RESOURCE *mysqli_resource;
497
498 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|h!", &mysql_link, mysqli_link_class_entry, &query, &query_len, &input_params) == FAILURE) {
499 RETURN_THROWS();
500 }
501 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
502
503 stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
504
505 if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
506 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
507 efree(stmt);
508 RETURN_FALSE;
509 }
510
511 if (FAIL == mysql_stmt_prepare(stmt->stmt, query, query_len)) {
512 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
513
514 close_stmt_and_copy_errors(stmt, mysql);
515 RETURN_FALSE;
516 }
517
518 /* The bit below, which is copied from mysqli_prepare, is needed for bad index exceptions */
519 /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
520 /* Get performance boost if reporting is switched off */
521 if (query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
522 stmt->query = estrdup(query);
523 }
524
525 // bind-in-execute
526 // It's very similar to the mysqli_stmt::execute, but it uses different error handling
527 if (input_params) {
528 zval *tmp;
529 unsigned int index;
530 unsigned int hash_num_elements;
531 unsigned int param_count;
532 MYSQLND_PARAM_BIND *params;
533
534 if (!zend_array_is_list(input_params)) {
535 mysqli_stmt_close(stmt->stmt, false);
536 stmt->stmt = NULL;
537 efree(stmt);
538 zend_argument_value_error(ERROR_ARG_POS(3), "must be a list array");
539 RETURN_THROWS();
540 }
541
542 hash_num_elements = zend_hash_num_elements(input_params);
543 param_count = mysql_stmt_param_count(stmt->stmt);
544 if (hash_num_elements != param_count) {
545 mysqli_stmt_close(stmt->stmt, false);
546 stmt->stmt = NULL;
547 efree(stmt);
548 zend_argument_value_error(ERROR_ARG_POS(3), "must consist of exactly %d elements, %d present", param_count, hash_num_elements);
549 RETURN_THROWS();
550 }
551
552 params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
553 ZEND_ASSERT(params);
554
555 index = 0;
556 ZEND_HASH_FOREACH_VAL(input_params, tmp) {
557 ZVAL_COPY_VALUE(¶ms[index].zv, tmp);
558 params[index].type = MYSQL_TYPE_VAR_STRING;
559 index++;
560 } ZEND_HASH_FOREACH_END();
561
562 if (mysqlnd_stmt_bind_param(stmt->stmt, params)) {
563 close_stmt_and_copy_errors(stmt, mysql);
564 RETURN_FALSE;
565 }
566
567 }
568
569 if (mysql_stmt_execute(stmt->stmt)) {
570 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
571
572 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
573 php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt));
574 }
575
576 close_stmt_and_copy_errors(stmt, mysql);
577 RETURN_FALSE;
578 }
579
580 if (!mysql_stmt_field_count(stmt->stmt)) {
581 /* no result set - not a SELECT */
582 close_stmt_and_copy_errors(stmt, mysql);
583 RETURN_TRUE;
584 }
585
586 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
587 php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt));
588 }
589
590 /* get result */
591 if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
592 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
593
594 close_stmt_and_copy_errors(stmt, mysql);
595 RETURN_FALSE;
596 }
597
598 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
599 mysqli_resource->ptr = (void *)result;
600 mysqli_resource->status = MYSQLI_STATUS_VALID;
601 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_result_class_entry);
602
603 close_stmt_and_copy_errors(stmt, mysql);
604 }
605
606 /* {{{ mixed mysqli_stmt_fetch_mysqlnd */
mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)607 void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
608 {
609 MY_STMT *stmt;
610 zval *mysql_stmt;
611 bool fetched_anything;
612
613 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
614 RETURN_THROWS();
615 }
616 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
617
618 if (FAIL == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
619 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
620 RETURN_FALSE;
621 } else if (fetched_anything) {
622 RETURN_TRUE;
623 } else {
624 RETURN_NULL();
625 }
626 }
627 /* }}} */
628
629 /* {{{ Fetch results from a prepared statement into the bound variables */
PHP_FUNCTION(mysqli_stmt_fetch)630 PHP_FUNCTION(mysqli_stmt_fetch)
631 {
632 mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
633 }
634 /* }}} */
635
636 /* {{{ php_add_field_properties */
php_add_field_properties(zval * value,const MYSQL_FIELD * field)637 static void php_add_field_properties(zval *value, const MYSQL_FIELD *field)
638 {
639 add_property_str(value, "name", zend_string_copy(field->sname));
640
641 add_property_stringl(value, "orgname", (field->org_name ? field->org_name : ""), field->org_name_length);
642 add_property_stringl(value, "table", (field->table ? field->table : ""), field->table_length);
643 add_property_stringl(value, "orgtable", (field->org_table ? field->org_table : ""), field->org_table_length);
644 add_property_stringl(value, "def", (field->def ? field->def : ""), field->def_length);
645 add_property_stringl(value, "db", (field->db ? field->db : ""), field->db_length);
646
647 /* FIXME: manually set the catalog to "def" due to bug in
648 * libmysqlclient which does not initialize field->catalog
649 * and in addition, the catalog is always be "def"
650 */
651 add_property_string(value, "catalog", "def");
652
653 add_property_long(value, "max_length", 0);
654 add_property_long(value, "length", field->length);
655 add_property_long(value, "charsetnr", field->charsetnr);
656 add_property_long(value, "flags", field->flags);
657 add_property_long(value, "type", field->type);
658 add_property_long(value, "decimals", field->decimals);
659 }
660 /* }}} */
661
662 /* {{{ Get column information from a result and return as an object */
PHP_FUNCTION(mysqli_fetch_field)663 PHP_FUNCTION(mysqli_fetch_field)
664 {
665 MYSQL_RES *result;
666 zval *mysql_result;
667 const MYSQL_FIELD *field;
668
669 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
670 RETURN_THROWS();
671 }
672
673 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
674
675 if (!(field = mysql_fetch_field(result))) {
676 RETURN_FALSE;
677 }
678
679 object_init(return_value);
680 php_add_field_properties(return_value, field);
681 }
682 /* }}} */
683
684 /* {{{ Return array of objects containing field meta-data */
PHP_FUNCTION(mysqli_fetch_fields)685 PHP_FUNCTION(mysqli_fetch_fields)
686 {
687 MYSQL_RES *result;
688 zval *mysql_result;
689 zval obj;
690
691 unsigned int i, num_fields;
692
693 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
694 RETURN_THROWS();
695 }
696
697 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
698
699 array_init(return_value);
700 num_fields = mysql_num_fields(result);
701
702 for (i = 0; i < num_fields; i++) {
703 const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
704
705 object_init(&obj);
706
707 php_add_field_properties(&obj, field);
708 add_index_zval(return_value, i, &obj);
709 }
710 }
711 /* }}} */
712
713 /* {{{ Fetch meta-data for a single field */
PHP_FUNCTION(mysqli_fetch_field_direct)714 PHP_FUNCTION(mysqli_fetch_field_direct)
715 {
716 MYSQL_RES *result;
717 zval *mysql_result;
718 const MYSQL_FIELD *field;
719 zend_long offset;
720
721 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
722 RETURN_THROWS();
723 }
724
725 if (offset < 0) {
726 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0");
727 RETURN_THROWS();
728 }
729
730 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
731
732 if (offset >= (zend_long) mysql_num_fields(result)) {
733 zend_argument_value_error(ERROR_ARG_POS(2), "must be less than the number of fields for this result set");
734 RETURN_THROWS();
735 }
736
737 if (!(field = mysql_fetch_field_direct(result,offset))) {
738 RETURN_FALSE;
739 }
740
741 object_init(return_value);
742 php_add_field_properties(return_value, field);
743 }
744 /* }}} */
745
746 /* {{{ Get the length of each output in a result */
PHP_FUNCTION(mysqli_fetch_lengths)747 PHP_FUNCTION(mysqli_fetch_lengths)
748 {
749 MYSQL_RES *result;
750 zval *mysql_result;
751 unsigned int i, num_fields;
752 const size_t *ret;
753
754 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
755 RETURN_THROWS();
756 }
757
758 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
759
760 // TODO Warning?
761 if (!(ret = mysql_fetch_lengths(result))) {
762 RETURN_FALSE;
763 }
764
765 array_init(return_value);
766 num_fields = mysql_num_fields(result);
767
768 for (i = 0; i < num_fields; i++) {
769 add_index_long(return_value, i, ret[i]);
770 }
771 }
772 /* }}} */
773
774 /* {{{ Get a result row as an enumerated array */
PHP_FUNCTION(mysqli_fetch_row)775 PHP_FUNCTION(mysqli_fetch_row)
776 {
777 php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
778 }
779 /* }}} */
780
781 /* {{{ Fetch the number of fields returned by the last query for the given link */
PHP_FUNCTION(mysqli_field_count)782 PHP_FUNCTION(mysqli_field_count)
783 {
784 MY_MYSQL *mysql;
785 zval *mysql_link;
786
787 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
788 RETURN_THROWS();
789 }
790 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
791
792 RETURN_LONG(mysql_field_count(mysql->mysql));
793 }
794 /* }}} */
795
796 /* {{{ Set result pointer to a specified field offset */
PHP_FUNCTION(mysqli_field_seek)797 PHP_FUNCTION(mysqli_field_seek)
798 {
799 MYSQL_RES *result;
800 zval *mysql_result;
801 zend_long fieldnr;
802
803 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
804 RETURN_THROWS();
805 }
806
807 if (fieldnr < 0) {
808 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0");
809 RETURN_THROWS();
810 }
811
812 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
813
814 if ((uint32_t)fieldnr >= mysql_num_fields(result)) {
815 zend_argument_value_error(ERROR_ARG_POS(2), "must be less than the number of fields for this result set");
816 RETURN_THROWS();
817 }
818
819 mysql_field_seek(result, fieldnr);
820 RETURN_TRUE;
821 }
822 /* }}} */
823
824 /* {{{ Get current field offset of result pointer */
PHP_FUNCTION(mysqli_field_tell)825 PHP_FUNCTION(mysqli_field_tell)
826 {
827 MYSQL_RES *result;
828 zval *mysql_result;
829
830 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
831 RETURN_THROWS();
832 }
833 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
834
835 RETURN_LONG(mysql_field_tell(result));
836 }
837 /* }}} */
838
839 /* {{{ Free query result memory for the given result handle */
PHP_FUNCTION(mysqli_free_result)840 PHP_FUNCTION(mysqli_free_result)
841 {
842 MYSQL_RES *result;
843 zval *mysql_result;
844
845 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
846 RETURN_THROWS();
847 }
848 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
849
850 mysqli_free_result(result, false);
851 MYSQLI_CLEAR_RESOURCE(mysql_result);
852 }
853 /* }}} */
854
855 /* {{{ Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_info)856 PHP_FUNCTION(mysqli_get_client_info)
857 {
858 if (getThis()) {
859 if (zend_parse_parameters_none() == FAILURE) {
860 RETURN_THROWS();
861 }
862 } else {
863 zval *mysql_link;
864
865 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &mysql_link, mysqli_link_class_entry) == FAILURE) {
866 RETURN_THROWS();
867 }
868
869 if (ZEND_NUM_ARGS()) {
870 php_error_docref(NULL, E_DEPRECATED, "Passing connection object as an argument is deprecated");
871 }
872 }
873
874 RETURN_STRING(mysql_get_client_info());
875 }
876 /* }}} */
877
878 /* {{{ Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_version)879 PHP_FUNCTION(mysqli_get_client_version)
880 {
881 if (zend_parse_parameters_none() == FAILURE) {
882 RETURN_THROWS();
883 }
884
885 RETURN_LONG((zend_long)mysql_get_client_version());
886 }
887 /* }}} */
888
889 /* {{{ Get MySQL host info */
PHP_FUNCTION(mysqli_get_host_info)890 PHP_FUNCTION(mysqli_get_host_info)
891 {
892 MY_MYSQL *mysql;
893 zval *mysql_link = NULL;
894
895 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
896 RETURN_THROWS();
897 }
898 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
899 RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "");
900 }
901 /* }}} */
902
903 /* {{{ Get MySQL protocol information */
PHP_FUNCTION(mysqli_get_proto_info)904 PHP_FUNCTION(mysqli_get_proto_info)
905 {
906 MY_MYSQL *mysql;
907 zval *mysql_link = NULL;
908
909 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
910 RETURN_THROWS();
911 }
912 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
913 RETURN_LONG(mysql_get_proto_info(mysql->mysql));
914 }
915 /* }}} */
916
917 /* {{{ Get MySQL server info */
PHP_FUNCTION(mysqli_get_server_info)918 PHP_FUNCTION(mysqli_get_server_info)
919 {
920 MY_MYSQL *mysql;
921 zval *mysql_link = NULL;
922
923 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
924 RETURN_THROWS();
925 }
926 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
927
928 RETURN_STRING(mysql_get_server_info(mysql->mysql));
929 }
930 /* }}} */
931
932 /* {{{ Return the MySQL version for the server referenced by the given link */
PHP_FUNCTION(mysqli_get_server_version)933 PHP_FUNCTION(mysqli_get_server_version)
934 {
935 MY_MYSQL *mysql;
936 zval *mysql_link = NULL;
937
938 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
939 RETURN_THROWS();
940 }
941 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
942
943 RETURN_LONG(mysql_get_server_version(mysql->mysql));
944 }
945 /* }}} */
946
947 /* {{{ Get information about the most recent query */
PHP_FUNCTION(mysqli_info)948 PHP_FUNCTION(mysqli_info)
949 {
950 MY_MYSQL *mysql;
951 zval *mysql_link = NULL;
952 const char *info;
953
954 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
955 RETURN_THROWS();
956 }
957 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
958
959 info = mysql_info(mysql->mysql);
960 if (info) {
961 RETURN_STRING(info);
962 }
963 }
964 /* }}} */
965
966 /* {{{ php_mysqli_init() */
php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS,bool is_method)967 void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, bool is_method)
968 {
969 MYSQLI_RESOURCE *mysqli_resource;
970 MY_MYSQL *mysql;
971
972 if (zend_parse_parameters_none() == FAILURE) {
973 RETURN_THROWS();
974 }
975
976 if (is_method && (Z_MYSQLI_P(getThis()))->ptr) {
977 return;
978 }
979
980 mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
981
982 /*
983 We create always persistent, as if the user want to connect
984 to p:somehost, we can't convert the handle then
985 */
986 if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, true)))
987 {
988 efree(mysql);
989 RETURN_FALSE;
990 }
991
992 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
993 mysqli_resource->ptr = (void *)mysql;
994 mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
995
996 if (!is_method) {
997 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_link_class_entry);
998 } else {
999 (Z_MYSQLI_P(getThis()))->ptr = mysqli_resource;
1000 }
1001 }
1002 /* }}} */
1003
1004 /* {{{ Initialize mysqli and return a resource for use with mysql_real_connect */
PHP_FUNCTION(mysqli_init)1005 PHP_FUNCTION(mysqli_init)
1006 {
1007 php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
1008 }
1009 /* }}} */
1010
1011 /* {{{ Get the ID generated from the previous INSERT operation */
PHP_FUNCTION(mysqli_insert_id)1012 PHP_FUNCTION(mysqli_insert_id)
1013 {
1014 MY_MYSQL *mysql;
1015 my_ulonglong rc;
1016 zval *mysql_link;
1017
1018 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1019 RETURN_THROWS();
1020 }
1021 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1022 rc = mysql_insert_id(mysql->mysql);
1023 MYSQLI_RETURN_LONG_INT(rc)
1024 }
1025 /* }}} */
1026
1027 /* {{{ Kill a mysql process on the server */
PHP_FUNCTION(mysqli_kill)1028 PHP_FUNCTION(mysqli_kill)
1029 {
1030 MY_MYSQL *mysql;
1031 zval *mysql_link;
1032 zend_long processid;
1033
1034 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
1035 RETURN_THROWS();
1036 }
1037
1038 if (processid <= 0) {
1039 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than 0");
1040 RETURN_THROWS();
1041 }
1042
1043 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1044
1045 if (mysql_kill(mysql->mysql, processid)) {
1046 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1047 RETURN_FALSE;
1048 }
1049 RETURN_TRUE;
1050 }
1051 /* }}} */
1052
1053 /* {{{ check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_more_results)1054 PHP_FUNCTION(mysqli_more_results)
1055 {
1056 MY_MYSQL *mysql;
1057 zval *mysql_link;
1058
1059 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1060 RETURN_THROWS();
1061 }
1062 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1063
1064 RETURN_BOOL(mysql_more_results(mysql->mysql));
1065 }
1066 /* }}} */
1067
1068 /* {{{ read next result from multi_query */
PHP_FUNCTION(mysqli_next_result)1069 PHP_FUNCTION(mysqli_next_result) {
1070 MY_MYSQL *mysql;
1071 zval *mysql_link;
1072
1073 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1074 RETURN_THROWS();
1075 }
1076 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1077
1078 if (mysql_next_result(mysql->mysql)) {
1079 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1080 RETURN_FALSE;
1081 }
1082 RETURN_TRUE;
1083 }
1084 /* }}} */
1085
1086
1087 /* {{{ check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_stmt_more_results)1088 PHP_FUNCTION(mysqli_stmt_more_results)
1089 {
1090 MY_STMT *stmt;
1091 zval *mysql_stmt;
1092
1093 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1094 RETURN_THROWS();
1095 }
1096 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1097
1098 RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
1099 }
1100 /* }}} */
1101
1102 /* {{{ read next result from multi_query */
PHP_FUNCTION(mysqli_stmt_next_result)1103 PHP_FUNCTION(mysqli_stmt_next_result) {
1104 MY_STMT *stmt;
1105 zval *mysql_stmt;
1106
1107 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1108 RETURN_THROWS();
1109 }
1110 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1111
1112 if (mysql_stmt_next_result(stmt->stmt)) {
1113 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1114 RETURN_FALSE;
1115 }
1116 RETURN_TRUE;
1117 }
1118 /* }}} */
1119
1120 /* {{{ Get number of fields in result */
PHP_FUNCTION(mysqli_num_fields)1121 PHP_FUNCTION(mysqli_num_fields)
1122 {
1123 MYSQL_RES *result;
1124 zval *mysql_result;
1125
1126 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1127 RETURN_THROWS();
1128 }
1129 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1130
1131 RETURN_LONG(mysql_num_fields(result));
1132 }
1133 /* }}} */
1134
1135 /* {{{ Get number of rows in result */
PHP_FUNCTION(mysqli_num_rows)1136 PHP_FUNCTION(mysqli_num_rows)
1137 {
1138 MYSQL_RES *result;
1139 zval *mysql_result;
1140
1141 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1142 RETURN_THROWS();
1143 }
1144 MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1145
1146 if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
1147 zend_throw_error(NULL, "mysqli_num_rows() cannot be used in MYSQLI_USE_RESULT mode");
1148 RETURN_THROWS();
1149 }
1150
1151 MYSQLI_RETURN_LONG_INT(mysql_num_rows(result));
1152 }
1153 /* }}} */
1154
1155 /* {{{ mysqli_options_get_option_zval_type */
mysqli_options_get_option_zval_type(int option)1156 static int mysqli_options_get_option_zval_type(int option)
1157 {
1158 switch (option) {
1159 case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
1160 case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
1161 case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
1162 case MYSQL_OPT_CONNECT_TIMEOUT:
1163 case MYSQL_OPT_LOCAL_INFILE:
1164 case MYSQL_OPT_NAMED_PIPE:
1165 case MYSQL_OPT_PROTOCOL:
1166 case MYSQL_OPT_READ_TIMEOUT:
1167 case MYSQL_OPT_WRITE_TIMEOUT:
1168 case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
1169 case MYSQL_OPT_COMPRESS:
1170 case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
1171 return IS_LONG;
1172
1173 case MYSQL_READ_DEFAULT_FILE:
1174 case MYSQL_READ_DEFAULT_GROUP:
1175 case MYSQL_INIT_COMMAND:
1176 case MYSQL_SET_CHARSET_NAME:
1177 case MYSQL_SERVER_PUBLIC_KEY:
1178 case MYSQL_OPT_LOAD_DATA_LOCAL_DIR:
1179 return IS_STRING;
1180
1181 default:
1182 return IS_NULL;
1183 }
1184 }
1185 /* }}} */
1186
1187 /* {{{ Set options */
PHP_FUNCTION(mysqli_options)1188 PHP_FUNCTION(mysqli_options)
1189 {
1190 MY_MYSQL *mysql;
1191 zval *mysql_link = NULL;
1192 zval *mysql_value;
1193 zend_long mysql_option;
1194 unsigned int l_value;
1195 zend_long ret;
1196 int expected_type;
1197
1198 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Olz", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
1199 RETURN_THROWS();
1200 }
1201 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
1202
1203 expected_type = mysqli_options_get_option_zval_type(mysql_option);
1204 if (expected_type != Z_TYPE_P(mysql_value)) {
1205 switch (expected_type) {
1206 case IS_STRING:
1207 if (!try_convert_to_string(mysql_value)) {
1208 RETURN_THROWS();
1209 }
1210 break;
1211 case IS_LONG:
1212 convert_to_long(mysql_value);
1213 break;
1214 default:
1215 break;
1216 }
1217 }
1218 switch (expected_type) {
1219 case IS_STRING:
1220 if ((ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_P(mysql_value)))) {
1221 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1222 }
1223 break;
1224 case IS_LONG:
1225 l_value = Z_LVAL_P(mysql_value);
1226 if ((ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value))) {
1227 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1228 }
1229 break;
1230 default:
1231 ret = 1;
1232 break;
1233 }
1234
1235 RETURN_BOOL(!ret);
1236 }
1237 /* }}} */
1238
1239 /* {{{ Ping a server connection or reconnect if there is no connection */
PHP_FUNCTION(mysqli_ping)1240 PHP_FUNCTION(mysqli_ping)
1241 {
1242 MY_MYSQL *mysql;
1243 zval *mysql_link;
1244 zend_long rc;
1245
1246 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1247 RETURN_THROWS();
1248 }
1249 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1250 rc = mysql_ping(mysql->mysql);
1251 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1252
1253 RETURN_BOOL(!rc);
1254 }
1255 /* }}} */
1256
1257 /* {{{ Prepare a SQL statement for execution */
PHP_FUNCTION(mysqli_prepare)1258 PHP_FUNCTION(mysqli_prepare)
1259 {
1260 MY_MYSQL *mysql;
1261 MY_STMT *stmt;
1262 char *query = NULL;
1263 size_t query_len;
1264 zval *mysql_link;
1265 MYSQLI_RESOURCE *mysqli_resource;
1266
1267 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1268 RETURN_THROWS();
1269 }
1270 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1271
1272 stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
1273
1274 if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
1275 if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
1276 /* mysql_stmt_close() clears errors, so we have to store them temporarily */
1277 MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
1278 mysql->mysql->data->error_info->error_list.head = NULL;
1279 mysql->mysql->data->error_info->error_list.tail = NULL;
1280 mysql->mysql->data->error_info->error_list.count = 0;
1281 mysqli_stmt_close(stmt->stmt, false);
1282 stmt->stmt = NULL;
1283
1284 /* restore error messages */
1285 zend_llist_clean(&mysql->mysql->data->error_info->error_list);
1286 *mysql->mysql->data->error_info = error_info;
1287 }
1288 }
1289
1290 /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
1291 /* Get performance boost if reporting is switched off */
1292 if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
1293 stmt->query = estrdup(query);
1294 }
1295
1296 /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
1297 if (!stmt->stmt) {
1298 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1299 efree(stmt);
1300 RETURN_FALSE;
1301 }
1302
1303 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1304 mysqli_resource->ptr = (void *)stmt;
1305
1306 /* change status */
1307 mysqli_resource->status = MYSQLI_STATUS_VALID;
1308 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
1309 }
1310 /* }}} */
1311
1312 /* {{{ Open a connection to a mysql server */
PHP_FUNCTION(mysqli_real_connect)1313 PHP_FUNCTION(mysqli_real_connect)
1314 {
1315 mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, true, false);
1316 }
1317 /* }}} */
1318
1319 /* {{{ Binary-safe version of mysql_query() */
PHP_FUNCTION(mysqli_real_query)1320 PHP_FUNCTION(mysqli_real_query)
1321 {
1322 MY_MYSQL *mysql;
1323 zval *mysql_link;
1324 char *query = NULL;
1325 size_t query_len;
1326
1327 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1328 RETURN_THROWS();
1329 }
1330 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1331
1332 MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
1333
1334 if (mysql_real_query(mysql->mysql, query, query_len)) {
1335 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1336 RETURN_FALSE;
1337 }
1338
1339 if (!mysql_field_count(mysql->mysql)) {
1340 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1341 php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
1342 }
1343 }
1344
1345 RETURN_TRUE;
1346 }
1347 /* }}} */
1348
1349 # define mysql_real_escape_string_quote(mysql, to, from, length, quote) \
1350 mysql_real_escape_string(mysql, to, from, length)
1351
PHP_FUNCTION(mysqli_real_escape_string)1352 PHP_FUNCTION(mysqli_real_escape_string) {
1353 MY_MYSQL *mysql;
1354 zval *mysql_link = NULL;
1355 char *escapestr;
1356 size_t escapestr_len;
1357 zend_string *newstr;
1358
1359 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
1360 RETURN_THROWS();
1361 }
1362 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1363
1364 newstr = zend_string_safe_alloc(2, escapestr_len, 0, 0);
1365 ZSTR_LEN(newstr) = mysql_real_escape_string_quote(mysql->mysql, ZSTR_VAL(newstr), escapestr, escapestr_len, '\'');
1366 newstr = zend_string_truncate(newstr, ZSTR_LEN(newstr), 0);
1367
1368 RETURN_NEW_STR(newstr);
1369 }
1370
1371 /* {{{ Undo actions from current transaction */
PHP_FUNCTION(mysqli_rollback)1372 PHP_FUNCTION(mysqli_rollback)
1373 {
1374 MY_MYSQL *mysql;
1375 zval *mysql_link;
1376 zend_long flags = TRANS_COR_NO_OPT;
1377 char * name = NULL;
1378 size_t name_len = 0;
1379
1380 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls!", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
1381 RETURN_THROWS();
1382 }
1383 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1384
1385
1386 if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
1387 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1388 RETURN_FALSE;
1389 }
1390 RETURN_TRUE;
1391 }
1392 /* }}} */
1393
1394 /* {{{ */
PHP_FUNCTION(mysqli_stmt_send_long_data)1395 PHP_FUNCTION(mysqli_stmt_send_long_data)
1396 {
1397 MY_STMT *stmt;
1398 zval *mysql_stmt;
1399 char *data;
1400 zend_long param_nr;
1401 size_t data_len;
1402
1403 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) {
1404 RETURN_THROWS();
1405 }
1406
1407 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1408
1409 if (param_nr < 0) {
1410 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0");
1411 RETURN_THROWS();
1412 }
1413
1414 if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
1415 RETURN_FALSE;
1416 }
1417 RETURN_TRUE;
1418 }
1419 /* }}} */
1420
1421 /* {{{ Return the number of rows affected in the last query for the given link. */
PHP_FUNCTION(mysqli_stmt_affected_rows)1422 PHP_FUNCTION(mysqli_stmt_affected_rows)
1423 {
1424 MY_STMT *stmt;
1425 zval *mysql_stmt;
1426 my_ulonglong rc;
1427
1428 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1429 RETURN_THROWS();
1430 }
1431 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1432
1433 rc = mysql_stmt_affected_rows(stmt->stmt);
1434 if (rc == (my_ulonglong) -1) {
1435 RETURN_LONG(-1);
1436 }
1437 MYSQLI_RETURN_LONG_INT(rc)
1438 }
1439 /* }}} */
1440
1441 /* {{{ Close statement */
PHP_FUNCTION(mysqli_stmt_close)1442 PHP_FUNCTION(mysqli_stmt_close)
1443 {
1444 MY_STMT *stmt;
1445 zval *mysql_stmt;
1446
1447 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1448 RETURN_THROWS();
1449 }
1450 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1451
1452 mysqli_stmt_close(stmt->stmt, false);
1453 stmt->stmt = NULL;
1454 php_clear_stmt_bind(stmt);
1455 MYSQLI_CLEAR_RESOURCE(mysql_stmt);
1456 RETURN_TRUE;
1457 }
1458 /* }}} */
1459
1460 /* {{{ Move internal result pointer */
PHP_FUNCTION(mysqli_stmt_data_seek)1461 PHP_FUNCTION(mysqli_stmt_data_seek)
1462 {
1463 MY_STMT *stmt;
1464 zval *mysql_stmt;
1465 zend_long offset;
1466
1467 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
1468 RETURN_THROWS();
1469 }
1470
1471 if (offset < 0) {
1472 zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0");
1473 RETURN_THROWS();
1474 }
1475
1476 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1477
1478 mysql_stmt_data_seek(stmt->stmt, offset);
1479 }
1480 /* }}} */
1481
1482 /* {{{ Return the number of result columns for the given statement */
PHP_FUNCTION(mysqli_stmt_field_count)1483 PHP_FUNCTION(mysqli_stmt_field_count)
1484 {
1485 MY_STMT *stmt;
1486 zval *mysql_stmt;
1487
1488 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1489 RETURN_THROWS();
1490 }
1491 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1492
1493 RETURN_LONG(mysql_stmt_field_count(stmt->stmt));
1494 }
1495 /* }}} */
1496
1497 /* {{{ Free stored result memory for the given statement handle */
PHP_FUNCTION(mysqli_stmt_free_result)1498 PHP_FUNCTION(mysqli_stmt_free_result)
1499 {
1500 MY_STMT *stmt;
1501 zval *mysql_stmt;
1502
1503 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1504 RETURN_THROWS();
1505 }
1506
1507 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1508
1509 mysql_stmt_free_result(stmt->stmt);
1510 }
1511 /* }}} */
1512
1513 /* {{{ Get the ID generated from the previous INSERT operation */
PHP_FUNCTION(mysqli_stmt_insert_id)1514 PHP_FUNCTION(mysqli_stmt_insert_id)
1515 {
1516 MY_STMT *stmt;
1517 my_ulonglong rc;
1518 zval *mysql_stmt;
1519
1520 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1521 RETURN_THROWS();
1522 }
1523 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1524 rc = mysql_stmt_insert_id(stmt->stmt);
1525 MYSQLI_RETURN_LONG_INT(rc)
1526 }
1527 /* }}} */
1528
1529 /* {{{ Return the number of parameter for the given statement */
PHP_FUNCTION(mysqli_stmt_param_count)1530 PHP_FUNCTION(mysqli_stmt_param_count)
1531 {
1532 MY_STMT *stmt;
1533 zval *mysql_stmt;
1534
1535 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1536 RETURN_THROWS();
1537 }
1538 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1539
1540 RETURN_LONG(mysql_stmt_param_count(stmt->stmt));
1541 }
1542 /* }}} */
1543
1544 /* {{{ reset a prepared statement */
PHP_FUNCTION(mysqli_stmt_reset)1545 PHP_FUNCTION(mysqli_stmt_reset)
1546 {
1547 MY_STMT *stmt;
1548 zval *mysql_stmt;
1549
1550 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1551 RETURN_THROWS();
1552 }
1553
1554 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1555
1556 if (mysql_stmt_reset(stmt->stmt)) {
1557 RETURN_FALSE;
1558 }
1559 RETURN_TRUE;
1560 }
1561 /* }}} */
1562
1563 /* {{{ Return the number of rows in statements result set */
PHP_FUNCTION(mysqli_stmt_num_rows)1564 PHP_FUNCTION(mysqli_stmt_num_rows)
1565 {
1566 MY_STMT *stmt;
1567 zval *mysql_stmt;
1568 my_ulonglong rc;
1569
1570 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1571 RETURN_THROWS();
1572 }
1573
1574 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1575
1576 rc = mysql_stmt_num_rows(stmt->stmt);
1577 MYSQLI_RETURN_LONG_INT(rc)
1578 }
1579 /* }}} */
1580
1581 /* {{{ Select a MySQL database */
PHP_FUNCTION(mysqli_select_db)1582 PHP_FUNCTION(mysqli_select_db)
1583 {
1584 MY_MYSQL *mysql;
1585 zval *mysql_link;
1586 char *dbname;
1587 size_t dbname_len;
1588
1589 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
1590 RETURN_THROWS();
1591 }
1592 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1593
1594 if (mysql_select_db(mysql->mysql, dbname)) {
1595 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1596 RETURN_FALSE;
1597 }
1598 RETURN_TRUE;
1599 }
1600 /* }}} */
1601
1602 /* {{{ Returns the SQLSTATE error from previous MySQL operation */
PHP_FUNCTION(mysqli_sqlstate)1603 PHP_FUNCTION(mysqli_sqlstate)
1604 {
1605 MY_MYSQL *mysql;
1606 zval *mysql_link;
1607
1608 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1609 RETURN_THROWS();
1610 }
1611 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1612 RETURN_STRING(mysql_sqlstate(mysql->mysql));
1613 }
1614 /* }}} */
1615
1616 /* {{{ */
PHP_FUNCTION(mysqli_ssl_set)1617 PHP_FUNCTION(mysqli_ssl_set)
1618 {
1619 MY_MYSQL *mysql;
1620 zval *mysql_link;
1621 char *ssl_parm[5];
1622 size_t ssl_parm_len[5], i;
1623
1624 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!s!s!s!s!", &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) {
1625 RETURN_THROWS();
1626 }
1627 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
1628
1629 for (i = 0; i < 5; i++) {
1630 if (!ssl_parm_len[i]) {
1631 ssl_parm[i] = NULL;
1632 }
1633 }
1634
1635 mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]);
1636
1637 RETURN_TRUE;
1638 }
1639 /* }}} */
1640
1641 /* {{{ Get current system status */
PHP_FUNCTION(mysqli_stat)1642 PHP_FUNCTION(mysqli_stat)
1643 {
1644 MY_MYSQL *mysql;
1645 zval *mysql_link;
1646 zend_string *stat;
1647
1648 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1649 RETURN_THROWS();
1650 }
1651 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1652
1653 if (mysqlnd_stat(mysql->mysql, &stat) == PASS)
1654 {
1655 RETURN_STR(stat);
1656 } else {
1657 RETURN_FALSE;
1658 }
1659 }
1660
1661 /* }}} */
1662
1663 /* {{{ Flush tables or caches, or reset replication server information */
PHP_FUNCTION(mysqli_refresh)1664 PHP_FUNCTION(mysqli_refresh)
1665 {
1666 MY_MYSQL *mysql;
1667 zval *mysql_link = NULL;
1668 zend_long options;
1669
1670 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) {
1671 RETURN_THROWS();
1672 }
1673 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
1674 RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
1675 }
1676 /* }}} */
1677
1678 /* {{{ */
PHP_FUNCTION(mysqli_stmt_attr_set)1679 PHP_FUNCTION(mysqli_stmt_attr_set)
1680 {
1681 MY_STMT *stmt;
1682 zval *mysql_stmt;
1683 zend_long mode_in;
1684 my_bool mode_b;
1685 unsigned long mode;
1686 zend_long attr;
1687 void *mode_p;
1688
1689 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
1690 RETURN_THROWS();
1691 }
1692
1693 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1694
1695 switch (attr) {
1696 case STMT_ATTR_UPDATE_MAX_LENGTH:
1697 if (mode_in != 0 && mode_in != 1) {
1698 zend_argument_value_error(ERROR_ARG_POS(3), "must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH");
1699 RETURN_THROWS();
1700 }
1701 mode_b = (my_bool) mode_in;
1702 mode_p = &mode_b;
1703 break;
1704 case STMT_ATTR_CURSOR_TYPE:
1705 switch (mode_in) {
1706 case CURSOR_TYPE_NO_CURSOR:
1707 case CURSOR_TYPE_READ_ONLY:
1708 break;
1709 default:
1710 zend_argument_value_error(ERROR_ARG_POS(3), "must be one of the MYSQLI_CURSOR_TYPE_* constants "
1711 "for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE");
1712 RETURN_THROWS();
1713 }
1714 mode = mode_in;
1715 mode_p = &mode;
1716 break;
1717 default:
1718 zend_argument_value_error(ERROR_ARG_POS(2), "must be either "
1719 "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE");
1720 RETURN_THROWS();
1721 }
1722
1723 if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
1724 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1725 RETURN_FALSE;
1726 }
1727 RETURN_TRUE;
1728 }
1729 /* }}} */
1730
1731 /* {{{ */
PHP_FUNCTION(mysqli_stmt_attr_get)1732 PHP_FUNCTION(mysqli_stmt_attr_get)
1733 {
1734 MY_STMT *stmt;
1735 zval *mysql_stmt;
1736 unsigned long value = 0;
1737 zend_long attr;
1738 int rc;
1739
1740 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
1741 RETURN_THROWS();
1742 }
1743
1744 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1745
1746 if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
1747 /* Success corresponds to 0 return value and a non-zero value
1748 * should only happen if the attr/option is unknown */
1749 zend_argument_value_error(ERROR_ARG_POS(2), "must be either "
1750 "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE");
1751 RETURN_THROWS();
1752 }
1753
1754 if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
1755 value = (my_bool)value;
1756
1757 RETURN_LONG((unsigned long)value);
1758 }
1759 /* }}} */
1760
1761 /* {{{ */
PHP_FUNCTION(mysqli_stmt_errno)1762 PHP_FUNCTION(mysqli_stmt_errno)
1763 {
1764 MY_STMT *stmt;
1765 zval *mysql_stmt;
1766
1767 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1768 RETURN_THROWS();
1769 }
1770 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
1771
1772 RETURN_LONG(mysql_stmt_errno(stmt->stmt));
1773 }
1774 /* }}} */
1775
1776 /* {{{ */
PHP_FUNCTION(mysqli_stmt_error)1777 PHP_FUNCTION(mysqli_stmt_error)
1778 {
1779 MY_STMT *stmt;
1780 zval *mysql_stmt;
1781
1782 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1783 RETURN_THROWS();
1784 }
1785 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
1786
1787 RETURN_STRING(mysql_stmt_error(stmt->stmt));
1788 }
1789 /* }}} */
1790
1791 /* {{{ Initialize statement object */
PHP_FUNCTION(mysqli_stmt_init)1792 PHP_FUNCTION(mysqli_stmt_init)
1793 {
1794 MY_MYSQL *mysql;
1795 MY_STMT *stmt;
1796 zval *mysql_link;
1797 MYSQLI_RESOURCE *mysqli_resource;
1798
1799 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
1800 RETURN_THROWS();
1801 }
1802 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1803
1804 stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
1805
1806 if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
1807 efree(stmt);
1808 RETURN_FALSE;
1809 }
1810
1811 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1812 mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
1813 mysqli_resource->ptr = (void *)stmt;
1814 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
1815 }
1816 /* }}} */
1817
1818 /* {{{ prepare server side statement with query */
PHP_FUNCTION(mysqli_stmt_prepare)1819 PHP_FUNCTION(mysqli_stmt_prepare)
1820 {
1821 MY_STMT *stmt;
1822 zval *mysql_stmt;
1823 char *query;
1824 size_t query_len;
1825
1826 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) {
1827 RETURN_THROWS();
1828 }
1829 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
1830
1831 if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
1832 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1833 RETURN_FALSE;
1834 }
1835 /* change status */
1836 MYSQLI_SET_STATUS(mysql_stmt, MYSQLI_STATUS_VALID);
1837 RETURN_TRUE;
1838 }
1839 /* }}} */
1840
1841 /* {{{ return result set from statement */
PHP_FUNCTION(mysqli_stmt_result_metadata)1842 PHP_FUNCTION(mysqli_stmt_result_metadata)
1843 {
1844 MY_STMT *stmt;
1845 MYSQL_RES *result;
1846 zval *mysql_stmt;
1847 MYSQLI_RESOURCE *mysqli_resource;
1848
1849 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1850 RETURN_THROWS();
1851 }
1852 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1853
1854 if (!(result = mysql_stmt_result_metadata(stmt->stmt))){
1855 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1856 RETURN_FALSE;
1857 }
1858
1859 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1860 mysqli_resource->ptr = (void *)result;
1861 mysqli_resource->status = MYSQLI_STATUS_VALID;
1862 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_result_class_entry);
1863 }
1864 /* }}} */
1865
1866 /* {{{ */
PHP_FUNCTION(mysqli_stmt_store_result)1867 PHP_FUNCTION(mysqli_stmt_store_result)
1868 {
1869 MY_STMT *stmt;
1870 zval *mysql_stmt;
1871
1872 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1873 RETURN_THROWS();
1874 }
1875 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1876
1877 if (mysql_stmt_store_result(stmt->stmt)){
1878 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
1879 RETURN_FALSE;
1880 }
1881 RETURN_TRUE;
1882 }
1883 /* }}} */
1884
1885 /* {{{ */
PHP_FUNCTION(mysqli_stmt_sqlstate)1886 PHP_FUNCTION(mysqli_stmt_sqlstate)
1887 {
1888 MY_STMT *stmt;
1889 zval *mysql_stmt;
1890
1891 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1892 RETURN_THROWS();
1893 }
1894 MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
1895
1896 RETURN_STRING(mysql_stmt_sqlstate(stmt->stmt));
1897 }
1898 /* }}} */
1899
1900 /* {{{ Buffer result set on client */
PHP_FUNCTION(mysqli_store_result)1901 PHP_FUNCTION(mysqli_store_result)
1902 {
1903 MY_MYSQL *mysql;
1904 MYSQL_RES *result;
1905 zval *mysql_link;
1906 MYSQLI_RESOURCE *mysqli_resource;
1907 zend_long flags = 0;
1908
1909
1910 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_link, mysqli_link_class_entry, &flags) == FAILURE) {
1911 RETURN_THROWS();
1912 }
1913
1914 if ((hasThis() && ZEND_NUM_ARGS() == 1) || ZEND_NUM_ARGS() == 2) {
1915 zend_error(E_DEPRECATED, "Passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1");
1916 if (UNEXPECTED(EG(exception))) {
1917 RETURN_THROWS();
1918 }
1919 }
1920
1921 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1922 result = mysql_store_result(mysql->mysql);
1923 if (!result) {
1924 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1925 RETURN_FALSE;
1926 }
1927 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1928 php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql));
1929 }
1930
1931 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1932 mysqli_resource->ptr = (void *)result;
1933 mysqli_resource->status = MYSQLI_STATUS_VALID;
1934 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_result_class_entry);
1935 }
1936 /* }}} */
1937
1938 /* {{{ Return the current thread ID */
PHP_FUNCTION(mysqli_thread_id)1939 PHP_FUNCTION(mysqli_thread_id)
1940 {
1941 MY_MYSQL *mysql;
1942 zval *mysql_link;
1943
1944 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1945 RETURN_THROWS();
1946 }
1947 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1948
1949 RETURN_LONG((zend_long) mysql_thread_id(mysql->mysql));
1950 }
1951 /* }}} */
1952
1953 /* {{{ Return whether thread safety is given or not */
PHP_FUNCTION(mysqli_thread_safe)1954 PHP_FUNCTION(mysqli_thread_safe)
1955 {
1956 if (zend_parse_parameters_none() == FAILURE) {
1957 RETURN_THROWS();
1958 }
1959
1960 RETURN_BOOL(mysql_thread_safe());
1961 }
1962 /* }}} */
1963
1964 /* {{{ Directly retrieve query results - do not buffer results on client side */
PHP_FUNCTION(mysqli_use_result)1965 PHP_FUNCTION(mysqli_use_result)
1966 {
1967 MY_MYSQL *mysql;
1968 MYSQL_RES *result;
1969 zval *mysql_link;
1970 MYSQLI_RESOURCE *mysqli_resource;
1971
1972 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1973 RETURN_THROWS();
1974 }
1975 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1976
1977 if (!(result = mysql_use_result(mysql->mysql))) {
1978 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1979 RETURN_FALSE;
1980 }
1981
1982 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1983 php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql));
1984 }
1985 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1986 mysqli_resource->ptr = (void *)result;
1987 mysqli_resource->status = MYSQLI_STATUS_VALID;
1988 MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_result_class_entry);
1989 }
1990 /* }}} */
1991
1992 /* {{{ Return number of warnings from the last query for the given link */
PHP_FUNCTION(mysqli_warning_count)1993 PHP_FUNCTION(mysqli_warning_count)
1994 {
1995 MY_MYSQL *mysql;
1996 zval *mysql_link;
1997
1998 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1999 RETURN_THROWS();
2000 }
2001 MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
2002
2003 RETURN_LONG(mysql_warning_count(mysql->mysql));
2004 }
2005 /* }}} */
2006