PageRenderTime 51ms CodeModel.GetById 19ms 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
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

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

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