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 */ 38PHP_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 */ 61PHP_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 81static 82int 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 138end_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 158static 159int 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 205end: 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 */ 213PHP_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*/ 282static int 283mysqli_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 455static int 456mysqli_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 */ 473PHP_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 */ 518PHP_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 */ 561PHP_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 */ 578void 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 */ 611PHP_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 */ 633PHP_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 */ 651PHP_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*/ 679PHP_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*/ 696PHP_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 */ 712PHP_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 */ 727PHP_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 */ 742static void 743php_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 */ 758PHP_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 */ 851void 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 */ 1012void 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 */ 1037PHP_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 */ 1048static 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 */ 1074PHP_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 */ 1097PHP_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 */ 1127PHP_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 */ 1156PHP_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 */ 1183PHP_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*/ 1192PHP_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*/ 1209PHP_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 */ 1232PHP_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 */ 1248PHP_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 */ 1265PHP_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 */ 1273PHP_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 */ 1281PHP_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 */ 1297PHP_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 */ 1312PHP_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 */ 1329PHP_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 */ 1345PHP_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() */ 1363void 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 */ 1403PHP_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 */ 1411PHP_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 */ 1428PHP_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) 1455PHP_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 */ 1475PHP_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 */ 1512PHP_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 */ 1528PHP_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 */ 1550PHP_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 */ 1567PHP_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 */ 1590PHP_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 */ 1606PHP_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 */ 1626static 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 */ 1692PHP_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 */ 1749PHP_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 */ 1768PHP_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 */ 1846PHP_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() */ 1855PHP_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 */ 1886PHP_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 */ 1907PHP_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*/ 1926PHP_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 */ 1953PHP_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 */ 1974PHP_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 */ 1994PHP_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 */ 2016PHP_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 */ 2032PHP_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 */ 2049PHP_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 */ 2066PHP_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 */ 2082PHP_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 */ 2102PHP_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 */ 2121PHP_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 */ 2143PHP_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*/ 2158PHP_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 */ 2184PHP_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 */ 2216PHP_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*/ 2236PHP_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*/ 2283PHP_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*/ 2310PHP_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*/ 2326PHP_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*/ 2343PHP_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*/ 2372PHP_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 */ 2396PHP_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*/ 2422PHP_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*/ 2471PHP_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 */ 2487PHP_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 */ 2517PHP_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 */ 2533PHP_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 */ 2541PHP_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 */ 2570PHP_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