PageRenderTime 214ms CodeModel.GetById 90ms app.highlight 112ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/mysqli/mysqli_api.c

http://php52-backports.googlecode.com/
C | 2178 lines | 1510 code | 342 blank | 326 comment | 319 complexity | bae15524b6c8cfe71215fc67e98fb255 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2  +----------------------------------------------------------------------+
   3  | PHP Version 5                                                        |
   4  +----------------------------------------------------------------------+
   5  | Copyright (c) 1997-2010 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  | Author: Georg Richter <georg@php.net>                                |
  16  +----------------------------------------------------------------------+
  17
  18  $Id: mysqli_api.c 298253 2010-04-21 12:52:24Z felipe $ 
  19*/
  20
  21#ifdef HAVE_CONFIG_H
  22#include "config.h"
  23#endif
  24
  25#include <signal.h>
  26
  27#include "php.h"
  28#include "php_ini.h"
  29#include "ext/standard/info.h"
  30#include "php_mysqli.h"
  31
  32/* {{{ proto mixed mysqli_affected_rows(object link)
  33   Get number of affected rows in previous MySQL operation */
  34PHP_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() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
  41		return;
  42	}
  43
  44	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_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_LONG(rc);
  51}
  52/* }}} */
  53
  54/* {{{ proto bool mysqli_autocommit(object link, bool mode)
  55   Turn auto commit on or of */
  56PHP_FUNCTION(mysqli_autocommit)
  57{
  58	MY_MYSQL 		*mysql;
  59	zval  			*mysql_link;
  60	zend_bool		automode;
  61
  62	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
  63		return;	
  64	}
  65	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  66
  67	if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
  68		RETURN_FALSE;
  69	}
  70	RETURN_TRUE;
  71}
  72/* }}} */
  73
  74/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....])
  75   Bind variables to a prepared statement as parameters */
  76PHP_FUNCTION(mysqli_stmt_bind_param)
  77{
  78	zval 			***args;
  79	int     		argc = ZEND_NUM_ARGS();
  80	int 	    	i;
  81	int				num_vars;
  82	int				start = 2;
  83	int				ofs;
  84	MY_STMT			*stmt;
  85	zval 			*mysql_stmt;
  86	MYSQL_BIND		*bind;
  87	char			*types;
  88	int				typelen;
  89	unsigned long	rc;
  90
  91	/* calculate and check number of parameters */
  92	if (argc < 2) {
  93		/* there has to be at least one pair */
  94		WRONG_PARAM_COUNT;
  95	}
  96
  97	if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &types, &typelen) == FAILURE) {
  98		return;	
  99	}
 100
 101	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); 
 102
 103	num_vars = argc - 1;
 104	if (getThis()) {
 105		start = 1;
 106	} else {
 107		/* ignore handle parameter in procedural interface*/
 108		--num_vars;
 109	}
 110
 111	if (typelen != argc - start) {
 112		/* number of bind variables doesn't match number of elements in type definition string */
 113		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
 114		RETURN_FALSE;
 115	}
 116
 117	if (typelen != stmt->stmt->param_count) {
 118		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
 119		RETURN_FALSE;
 120	}
 121
 122	/* prevent leak if variables are already bound */
 123	if (stmt->param.var_cnt) {
 124		php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
 125	}
 126
 127	args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
 128
 129	if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
 130		efree(args);
 131		WRONG_PARAM_COUNT;
 132	}
 133
 134	stmt->param.is_null = ecalloc(num_vars, sizeof(char));
 135	bind = (MYSQL_BIND *)ecalloc(num_vars, sizeof(MYSQL_BIND));
 136
 137	ofs = 0;
 138	for (i=start; i < argc; i++) {
 139
 140		/* set specified type */
 141		switch (types[ofs]) {
 142			case 'd': /* Double */
 143				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
 144				bind[ofs].buffer = (char*)&Z_DVAL_PP(args[i]);
 145				bind[ofs].is_null = &stmt->param.is_null[ofs];
 146				break;
 147
 148			case 'i': /* Integer */
 149				bind[ofs].buffer_type = MYSQL_TYPE_LONG;
 150				bind[ofs].buffer = (char*)&Z_LVAL_PP(args[i]);
 151				bind[ofs].is_null = &stmt->param.is_null[ofs];
 152				break;
 153
 154			case 'b': /* Blob (send data) */
 155				bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
 156				/* don't initialize is_null and length to 0 because we use ecalloc */
 157				break;
 158
 159			case 's': /* string */
 160				bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
 161				/* don't initialize buffer and buffer_length because we use ecalloc */
 162				bind[ofs].is_null = &stmt->param.is_null[ofs];
 163				break;
 164
 165			default:
 166				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
 167				RETVAL_FALSE;
 168				goto end;
 169		}
 170		ofs++;
 171	}
 172	rc = mysql_stmt_bind_param(stmt->stmt, bind);
 173	MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
 174
 175	if (rc) {
 176		RETVAL_FALSE;
 177		goto end;
 178	}
 179
 180	stmt->param.var_cnt = num_vars;
 181	stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0);
 182	for (i = 0; i < num_vars; i++) {
 183		if (bind[i].buffer_type  != MYSQL_TYPE_LONG_BLOB) {
 184			ZVAL_ADDREF(*args[i+start]);
 185			stmt->param.vars[i] = *args[i+start];
 186		} else {
 187			stmt->param.vars[i] = NULL;
 188		}
 189	}
 190	RETVAL_TRUE;
 191end:
 192	efree(args);
 193	efree(bind);
 194}
 195/* }}} */
 196
 197/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...])
 198   Bind variables to a prepared statement for result storage */
 199
 200/* TODO:
 201   do_alloca, free_alloca
 202*/
 203
 204PHP_FUNCTION(mysqli_stmt_bind_result)
 205{
 206	zval 		***args;
 207	int     	argc = ZEND_NUM_ARGS();
 208	int     	i;
 209	int			start = 1;
 210	int			var_cnt;
 211	int			ofs;
 212	long		col_type;
 213	ulong		rc;
 214	MY_STMT 	*stmt;
 215	zval 		*mysql_stmt;
 216	MYSQL_BIND 	*bind;
 217
 218	if (getThis()) {
 219		start = 0;
 220	}
 221
 222	if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
 223		return;	
 224	}
 225
 226	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); 
 227
 228	if (argc < (getThis() ? 1 : 2))  {
 229		WRONG_PARAM_COUNT;
 230	}
 231
 232	args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
 233
 234	if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
 235		efree(args);
 236		WRONG_PARAM_COUNT;
 237	}
 238
 239	var_cnt = argc - start;
 240
 241	if (var_cnt != mysql_stmt_field_count(stmt->stmt)) {
 242		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement");
 243		efree(args);
 244		RETURN_FALSE;
 245	}
 246
 247	/* prevent leak if variables are already bound */
 248	if (stmt->result.var_cnt) {
 249		php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
 250	}
 251
 252	bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
 253	{
 254		int size;
 255		char *p= emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
 256		stmt->result.buf = (VAR_BUFFER *) p;
 257		stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
 258		memset(p, 0, size);
 259	}
 260
 261	for (i=start; i < var_cnt + start ; i++) {
 262		ofs = i - start;
 263		col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
 264
 265		switch (col_type) {
 266			case MYSQL_TYPE_DOUBLE:
 267			case MYSQL_TYPE_FLOAT:
 268				convert_to_double_ex(args[i]);
 269				stmt->result.buf[ofs].type = IS_DOUBLE;
 270				stmt->result.buf[ofs].buflen = sizeof(double);
 271				
 272				/* allocate buffer for double */
 273				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
 274				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
 275				bind[ofs].buffer = stmt->result.buf[ofs].val;
 276				bind[ofs].is_null = &stmt->result.is_null[ofs];
 277				break;
 278
 279			case MYSQL_TYPE_NULL:
 280				stmt->result.buf[ofs].type = IS_NULL;
 281				/*
 282				  don't initialize to 0 :
 283				  1. stmt->result.buf[ofs].buflen
 284				  2. bind[ofs].buffer
 285				  3. bind[ofs].buffer_length
 286				  because memory was allocated with ecalloc
 287				*/
 288				bind[ofs].buffer_type = MYSQL_TYPE_NULL;
 289				bind[ofs].is_null = &stmt->result.is_null[ofs];
 290				break;
 291
 292			case MYSQL_TYPE_SHORT:
 293			case MYSQL_TYPE_TINY:
 294			case MYSQL_TYPE_LONG:
 295			case MYSQL_TYPE_INT24:
 296			case MYSQL_TYPE_YEAR:
 297				convert_to_long_ex(args[i]);
 298				stmt->result.buf[ofs].type = IS_LONG;
 299				/* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
 300				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
 301				bind[ofs].buffer_type = MYSQL_TYPE_LONG;
 302				bind[ofs].buffer = stmt->result.buf[ofs].val;
 303				bind[ofs].is_null = &stmt->result.is_null[ofs];
 304				bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
 305				break;
 306
 307			case MYSQL_TYPE_LONGLONG:
 308#if MYSQL_VERSION_ID > 50002
 309			case MYSQL_TYPE_BIT:
 310#endif
 311				stmt->result.buf[ofs].type = IS_STRING; 
 312				stmt->result.buf[ofs].buflen = sizeof(my_ulonglong); 
 313				stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
 314				bind[ofs].buffer_type = col_type;
 315				bind[ofs].buffer = stmt->result.buf[ofs].val;
 316				bind[ofs].is_null = &stmt->result.is_null[ofs];
 317				bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
 318				bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
 319				break;
 320
 321			case MYSQL_TYPE_DATE:
 322			case MYSQL_TYPE_TIME:
 323			case MYSQL_TYPE_DATETIME:
 324			case MYSQL_TYPE_NEWDATE:
 325			case MYSQL_TYPE_VAR_STRING:
 326			case MYSQL_TYPE_STRING:
 327			case MYSQL_TYPE_BLOB:
 328			case MYSQL_TYPE_TINY_BLOB:
 329			case MYSQL_TYPE_MEDIUM_BLOB:
 330			case MYSQL_TYPE_LONG_BLOB:
 331			case MYSQL_TYPE_TIMESTAMP:
 332			case MYSQL_TYPE_DECIMAL:
 333#ifdef FIELD_TYPE_NEWDECIMAL
 334			case MYSQL_TYPE_NEWDECIMAL:
 335#endif
 336			{
 337#if MYSQL_VERSION_ID > 50099
 338				/* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
 339				my_bool tmp;
 340#else
 341				ulong tmp = 0;
 342#endif
 343				stmt->result.buf[ofs].type = IS_STRING;
 344				/*
 345					If the user has called $stmt->store_result() then we have asked
 346					max_length to be updated. this is done only for BLOBS because we don't want to allocate
 347					big chunkgs of memory 2^16 or 2^24 
 348				*/
 349				if (stmt->stmt->fields[ofs].max_length == 0 &&
 350					!mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
 351				{
 352					stmt->result.buf[ofs].buflen =
 353						(stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
 354				} else {
 355					/*
 356						the user has called store_result(). if he does not there is no way to determine the
 357						libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
 358					*/
 359					if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
 360						++stmt->result.buf[ofs].buflen;
 361				}
 362				stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
 363				bind[ofs].buffer_type = MYSQL_TYPE_STRING;
 364				bind[ofs].buffer = stmt->result.buf[ofs].val;
 365				bind[ofs].is_null = &stmt->result.is_null[ofs];
 366				bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
 367				bind[ofs].length = &stmt->result.buf[ofs].output_len;
 368				break;
 369			}
 370			default:
 371				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);
 372				break;
 373		}
 374	}
 375
 376	rc = mysql_stmt_bind_result(stmt->stmt, bind);
 377	MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
 378
 379	if (rc) {
 380		/* dont close the statement or subsequent usage (for example ->execute()) will lead to crash */
 381		for (i=0; i < var_cnt ; i++) {
 382			if (stmt->result.buf[i].val) {
 383				efree(stmt->result.buf[i].val);
 384			}
 385		}
 386		/* Don't free stmt->result.is_null because is_null & buf are one block of memory  */
 387		efree(stmt->result.buf);
 388		RETVAL_FALSE;
 389	} else {
 390		stmt->result.var_cnt = var_cnt;
 391		stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0);
 392		for (i = start; i < var_cnt+start; i++) {
 393			ofs = i-start;
 394			ZVAL_ADDREF(*args[i]);
 395			stmt->result.vars[ofs] = *args[i];
 396		}
 397		RETVAL_TRUE;
 398	}
 399	efree(args);
 400	efree(bind);
 401}
 402/* }}} */
 403
 404/* {{{ proto bool mysqli_change_user(object link, string user, string password, string database)
 405   Change logged-in user of the active connection */
 406PHP_FUNCTION(mysqli_change_user)
 407{
 408	MY_MYSQL	*mysql;
 409	zval  		*mysql_link = NULL;
 410	char  		*user, *password, *dbname;
 411	int   		user_len, password_len, dbname_len;
 412	ulong		rc;
 413
 414	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) {
 415		return;
 416	}
 417	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 418
 419	rc = mysql_change_user(mysql->mysql, user, password, dbname);
 420	MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
 421
 422	if (rc) {
 423		RETURN_FALSE;
 424	}
 425
 426	RETURN_TRUE;
 427}
 428/* }}} */
 429
 430/* {{{ proto string mysqli_character_set_name(object link)
 431   Returns the name of the character set used for this connection */
 432PHP_FUNCTION(mysqli_character_set_name)
 433{
 434	MY_MYSQL 	*mysql;
 435	zval  		*mysql_link;
 436
 437	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 438		return;
 439	}
 440
 441	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 442
 443	RETURN_STRING((char *) mysql_character_set_name(mysql->mysql), 1);
 444}
 445/* }}} */
 446
 447/* {{{ proto bool mysqli_close(object link)
 448   Close connection */
 449PHP_FUNCTION(mysqli_close)
 450{
 451	zval 		*mysql_link;
 452	MY_MYSQL 	*mysql;
 453	
 454	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 455		return;
 456	}
 457
 458	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
 459
 460	mysql_close(mysql->mysql);
 461	mysql->mysql = NULL;
 462	php_clear_mysql(mysql);
 463	efree(mysql);
 464	MYSQLI_CLEAR_RESOURCE(&mysql_link);	
 465	RETURN_TRUE;
 466}
 467/* }}} */
 468
 469/* {{{ proto bool mysqli_commit(object link)
 470   Commit outstanding actions and close transaction */
 471PHP_FUNCTION(mysqli_commit)
 472{
 473	MY_MYSQL 	*mysql;
 474	zval 		*mysql_link;
 475
 476	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 477		return;
 478	}
 479	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 480	if (mysql_commit(mysql->mysql)) {
 481		RETURN_FALSE;
 482	}
 483	RETURN_TRUE;
 484}
 485/* }}} */
 486
 487/* {{{ proto bool mysqli_data_seek(object result, int offset)
 488   Move internal result pointer */
 489PHP_FUNCTION(mysqli_data_seek)
 490{
 491	MYSQL_RES	*result;
 492	zval  		*mysql_result;
 493	long  		offset;
 494
 495	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
 496		return;
 497	}
 498
 499	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 500
 501	if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) {
 502		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
 503		RETURN_FALSE;
 504	}
 505
 506	if (offset < 0 || offset >= result->row_count) {
 507	   RETURN_FALSE;
 508	}
 509
 510	mysql_data_seek(result, offset);
 511	RETURN_TRUE;
 512}
 513/* }}} */
 514
 515/* {{{ proto void mysqli_debug(string debug)
 516*/
 517PHP_FUNCTION(mysqli_debug)
 518{
 519	char		*debug;
 520	int			debug_len;
 521
 522	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
 523		return;
 524	}
 525	
 526	mysql_debug(debug);
 527	RETURN_TRUE;
 528}
 529/* }}} */
 530
 531/* {{{ proto bool mysqli_dump_debug_info(object link)
 532*/
 533PHP_FUNCTION(mysqli_dump_debug_info)
 534{
 535	MY_MYSQL 	*mysql;
 536	zval  		*mysql_link;
 537	ulong		rc;
 538
 539	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 540		return;
 541	}
 542	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 543
 544	rc = mysql_dump_debug_info(mysql->mysql);
 545
 546	if (rc) {
 547		RETURN_FALSE;
 548	}
 549	RETURN_TRUE;	
 550}
 551/* }}} */
 552
 553/* {{{ proto int mysqli_errno(object link)
 554   Returns the numerical value of the error message from previous MySQL operation */
 555PHP_FUNCTION(mysqli_errno)
 556{
 557	MY_MYSQL 	*mysql;
 558	zval  		*mysql_link;
 559
 560	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 561		return;
 562	}
 563	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 564	RETURN_LONG(mysql_errno(mysql->mysql));
 565}
 566/* }}} */
 567
 568/* {{{ proto string mysqli_error(object link)
 569   Returns the text of the error message from previous MySQL operation */
 570PHP_FUNCTION(mysqli_error) 
 571{
 572	MY_MYSQL 	*mysql;
 573	zval  		*mysql_link;
 574
 575	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 576		return;
 577	}
 578	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 579	RETURN_STRING((char *)mysql_error(mysql->mysql),1);
 580}
 581/* }}} */
 582
 583/* {{{ proto bool mysqli_stmt_execute(object stmt)
 584   Execute a prepared statement */
 585PHP_FUNCTION(mysqli_stmt_execute)
 586{
 587	MY_STMT 		*stmt;
 588	zval 			*mysql_stmt;
 589	unsigned int 	i;
 590
 591	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
 592		return;
 593	}
 594	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
 595	
 596	for (i = 0; i < stmt->param.var_cnt; i++) {		
 597		if (stmt->param.vars[i]) {
 598			if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) {
 599				switch (stmt->stmt->params[i].buffer_type) {
 600					case MYSQL_TYPE_VAR_STRING:
 601						convert_to_string_ex(&stmt->param.vars[i]);
 602						stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->param.vars[i]);
 603						stmt->stmt->params[i].buffer_length = Z_STRLEN_PP(&stmt->param.vars[i]);
 604						break;
 605					case MYSQL_TYPE_DOUBLE:
 606						convert_to_double_ex(&stmt->param.vars[i]);
 607						stmt->stmt->params[i].buffer = (char*)&Z_LVAL_PP(&stmt->param.vars[i]);
 608						break;
 609					case MYSQL_TYPE_LONG:
 610						convert_to_long_ex(&stmt->param.vars[i]);
 611						stmt->stmt->params[i].buffer = (char*)&Z_LVAL_PP(&stmt->param.vars[i]);
 612						break;
 613					default:
 614						break;
 615				}
 616			}	
 617		}
 618	}
 619	if (mysql_stmt_execute(stmt->stmt)) {
 620		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
 621		RETURN_FALSE;
 622	}
 623
 624	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
 625		php_mysqli_report_index(stmt->query, stmt->stmt->mysql->server_status TSRMLS_CC);
 626	}
 627	
 628	RETURN_TRUE;
 629}
 630/* }}} */
 631
 632/* {{{ proto mixed mysqli_stmt_fetch(object stmt)
 633   Fetch results from a prepared statement into the bound variables */
 634PHP_FUNCTION(mysqli_stmt_fetch)
 635{
 636	MY_STMT 		*stmt;
 637	zval 			*mysql_stmt;
 638	unsigned int 	i;
 639	ulong 			ret;
 640	unsigned int    uval;
 641	my_ulonglong	llval;
 642	
 643
 644	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
 645		return;
 646	}
 647	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
 648	
 649	/* reset buffers */
 650
 651
 652	for (i = 0; i < stmt->result.var_cnt; i++) {
 653		if (stmt->result.buf[i].type == IS_STRING) {
 654			memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
 655		}
 656	}
 657	ret = mysql_stmt_fetch(stmt->stmt);
 658#ifdef MYSQL_DATA_TRUNCATED
 659	if (!ret || ret == MYSQL_DATA_TRUNCATED) {
 660#else
 661	if (!ret) {
 662#endif
 663		for (i = 0; i < stmt->result.var_cnt; i++) {
 664			/* Even if the string is of length zero there is one byte alloced so efree() in all cases */
 665			if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) {
 666				efree(stmt->result.vars[i]->value.str.val);
 667			}
 668			if (!stmt->result.is_null[i]) {
 669				switch (stmt->result.buf[i].type) {
 670					case IS_LONG:
 671						if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG) 
 672						    && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)) 
 673						{
 674							/* unsigned int (11) */
 675							uval= *(unsigned int *) stmt->result.buf[i].val;
 676
 677							if (uval > INT_MAX) {
 678								char *tmp, *p;
 679								int j=10;
 680								tmp= emalloc(11);
 681								p= &tmp[9];
 682								do { 
 683									*p-- = (uval % 10) + 48;
 684									uval = uval / 10;							
 685								} while (--j > 0);
 686								tmp[10]= '\0';
 687								/* unsigned int > INT_MAX is 10 digis - ALWAYS */
 688								ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0);
 689								break;
 690							}
 691						}
 692						if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) { 
 693							ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val);
 694						} else {
 695							ZVAL_LONG(stmt->result.vars[i], *(int *)stmt->result.buf[i].val);
 696						}
 697						break;
 698					case IS_DOUBLE:
 699						ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val);
 700						break;
 701					case IS_STRING:
 702						if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG) {
 703							my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
 704							llval= *(my_ulonglong *) stmt->result.buf[i].val;
 705#if SIZEOF_LONG==8  
 706							if (uns && llval > 9223372036854775807L) {
 707#elif SIZEOF_LONG==4
 708							if ((uns && llval > L64(2147483647)) || 
 709							    (!uns && (( L64(2147483647) < (my_longlong) llval) || (L64(-2147483648) > (my_longlong) llval))))
 710							{
 711#endif
 712								char tmp[22];
 713								/* even though lval is declared as unsigned, the value
 714								 * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
 715								 * use MYSQLI_LL_SPEC.
 716								 */
 717								snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
 718								ZVAL_STRING(stmt->result.vars[i], tmp, 1);
 719							} else {
 720								ZVAL_LONG(stmt->result.vars[i], llval);
 721							}
 722						} 
 723#if MYSQL_VERSION_ID > 50002
 724						else if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
 725							llval = *(my_ulonglong *)stmt->result.buf[i].val;
 726							ZVAL_LONG(stmt->result.vars[i], llval);
 727						}
 728#endif
 729						else {
 730#if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
 731							if(ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
 732								/* result was truncated */
 733								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length, 1);
 734							} else {
 735#else
 736							{
 737#endif
 738								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].output_len, 1);
 739							}
 740						}
 741						break;
 742					default:
 743						break;	
 744				}
 745			} else {
 746				ZVAL_NULL(stmt->result.vars[i]);
 747			}
 748		}
 749	} else {
 750		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
 751	}
 752
 753	switch (ret) {
 754		case 0:
 755#ifdef MYSQL_DATA_TRUNCATED
 756		/* according to SQL standard truncation (e.g. loss of precision is
 757		   not an error) - for detecting possible truncation you have to 
 758		   check mysqli_stmt_warning
 759		*/
 760		case MYSQL_DATA_TRUNCATED:
 761#endif
 762			RETURN_TRUE;
 763		break;
 764		case 1:
 765			RETURN_FALSE;
 766		break;
 767		default:
 768			RETURN_NULL();
 769		break;
 770	}
 771}
 772/* }}} */
 773
 774/* {{{ proto mixed mysqli_fetch_field (object result)
 775   Get column information from a result and return as an object */
 776PHP_FUNCTION(mysqli_fetch_field) 
 777{
 778	MYSQL_RES 	*result;
 779	zval  		*mysql_result;
 780	MYSQL_FIELD *field;
 781
 782	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
 783		return;
 784	}
 785
 786	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 787
 788	if (!(field = mysql_fetch_field(result))) {
 789		RETURN_FALSE;
 790	}
 791
 792	object_init(return_value);
 793
 794	add_property_string(return_value, "name",(field->name ? field->name : ""), 1);
 795	add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1);
 796	add_property_string(return_value, "table",(field->table ? field->table : ""), 1);
 797	add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1);
 798	add_property_string(return_value, "db",(field->db ? field->db : ""), 1);
 799	add_property_string(return_value, "catalog",(field->catalog ? field->catalog : ""), 1);
 800	add_property_string(return_value, "def",(field->def ? field->def : ""), 1);
 801	add_property_long(return_value, "max_length", field->max_length);
 802	add_property_long(return_value, "length", field->length);
 803	add_property_long(return_value, "charsetnr", field->charsetnr);
 804	add_property_long(return_value, "flags", field->flags);
 805	add_property_long(return_value, "type", field->type);
 806	add_property_long(return_value, "decimals", field->decimals);
 807}
 808/* }}} */
 809
 810/* {{{ proto mixed mysqli_fetch_fields (object result)
 811   Return array of objects containing field meta-data */
 812PHP_FUNCTION(mysqli_fetch_fields) 
 813{
 814	MYSQL_RES	*result;
 815	zval  		*mysql_result;
 816	MYSQL_FIELD	*field;
 817	zval 		*obj;
 818
 819	unsigned int i;
 820
 821	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
 822		return;
 823	}
 824
 825	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 826
 827	array_init(return_value);
 828
 829	for (i = 0; i < mysql_num_fields(result); i++) {
 830		field = mysql_fetch_field_direct(result, i);
 831
 832
 833		MAKE_STD_ZVAL(obj);
 834		object_init(obj);
 835
 836		add_property_string(obj, "name",(field->name ? field->name : ""), 1);
 837		add_property_string(obj, "orgname",(field->org_name ? field->org_name : ""), 1);
 838		add_property_string(obj, "table",(field->table ? field->table : ""), 1);
 839		add_property_string(obj, "orgtable",(field->org_table ? field->org_table : ""), 1);
 840		add_property_string(obj, "def",(field->def ? field->def : ""), 1);
 841		add_property_long(obj, "max_length", field->max_length);
 842		add_property_long(obj, "length", field->length);
 843		add_property_long(obj, "charsetnr", field->charsetnr);
 844		add_property_long(obj, "flags", field->flags);
 845		add_property_long(obj, "type", field->type);
 846		add_property_long(obj, "decimals", field->decimals);
 847
 848		add_index_zval(return_value, i, obj);
 849	}
 850}
 851/* }}} */
 852
 853/* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset)
 854   Fetch meta-data for a single field */
 855PHP_FUNCTION(mysqli_fetch_field_direct) 
 856{
 857	MYSQL_RES	*result;
 858	zval		*mysql_result;
 859	MYSQL_FIELD *field;
 860	long 		offset;
 861
 862	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
 863		return;
 864	}
 865
 866	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 867	
 868	if (offset < 0 || offset >= mysql_num_fields(result)) {
 869		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field offset is invalid for resultset");
 870		RETURN_FALSE; 
 871	}
 872
 873	if (!(field = mysql_fetch_field_direct(result,offset))) {
 874		RETURN_FALSE;
 875	}
 876
 877	object_init(return_value);
 878
 879	add_property_string(return_value, "name",(field->name ? field->name : ""), 1);
 880	add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1);
 881	add_property_string(return_value, "table",(field->table ? field->table : ""), 1);
 882	add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1);
 883	add_property_string(return_value, "db",(field->db ? field->db : ""), 1);
 884	add_property_string(return_value, "catalog",(field->catalog ? field->catalog : ""), 1);
 885	add_property_string(return_value, "def",(field->def ? field->def : ""), 1);
 886	add_property_long(return_value, "max_length", field->max_length);
 887	add_property_long(return_value, "length", field->length);
 888	add_property_long(return_value, "charsetnr", field->charsetnr);
 889	add_property_long(return_value, "flags", field->flags);
 890	add_property_long(return_value, "type", field->type);
 891	add_property_long(return_value, "decimals", field->decimals);
 892}
 893/* }}} */
 894
 895/* {{{ proto mixed mysqli_fetch_lengths (object result)
 896   Get the length of each output in a result */
 897PHP_FUNCTION(mysqli_fetch_lengths) 
 898{
 899	MYSQL_RES		*result;
 900	zval			*mysql_result;
 901	unsigned int	i;
 902	unsigned long	*ret;
 903	
 904	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
 905		return;
 906	}
 907
 908	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 909
 910	if (!(ret = mysql_fetch_lengths(result))) {
 911		RETURN_FALSE;
 912	}
 913
 914	array_init(return_value);
 915
 916	for (i = 0; i < mysql_num_fields(result); i++) {
 917		add_index_long(return_value, i, ret[i]);	
 918	}
 919}
 920/* }}} */
 921
 922/* {{{ proto array mysqli_fetch_row (object result)
 923   Get a result row as an enumerated array */
 924PHP_FUNCTION(mysqli_fetch_row) 
 925{
 926	php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
 927}
 928/* }}} */
 929
 930/* {{{ proto int mysqli_field_count(object link)
 931   Fetch the number of fields returned by the last query for the given link
 932*/
 933PHP_FUNCTION(mysqli_field_count) 
 934{
 935	MY_MYSQL 	*mysql;
 936	zval  		*mysql_link;
 937
 938	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
 939		return;
 940	}
 941	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
 942
 943	RETURN_LONG(mysql_field_count(mysql->mysql));
 944}
 945/* }}} */
 946
 947/* {{{ proto int mysqli_field_seek(object result, int fieldnr)
 948   Set result pointer to a specified field offset
 949*/
 950PHP_FUNCTION(mysqli_field_seek)
 951{
 952	MYSQL_RES		*result;
 953	zval			*mysql_result;
 954	unsigned long	fieldnr;
 955
 956	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
 957		return;
 958	}
 959	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 960
 961	if (fieldnr < 0 || fieldnr >= mysql_num_fields(result)) {
 962		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");
 963		RETURN_FALSE; 
 964	}
 965	
 966	mysql_field_seek(result, fieldnr);
 967	RETURN_TRUE;
 968}
 969/* }}} */
 970
 971/* {{{ proto int mysqli_field_tell(object result)
 972   Get current field offset of result pointer */
 973PHP_FUNCTION(mysqli_field_tell)
 974{
 975	MYSQL_RES	*result;
 976	zval		*mysql_result;
 977
 978	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
 979		return;
 980	}
 981	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 982	
 983	RETURN_LONG(mysql_field_tell(result));
 984}
 985/* }}} */
 986
 987/* {{{ proto void mysqli_free_result(object result)
 988   Free query result memory for the given result handle */
 989PHP_FUNCTION(mysqli_free_result) 
 990{
 991	MYSQL_RES	*result;
 992	zval		*mysql_result;
 993
 994	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
 995		return;
 996	}
 997	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
 998
 999	mysql_free_result(result);
1000	MYSQLI_CLEAR_RESOURCE(&mysql_result);	
1001}
1002/* }}} */
1003
1004/* {{{ proto string mysqli_get_client_info(void) 
1005   Get MySQL client info */
1006PHP_FUNCTION(mysqli_get_client_info)
1007{
1008	RETURN_STRING((char *)mysql_get_client_info(), 1);
1009}
1010/* }}} */
1011
1012/* {{{ proto int mysqli_get_client_version(void) 
1013   Get MySQL client info */
1014PHP_FUNCTION(mysqli_get_client_version)
1015{
1016	RETURN_LONG((long)mysql_get_client_version());
1017}
1018/* }}} */
1019
1020/* {{{ proto string mysqli_get_host_info (object link) 
1021   Get MySQL host info */
1022PHP_FUNCTION(mysqli_get_host_info)
1023{
1024	MY_MYSQL	*mysql;
1025	zval  		*mysql_link = NULL;
1026
1027	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1028		return;
1029	}
1030	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1031
1032	RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1);
1033}
1034/* }}} */
1035
1036/* {{{ proto int mysqli_get_proto_info(object link)
1037   Get MySQL protocol information */
1038PHP_FUNCTION(mysqli_get_proto_info)
1039{
1040	MY_MYSQL 	*mysql;
1041	zval  		*mysql_link = NULL;
1042
1043	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1044		return;
1045	}
1046	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1047
1048	RETURN_LONG(mysql_get_proto_info(mysql->mysql));
1049}
1050/* }}} */
1051
1052/* {{{ proto string mysqli_get_server_info(object link) 
1053   Get MySQL server info */
1054PHP_FUNCTION(mysqli_get_server_info)
1055{
1056	MY_MYSQL	*mysql;
1057	zval	  	*mysql_link = NULL;
1058
1059	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1060		return;
1061	}
1062	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1063
1064	RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1);
1065}
1066
1067/* }}} */
1068
1069/* {{{ proto int mysqli_get_server_version(object link) 
1070   Return the MySQL version for the server referenced by the given link */
1071PHP_FUNCTION(mysqli_get_server_version)
1072{
1073	MY_MYSQL	*mysql;
1074	zval		*mysql_link = NULL;
1075
1076	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1077		return;
1078	}
1079	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1080
1081	RETURN_LONG(mysql_get_server_version(mysql->mysql));
1082}
1083/* }}} */
1084
1085/* {{{ proto string mysqli_info(object link)
1086   Get information about the most recent query */
1087PHP_FUNCTION(mysqli_info)
1088{
1089	MY_MYSQL	*mysql;
1090	zval  		*mysql_link = NULL;
1091
1092	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1093		return;
1094	}
1095	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1096
1097	RETURN_STRING((mysql->mysql->info) ? mysql->mysql->info : "", 1);
1098}
1099/* }}} */
1100
1101
1102/* {{{ php_mysqli_init() */
1103void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS)
1104{
1105	MYSQLI_RESOURCE *mysqli_resource;
1106	MY_MYSQL *mysql;
1107
1108	if (getThis() && ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr) {
1109		return;
1110	}
1111
1112	mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
1113
1114	if (!(mysql->mysql = mysql_init(NULL))) {
1115		efree(mysql);
1116		RETURN_FALSE;
1117	}
1118
1119	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1120	mysqli_resource->ptr = (void *)mysql;
1121	mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
1122
1123	if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC)) {
1124		MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);	
1125	} else {
1126		((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
1127	}
1128
1129}
1130/* }}} */
1131
1132
1133/* {{{ proto resource mysqli_init(void)
1134   Initialize mysqli and return a resource for use with mysql_real_connect */
1135PHP_FUNCTION(mysqli_init)
1136{
1137	php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1138}
1139/* }}} */
1140
1141
1142/* {{{ proto mixed mysqli_insert_id(object link)
1143   Get the ID generated from the previous INSERT operation */
1144PHP_FUNCTION(mysqli_insert_id)
1145{
1146	MY_MYSQL		*mysql;
1147	my_ulonglong 	rc;
1148	zval  			*mysql_link;
1149
1150	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1151		return;
1152	}
1153	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1154	rc = mysql_insert_id(mysql->mysql);
1155	MYSQLI_RETURN_LONG_LONG(rc)
1156}
1157/* }}} */
1158
1159/* {{{ proto bool mysqli_kill(object link, int processid)
1160   Kill a mysql process on the server */
1161PHP_FUNCTION(mysqli_kill)
1162{
1163	MY_MYSQL 	*mysql;
1164	zval  		*mysql_link;
1165	long   		processid;
1166
1167	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
1168		return;
1169	}
1170	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1171	
1172	if (mysql_kill(mysql->mysql, processid)) {
1173		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1174		RETURN_FALSE;
1175	}
1176	RETURN_TRUE;
1177}
1178/* }}} */
1179
1180/* {{{ proto void mysqli_set_local_infile_default(object link)
1181   unsets user defined handler for load local infile command */
1182PHP_FUNCTION(mysqli_set_local_infile_default)
1183{
1184	MY_MYSQL	*mysql;
1185	zval		*mysql_link;
1186
1187	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1188		return;
1189	}
1190
1191	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1192
1193	if (mysql->li_read) {
1194		zval_ptr_dtor(&(mysql->li_read));
1195		mysql->li_read = NULL;
1196	}
1197}
1198/* }}} */
1199
1200/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
1201   Set callback functions for LOAD DATA LOCAL INFILE */
1202PHP_FUNCTION(mysqli_set_local_infile_handler)
1203{
1204	MY_MYSQL	*mysql;
1205	zval  		*mysql_link;
1206	char		*callback_name;
1207	zval		*callback_func;
1208
1209	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
1210			&callback_func) == FAILURE) {
1211		return;
1212	}
1213
1214	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1215
1216	/* check callback function */
1217	if (!zend_is_callable(callback_func, 0, &callback_name)) {
1218		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
1219		efree(callback_name);
1220		RETURN_FALSE;		
1221	}
1222
1223	/* save callback function */
1224	if (!mysql->li_read) {
1225		MAKE_STD_ZVAL(mysql->li_read);
1226	} else {
1227		zval_dtor(mysql->li_read);
1228	}
1229	ZVAL_STRING(mysql->li_read, callback_name, 0);
1230
1231	RETURN_TRUE;
1232}
1233/* }}} */
1234
1235/* {{{ proto bool mysqli_more_results(object link)
1236   check if there any more query results from a multi query */
1237PHP_FUNCTION(mysqli_more_results)
1238{
1239	MY_MYSQL		*mysql;
1240	zval			*mysql_link;
1241
1242	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1243		return;
1244	}
1245	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1246
1247	RETURN_BOOL(mysql_more_results(mysql->mysql));
1248}
1249/* }}} */
1250
1251/* {{{ proto bool mysqli_next_result(object link)
1252   read next result from multi_query */
1253PHP_FUNCTION(mysqli_next_result) {
1254	MY_MYSQL		*mysql;
1255	zval			*mysql_link;
1256
1257	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1258		return;
1259	}
1260	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1261
1262	RETURN_BOOL(!mysql_next_result(mysql->mysql));
1263}
1264/* }}} */
1265
1266/* {{{ proto int mysqli_num_fields(object result)
1267   Get number of fields in result */
1268PHP_FUNCTION(mysqli_num_fields)
1269{
1270	MYSQL_RES	*result;
1271	zval		*mysql_result;
1272
1273	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1274		return;
1275	}
1276	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1277
1278	RETURN_LONG(mysql_num_fields(result));
1279}
1280/* }}} */
1281
1282/* {{{ proto mixed mysqli_num_rows(object result)
1283   Get number of rows in result */
1284PHP_FUNCTION(mysqli_num_rows)
1285{
1286	MYSQL_RES	*result;
1287	zval		*mysql_result;
1288
1289	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
1290		return;
1291	}
1292	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1293
1294	if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) {
1295		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
1296		RETURN_LONG(0);
1297	}
1298
1299	MYSQLI_RETURN_LONG_LONG(mysql_num_rows(result));
1300}
1301/* }}} */
1302
1303/* {{{ proto bool mysqli_options(object link, int flags, mixed values)
1304   Set options */
1305PHP_FUNCTION(mysqli_options)
1306{
1307	MY_MYSQL 		*mysql;
1308	zval  			*mysql_link = NULL;
1309	zval  			**mysql_value;
1310	long  			mysql_option;
1311	unsigned int 	l_value;
1312	long  			ret;
1313
1314	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OlZ", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
1315		return;
1316	}
1317	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
1318
1319	if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
1320		if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
1321			RETURN_FALSE;
1322		}
1323	}
1324
1325	switch (Z_TYPE_PP(mysql_value)) {
1326		case IS_STRING:
1327			ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(mysql_value));
1328			break;
1329		default:
1330			convert_to_long_ex(mysql_value);
1331			l_value = Z_LVAL_PP(mysql_value);
1332			ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
1333			break;
1334	}
1335
1336	RETURN_BOOL(!ret);
1337}   
1338/* }}} */
1339
1340
1341/* {{{ proto bool mysqli_ping(object link)
1342   Ping a server connection or reconnect if there is no connection */
1343PHP_FUNCTION(mysqli_ping)
1344{
1345	MY_MYSQL 	*mysql;
1346	zval  		*mysql_link;
1347	long		rc;
1348
1349	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1350		return;
1351	}
1352	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1353	rc = mysql_ping(mysql->mysql);
1354	MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1355
1356	RETURN_BOOL(!rc);
1357}
1358/* }}} */
1359
1360/* {{{ proto mixed mysqli_prepare(object link, string query)
1361   Prepare a SQL statement for execution */
1362PHP_FUNCTION(mysqli_prepare)
1363{
1364	MY_MYSQL		*mysql;
1365	MY_STMT 		*stmt;
1366	char			*query = NULL;
1367	unsigned int	query_len;
1368	zval			*mysql_link;
1369	MYSQLI_RESOURCE *mysqli_resource; 
1370
1371	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1372		return;
1373	}
1374	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1375	if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
1376		php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");
1377		RETURN_FALSE;
1378	}
1379
1380	stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
1381
1382	if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
1383		if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
1384  			char  last_error[MYSQL_ERRMSG_SIZE];
1385  			char  sqlstate[SQLSTATE_LENGTH+1];	
1386			unsigned int last_errno;
1387
1388			/* mysql_stmt_close clears errors, so we have to store them temporarily */
1389			last_errno = stmt->stmt->last_errno;
1390			memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
1391			memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
1392
1393			mysql_stmt_close(stmt->stmt);
1394			stmt->stmt = NULL;
1395
1396			/* restore error messages */
1397			mysql->mysql->net.last_errno = last_errno;
1398			memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
1399			memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
1400		}
1401	}
1402	/* don't joing to the previous if because it won't work if mysql_stmt_prepare_fails */
1403	if (!stmt->stmt) {
1404		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1405		efree(stmt);
1406		RETURN_FALSE;
1407	}
1408
1409
1410	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
1411	mysqli_resource->ptr = (void *)stmt;
1412	/* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
1413	/* Get performance boost if reporting is switched off */
1414	if (query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
1415		stmt->query = (char *)emalloc(query_len + 1);
1416		memcpy(stmt->query, query, query_len);
1417		stmt->query[query_len] = '\0';
1418	}
1419
1420	/* change status */
1421	mysqli_resource->status = MYSQLI_STATUS_VALID;
1422	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
1423}
1424/* }}} */
1425
1426/* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])
1427   Open a connection to a mysql server */ 
1428PHP_FUNCTION(mysqli_real_connect)
1429{
1430	MY_MYSQL 		*mysql;
1431	char 			*hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
1432	unsigned int 	hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
1433	unsigned long 	port=0, flags=0;
1434	zval			*mysql_link;
1435
1436	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &mysql_link, mysqli_link_class_entry,
1437		&hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len,
1438		&flags) == FAILURE) {
1439		return;
1440	}
1441
1442	if (!socket_len) {
1443		socket = NULL;
1444	}
1445
1446	/* TODO: safe mode handling */
1447	if (PG(sql_safe_mode)) {
1448	} else {
1449		if (!socket_len || !socket) {
1450			socket = MyG(default_socket);
1451		}
1452		if (!port) {
1453			port = MyG(default_port);
1454		}
1455		if (!passwd) {
1456			passwd = MyG(default_pw);
1457		}
1458		if (!username){
1459			username = MyG(default_user);
1460		}
1461		if (!hostname) {
1462			hostname = MyG(default_host);
1463		}
1464	}	
1465
1466	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
1467
1468
1469	/* set some required options */
1470	flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
1471	/* remove some insecure options */
1472	flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
1473	if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
1474		flags &= ~CLIENT_LOCAL_FILES;
1475	}
1476
1477	if (!socket) {
1478		socket = MyG(default_socket);
1479	}
1480
1481	if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,flags) == NULL) {
1482		php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
1483		php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
1484										"%s", mysql->mysql->net.last_error);
1485
1486		/* change status */
1487		MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_INITIALIZED);
1488		RETURN_FALSE;
1489	}
1490
1491	php_mysqli_set_error(mysql_errno(mysql->mysql), (char *)mysql_error(mysql->mysql) TSRMLS_CC);
1492
1493	mysql->mysql->reconnect = MyG(reconnect);
1494
1495	/* set our own local_infile handler */
1496	php_set_local_infile_handler_default(mysql);
1497
1498	/* change status */
1499	MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_VALID);
1500
1501	RETURN_TRUE;
1502}
1503/* }}} */
1504
1505/* {{{ proto bool mysqli_real_query(object link, string query)
1506   Binary-safe version of mysql_query() */
1507PHP_FUNCTION(mysqli_real_query)
1508{
1509	MY_MYSQL		*mysql;
1510	zval			*mysql_link;
1511	char			*query = NULL;
1512	unsigned int 	query_len;
1513
1514	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
1515		return;
1516	}
1517	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1518
1519	MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
1520
1521	if (mysql_real_query(mysql->mysql, query, query_len)) {
1522		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1523		RETURN_FALSE;
1524	}
1525
1526	if (!mysql_field_count(mysql->mysql)) {
1527		if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
1528			php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
1529		}
1530	}
1531
1532	RETURN_TRUE;
1533}
1534/* }}} */
1535
1536/* {{{ proto string mysqli_real_escape_string(object link, string escapestr) 
1537   Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
1538PHP_FUNCTION(mysqli_real_escape_string) {
1539	MY_MYSQL	*mysql;
1540	zval		*mysql_link = NULL;
1541	char		*escapestr, *newstr;
1542	int			escapestr_len, newstr_len;
1543
1544	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
1545		return;
1546	}	
1547	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1548
1549	newstr = safe_emalloc(2, escapestr_len, 1);
1550	newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len);
1551	newstr = erealloc(newstr, newstr_len + 1);
1552		
1553	RETURN_STRINGL(newstr, newstr_len, 0);
1554}
1555/* }}} */
1556
1557/* {{{ proto bool mysqli_rollback(object link)
1558   Undo actions from current transaction */
1559PHP_FUNCTION(mysqli_rollback)
1560{
1561	MY_MYSQL	*mysql;
1562	zval  		*mysql_link;
1563
1564	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
1565		return;
1566	}
1567	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
1568
1569	if (mysql_rollback(mysql->mysql)) {
1570		RETURN_FALSE;
1571	}
1572	RETURN_TRUE;
1573}
1574/* }}} */
1575
1576/* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)
1577*/
1578PHP_FUNCTION(mysqli_stmt_send_long_data)
1579{
1580	MY_STMT *stmt;
1581	zval  	*mysql_stmt;
1582	char	*data;
1583	long	param_nr;
1584	int		data_len;
1585
1586
1587	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, &param_nr, &data, &data_len) == FAILURE) {
1588		return;
1589	}
1590	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
1591
1592	if (param_nr < 0) {
1593		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number");
1594		RETURN_FALSE;
1595	}
1596	if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
1597		RETURN_FALSE;
1598	}
1599	RETURN_TRUE;
1600}
1601/* }}} */
1602
1603
1604/* {{{ proto mixed mysqli_stmt_affected_rows(object stmt)
1605   Return the number of rows affected in the last query for the given link */
1606PHP_FUNCTION(mysqli_stmt_affected_rows)
1607{
1608	MY_STMT 		*stmt;
1609	zval    		*mysql_stmt;
1610	my_ulonglong	rc;
1611
1612	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1613		return;
1614	}
1615	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
1616
1617	rc = mysql_stmt_affected_rows(stmt->stmt);
1618	if (rc == (my_ulonglong) -1) {
1619		RETURN_LONG(-1);
1620	}
1621	MYSQLI_RETURN_LONG_LONG(rc)
1622}
1623/* }}} */
1624
1625/* {{{ proto bool mysqli_stmt_close(object stmt) 
1626   Close statement */
1627PHP_FUNCTION(mysqli_stmt_close)
1628{
1629	MY_STMT 	*stmt;
1630	zval    	*mysql_stmt;
1631
1632	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
1633		return;
1634	}
1635	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
1636
1637	mysql_stmt_close(stmt->stmt);
1638	stmt->stmt = NULL;
1639	php_clear_stmt_bind(stmt); 
1640	MYSQLI_CLEAR_RESOURCE(&mysql_stmt);
1641	RETURN_TRUE;
1642}
1643/* }}} */
1644
1645/* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset)
1646   Move internal result pointer */
1647PHP_FUNCTION(mysqli_stmt_data_seek)
1648{
1649	MY_STMT 	*stmt;
1650	zval  		*mysql_stmt;
1651	long  		offset;
1652
1653	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
1654		return;
1655	}
1656	if (offset < 

Large files files are truncated, but you can click here to view the full file