mysqli.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Georg Richter <georg@php.net> |
  16. | Andrey Hristov <andrey@php.net> |
  17. | Ulf Wendel <uw@php.net> |
  18. +----------------------------------------------------------------------+
  19. $Id$
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include "config.h"
  23. #endif
  24. #include <signal.h>
  25. #include "php.h"
  26. #include "php_ini.h"
  27. #include "ext/standard/info.h"
  28. #include "ext/standard/php_string.h"
  29. #include "php_mysqli.h"
  30. #include "php_mysqli_structs.h"
  31. #include "mysqli_priv.h"
  32. #include "zend_exceptions.h"
  33. #include "zend_interfaces.h"
  34. ZEND_DECLARE_MODULE_GLOBALS(mysqli)
  35. static PHP_GINIT_FUNCTION(mysqli);
  36. #define MYSQLI_ADD_PROPERTIES(a,b) \
  37. { \
  38. int i = 0; \
  39. while (b[i].pname != NULL) { \
  40. mysqli_add_property((a), (b)[i].pname, (b)[i].pname_length, \
  41. (mysqli_read_t)(b)[i].r_func, (mysqli_write_t)(b)[i].w_func TSRMLS_CC); \
  42. i++; \
  43. }\
  44. }
  45. #define MYSQLI_ADD_PROPERTIES_INFO(a,b) \
  46. { \
  47. int i = 0; \
  48. while (b[i].name != NULL) { \
  49. zend_declare_property_null((a), (b)[i].name, (b)[i].name_length, ZEND_ACC_PUBLIC TSRMLS_CC); \
  50. i++; \
  51. }\
  52. }
  53. static zend_object_handlers mysqli_object_handlers;
  54. static HashTable classes;
  55. static HashTable mysqli_driver_properties;
  56. static HashTable mysqli_link_properties;
  57. static HashTable mysqli_result_properties;
  58. static HashTable mysqli_stmt_properties;
  59. static HashTable mysqli_warning_properties;
  60. zend_class_entry *mysqli_link_class_entry;
  61. zend_class_entry *mysqli_stmt_class_entry;
  62. zend_class_entry *mysqli_result_class_entry;
  63. zend_class_entry *mysqli_driver_class_entry;
  64. zend_class_entry *mysqli_warning_class_entry;
  65. zend_class_entry *mysqli_exception_class_entry;
  66. typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC);
  67. typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval TSRMLS_DC);
  68. typedef struct _mysqli_prop_handler {
  69. char *name;
  70. size_t name_len;
  71. mysqli_read_t read_func;
  72. mysqli_write_t write_func;
  73. } mysqli_prop_handler;
  74. static int le_pmysqli;
  75. /* Destructor for mysqli entries in free_links/used_links */
  76. void php_mysqli_dtor_p_elements(void *data)
  77. {
  78. MYSQL *mysql = (MYSQL *) data;
  79. TSRMLS_FETCH();
  80. mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
  81. }
  82. ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor)
  83. {
  84. if (rsrc->ptr) {
  85. mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr;
  86. zend_ptr_stack_clean(&plist->free_links, php_mysqli_dtor_p_elements, 0);
  87. zend_ptr_stack_destroy(&plist->free_links);
  88. free(plist);
  89. }
  90. }
  91. int php_le_pmysqli(void)
  92. {
  93. return le_pmysqli;
  94. }
  95. #ifndef MYSQLI_USE_MYSQLND
  96. /* {{{ php_free_stmt_bind_buffer */
  97. void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
  98. {
  99. unsigned int i;
  100. if (!bbuf.var_cnt) {
  101. return;
  102. }
  103. for (i=0; i < bbuf.var_cnt; i++) {
  104. /* free temporary bind buffer */
  105. if (type == FETCH_RESULT && bbuf.buf[i].val) {
  106. efree(bbuf.buf[i].val);
  107. }
  108. if (bbuf.vars[i]) {
  109. zval_ptr_dtor(&bbuf.vars[i]);
  110. }
  111. }
  112. if (bbuf.vars) {
  113. efree(bbuf.vars);
  114. }
  115. /*
  116. Don't free bbuf.is_null for FETCH_RESULT since we have allocated
  117. is_null and buf in one block so we free only buf, which is the beginning
  118. of the block. When FETCH_SIMPLE then buf wasn't allocated together with
  119. buf and we have to free it.
  120. */
  121. if (type == FETCH_RESULT) {
  122. efree(bbuf.buf);
  123. } else if (type == FETCH_SIMPLE){
  124. efree(bbuf.is_null);
  125. }
  126. bbuf.var_cnt = 0;
  127. }
  128. /* }}} */
  129. #endif
  130. /* {{{ php_clear_stmt_bind */
  131. void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC)
  132. {
  133. if (stmt->stmt) {
  134. if (mysqli_stmt_close(stmt->stmt, TRUE)) {
  135. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occurred while closing statement");
  136. return;
  137. }
  138. }
  139. /*
  140. mysqlnd keeps track of the binding and has freed its
  141. structures in stmt_close() above
  142. */
  143. #ifndef MYSQLI_USE_MYSQLND
  144. /* Clean param bind */
  145. php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
  146. /* Clean output bind */
  147. php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
  148. if (stmt->link_handle) {
  149. zend_objects_store_del_ref_by_handle(stmt->link_handle TSRMLS_CC);
  150. }
  151. #endif
  152. if (stmt->query) {
  153. efree(stmt->query);
  154. }
  155. efree(stmt);
  156. }
  157. /* }}} */
  158. /* {{{ php_clear_mysql */
  159. void php_clear_mysql(MY_MYSQL *mysql) {
  160. if (mysql->hash_key) {
  161. efree(mysql->hash_key);
  162. mysql->hash_key = NULL;
  163. }
  164. if (mysql->li_read) {
  165. zval_ptr_dtor(&(mysql->li_read));
  166. mysql->li_read = NULL;
  167. }
  168. }
  169. /* }}} */
  170. /* {{{ mysqli_objects_free_storage
  171. */
  172. static void mysqli_objects_free_storage(void *object TSRMLS_DC)
  173. {
  174. zend_object *zo = (zend_object *)object;
  175. mysqli_object *intern = (mysqli_object *)zo;
  176. MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
  177. my_efree(my_res);
  178. zend_object_std_dtor(&intern->zo TSRMLS_CC);
  179. efree(intern);
  180. }
  181. /* }}} */
  182. /* mysqli_link_free_storage partly doubles the work of PHP_FUNCTION(mysqli_close) */
  183. /* {{{ mysqli_link_free_storage
  184. */
  185. static void mysqli_link_free_storage(void *object TSRMLS_DC)
  186. {
  187. zend_object *zo = (zend_object *)object;
  188. mysqli_object *intern = (mysqli_object *)zo;
  189. MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
  190. if (my_res && my_res->ptr) {
  191. MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
  192. if (mysql->mysql) {
  193. php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status TSRMLS_CC);
  194. }
  195. php_clear_mysql(mysql);
  196. efree(mysql);
  197. my_res->status = MYSQLI_STATUS_UNKNOWN;
  198. }
  199. mysqli_objects_free_storage(object TSRMLS_CC);
  200. }
  201. /* }}} */
  202. /* {{{ mysql_driver_free_storage */
  203. static void mysqli_driver_free_storage(void *object TSRMLS_DC)
  204. {
  205. mysqli_objects_free_storage(object TSRMLS_CC);
  206. }
  207. /* }}} */
  208. /* {{{ mysqli_stmt_free_storage
  209. */
  210. static void mysqli_stmt_free_storage(void *object TSRMLS_DC)
  211. {
  212. zend_object *zo = (zend_object *)object;
  213. mysqli_object *intern = (mysqli_object *)zo;
  214. MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
  215. if (my_res && my_res->ptr) {
  216. MY_STMT *stmt = (MY_STMT *)my_res->ptr;
  217. php_clear_stmt_bind(stmt TSRMLS_CC);
  218. }
  219. mysqli_objects_free_storage(object TSRMLS_CC);
  220. }
  221. /* }}} */
  222. /* {{{ mysqli_result_free_storage
  223. */
  224. static void mysqli_result_free_storage(void *object TSRMLS_DC)
  225. {
  226. zend_object *zo = (zend_object *)object;
  227. mysqli_object *intern = (mysqli_object *)zo;
  228. MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
  229. if (my_res && my_res->ptr) {
  230. mysql_free_result(my_res->ptr);
  231. }
  232. mysqli_objects_free_storage(object TSRMLS_CC);
  233. }
  234. /* }}} */
  235. /* {{{ mysqli_warning_free_storage
  236. */
  237. static void mysqli_warning_free_storage(void *object TSRMLS_DC)
  238. {
  239. zend_object *zo = (zend_object *)object;
  240. mysqli_object *intern = (mysqli_object *)zo;
  241. MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
  242. if (my_res && my_res->ptr) {
  243. php_clear_warnings((MYSQLI_WARNING *)my_res->info);
  244. my_res->ptr = NULL;
  245. }
  246. mysqli_objects_free_storage(object TSRMLS_CC);
  247. }
  248. /* }}} */
  249. /* {{{ mysqli_read_na */
  250. static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC)
  251. {
  252. *retval = NULL;
  253. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property");
  254. return FAILURE;
  255. }
  256. /* }}} */
  257. /* {{{ mysqli_write_na */
  258. static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC)
  259. {
  260. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property");
  261. return FAILURE;
  262. }
  263. /* }}} */
  264. #ifndef Z_ADDREF_P
  265. /* PHP 5.2, old GC */
  266. #define Z_ADDREF_P(pz) (++(pz)->refcount)
  267. #define Z_REFCOUNT_P(pz) ((pz)->refcount)
  268. #define Z_SET_REFCOUNT_P(pz, rc) ((pz)->refcount = rc)
  269. #endif
  270. /* {{{ mysqli_read_property */
  271. zval *mysqli_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
  272. {
  273. zval tmp_member;
  274. zval *retval;
  275. mysqli_object *obj;
  276. mysqli_prop_handler *hnd;
  277. int ret;
  278. ret = FAILURE;
  279. obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
  280. if (member->type != IS_STRING) {
  281. tmp_member = *member;
  282. zval_copy_ctor(&tmp_member);
  283. convert_to_string(&tmp_member);
  284. member = &tmp_member;
  285. }
  286. if (obj->prop_handler != NULL) {
  287. ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
  288. }
  289. if (ret == SUCCESS) {
  290. ret = hnd->read_func(obj, &retval TSRMLS_CC);
  291. if (ret == SUCCESS) {
  292. /* ensure we're creating a temporary variable */
  293. Z_SET_REFCOUNT_P(retval, 0);
  294. } else {
  295. retval = EG(uninitialized_zval_ptr);
  296. }
  297. } else {
  298. zend_object_handlers * std_hnd = zend_get_std_object_handlers();
  299. retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
  300. }
  301. if (member == &tmp_member) {
  302. zval_dtor(member);
  303. }
  304. return(retval);
  305. }
  306. /* }}} */
  307. /* {{{ mysqli_write_property */
  308. void mysqli_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
  309. {
  310. zval tmp_member;
  311. mysqli_object *obj;
  312. mysqli_prop_handler *hnd;
  313. int ret;
  314. if (member->type != IS_STRING) {
  315. tmp_member = *member;
  316. zval_copy_ctor(&tmp_member);
  317. convert_to_string(&tmp_member);
  318. member = &tmp_member;
  319. }
  320. ret = FAILURE;
  321. obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
  322. if (obj->prop_handler != NULL) {
  323. ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
  324. }
  325. if (ret == SUCCESS) {
  326. hnd->write_func(obj, value TSRMLS_CC);
  327. if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) {
  328. Z_ADDREF_P(value);
  329. zval_ptr_dtor(&value);
  330. }
  331. } else {
  332. zend_object_handlers * std_hnd = zend_get_std_object_handlers();
  333. std_hnd->write_property(object, member, value, key TSRMLS_CC);
  334. }
  335. if (member == &tmp_member) {
  336. zval_dtor(member);
  337. }
  338. }
  339. /* }}} */
  340. /* {{{ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) */
  341. void mysqli_add_property(HashTable *h, const char *pname, size_t pname_len, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) {
  342. mysqli_prop_handler p;
  343. p.name = (char*) pname;
  344. p.name_len = pname_len;
  345. p.read_func = (r_func) ? r_func : mysqli_read_na;
  346. p.write_func = (w_func) ? w_func : mysqli_write_na;
  347. zend_hash_add(h, pname, pname_len + 1, &p, sizeof(mysqli_prop_handler), NULL);
  348. }
  349. /* }}} */
  350. static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */
  351. {
  352. mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
  353. mysqli_prop_handler p;
  354. int ret = 0;
  355. if (zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **)&p) == SUCCESS) {
  356. switch (has_set_exists) {
  357. case 2:
  358. ret = 1;
  359. break;
  360. case 1: {
  361. zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC);
  362. if (value != EG(uninitialized_zval_ptr)) {
  363. convert_to_boolean(value);
  364. ret = Z_BVAL_P(value)? 1:0;
  365. /* refcount is 0 */
  366. Z_ADDREF_P(value);
  367. zval_ptr_dtor(&value);
  368. }
  369. break;
  370. }
  371. case 0:{
  372. zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC);
  373. if (value != EG(uninitialized_zval_ptr)) {
  374. ret = Z_TYPE_P(value) != IS_NULL? 1:0;
  375. /* refcount is 0 */
  376. Z_ADDREF_P(value);
  377. zval_ptr_dtor(&value);
  378. }
  379. break;
  380. }
  381. default:
  382. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for has_set_exists");
  383. }
  384. } else {
  385. zend_object_handlers * std_hnd = zend_get_std_object_handlers();
  386. ret = std_hnd->has_property(object, member, has_set_exists, key TSRMLS_CC);
  387. }
  388. return ret;
  389. } /* }}} */
  390. #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
  391. HashTable * mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
  392. {
  393. mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
  394. HashTable *retval, *props = obj->prop_handler;
  395. HashPosition pos;
  396. mysqli_prop_handler *entry;
  397. ALLOC_HASHTABLE(retval);
  398. ZEND_INIT_SYMTABLE_EX(retval, zend_hash_num_elements(props) + 1, 0);
  399. zend_hash_internal_pointer_reset_ex(props, &pos);
  400. while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) {
  401. zval member;
  402. zval *value;
  403. INIT_ZVAL(member);
  404. ZVAL_STRINGL(&member, entry->name, entry->name_len, 0);
  405. value = mysqli_read_property(object, &member, BP_VAR_IS, 0 TSRMLS_CC);
  406. if (value != EG(uninitialized_zval_ptr)) {
  407. Z_ADDREF_P(value);
  408. zend_hash_add(retval, entry->name, entry->name_len + 1, &value, sizeof(zval *), NULL);
  409. }
  410. zend_hash_move_forward_ex(props, &pos);
  411. }
  412. *is_temp = 1;
  413. return retval;
  414. }
  415. #endif
  416. /* {{{ mysqli_objects_new
  417. */
  418. PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC)
  419. {
  420. zend_object_value retval;
  421. mysqli_object *intern;
  422. zend_class_entry *mysqli_base_class;
  423. zend_objects_free_object_storage_t free_storage;
  424. intern = emalloc(sizeof(mysqli_object));
  425. memset(intern, 0, sizeof(mysqli_object));
  426. intern->ptr = NULL;
  427. intern->prop_handler = NULL;
  428. mysqli_base_class = class_type;
  429. while (mysqli_base_class->type != ZEND_INTERNAL_CLASS &&
  430. mysqli_base_class->parent != NULL) {
  431. mysqli_base_class = mysqli_base_class->parent;
  432. }
  433. zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1,
  434. (void **) &intern->prop_handler);
  435. zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
  436. object_properties_init(&intern->zo, class_type);
  437. /* link object */
  438. if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) {
  439. free_storage = mysqli_link_free_storage;
  440. } else if (instanceof_function(class_type, mysqli_driver_class_entry TSRMLS_CC)) { /* driver object */
  441. free_storage = mysqli_driver_free_storage;
  442. } else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */
  443. free_storage = mysqli_stmt_free_storage;
  444. } else if (instanceof_function(class_type, mysqli_result_class_entry TSRMLS_CC)) { /* result object */
  445. free_storage = mysqli_result_free_storage;
  446. } else if (instanceof_function(class_type, mysqli_warning_class_entry TSRMLS_CC)) { /* warning object */
  447. free_storage = mysqli_warning_free_storage;
  448. } else {
  449. free_storage = mysqli_objects_free_storage;
  450. }
  451. retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, free_storage, NULL TSRMLS_CC);
  452. retval.handlers = &mysqli_object_handlers;
  453. return retval;
  454. }
  455. /* }}} */
  456. #ifdef MYSQLI_USE_MYSQLND
  457. #include "ext/mysqlnd/mysqlnd_reverse_api.h"
  458. static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
  459. {
  460. if (Z_TYPE_P(zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zv), mysqli_link_class_entry TSRMLS_CC)) {
  461. MY_MYSQL * mysql;
  462. MYSQLI_RESOURCE * my_res;
  463. mysqli_object * intern = (mysqli_object *)zend_object_store_get_object(zv TSRMLS_CC);
  464. if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
  465. /* We know that we have a mysqli object, so this failure should be emitted */
  466. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);
  467. return NULL;
  468. }
  469. mysql = (MY_MYSQL *)(my_res->ptr);
  470. return mysql ? mysql->mysql : NULL;
  471. }
  472. return NULL;
  473. }
  474. static MYSQLND_REVERSE_API mysqli_reverse_api = {
  475. &mysqli_module_entry,
  476. mysqli_convert_zv_to_mysqlnd
  477. };
  478. #endif
  479. /* {{{ PHP_INI_BEGIN
  480. */
  481. PHP_INI_BEGIN()
  482. STD_PHP_INI_ENTRY_EX("mysqli.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysqli_globals, mysqli_globals, display_link_numbers)
  483. STD_PHP_INI_ENTRY_EX("mysqli.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysqli_globals, mysqli_globals, display_link_numbers)
  484. STD_PHP_INI_BOOLEAN("mysqli.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysqli_globals, mysqli_globals)
  485. STD_PHP_INI_BOOLEAN("mysqli.rollback_on_cached_plink", "0",PHP_INI_SYSTEM, OnUpdateBool, rollback_on_cached_plink, zend_mysqli_globals, mysqli_globals)
  486. STD_PHP_INI_ENTRY("mysqli.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysqli_globals, mysqli_globals)
  487. STD_PHP_INI_ENTRY("mysqli.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysqli_globals, mysqli_globals)
  488. STD_PHP_INI_ENTRY("mysqli.default_pw", NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_mysqli_globals, mysqli_globals)
  489. STD_PHP_INI_ENTRY("mysqli.default_port", "3306", PHP_INI_ALL, OnUpdateLong, default_port, zend_mysqli_globals, mysqli_globals)
  490. #ifdef PHP_MYSQL_UNIX_SOCK_ADDR
  491. STD_PHP_INI_ENTRY("mysqli.default_socket", MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals)
  492. #else
  493. STD_PHP_INI_ENTRY("mysqli.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals)
  494. #endif
  495. STD_PHP_INI_BOOLEAN("mysqli.reconnect", "0", PHP_INI_SYSTEM, OnUpdateLong, reconnect, zend_mysqli_globals, mysqli_globals)
  496. STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals)
  497. PHP_INI_END()
  498. /* }}} */
  499. /* {{{ PHP_GINIT_FUNCTION
  500. */
  501. static PHP_GINIT_FUNCTION(mysqli)
  502. {
  503. mysqli_globals->num_links = 0;
  504. mysqli_globals->num_active_persistent = 0;
  505. mysqli_globals->num_inactive_persistent = 0;
  506. mysqli_globals->max_links = -1;
  507. mysqli_globals->max_persistent = -1;
  508. mysqli_globals->allow_persistent = 1;
  509. mysqli_globals->default_port = 0;
  510. mysqli_globals->default_host = NULL;
  511. mysqli_globals->default_user = NULL;
  512. mysqli_globals->default_pw = NULL;
  513. mysqli_globals->default_socket = NULL;
  514. mysqli_globals->reconnect = 0;
  515. mysqli_globals->report_mode = 0;
  516. mysqli_globals->report_ht = 0;
  517. mysqli_globals->allow_local_infile = 1;
  518. #ifdef HAVE_EMBEDDED_MYSQLI
  519. mysqli_globals->embedded = 1;
  520. #else
  521. mysqli_globals->embedded = 0;
  522. #endif
  523. mysqli_globals->rollback_on_cached_plink = FALSE;
  524. }
  525. /* }}} */
  526. /* {{{ PHP_MINIT_FUNCTION
  527. */
  528. PHP_MINIT_FUNCTION(mysqli)
  529. {
  530. zend_class_entry *ce,cex;
  531. zend_object_handlers *std_hnd = zend_get_std_object_handlers();
  532. REGISTER_INI_ENTRIES();
  533. #ifndef MYSQLI_USE_MYSQLND
  534. #if MYSQL_VERSION_ID >= 40000
  535. if (mysql_server_init(0, NULL, NULL)) {
  536. return FAILURE;
  537. }
  538. #endif
  539. #endif
  540. memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  541. mysqli_object_handlers.clone_obj = NULL;
  542. mysqli_object_handlers.read_property = mysqli_read_property;
  543. mysqli_object_handlers.write_property = mysqli_write_property;
  544. mysqli_object_handlers.get_property_ptr_ptr = std_hnd->get_property_ptr_ptr;
  545. mysqli_object_handlers.has_property = mysqli_object_has_property;
  546. #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
  547. mysqli_object_handlers.get_debug_info = mysqli_object_get_debug_info;
  548. #endif
  549. zend_hash_init(&classes, 0, NULL, NULL, 1);
  550. /* persistent connections */
  551. le_pmysqli = zend_register_list_destructors_ex(NULL, php_mysqli_dtor,
  552. "MySqli persistent connection", module_number);
  553. INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods);
  554. #ifdef HAVE_SPL
  555. mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
  556. #else
  557. mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
  558. #endif
  559. mysqli_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
  560. zend_declare_property_long(mysqli_exception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
  561. zend_declare_property_string(mysqli_exception_class_entry, "sqlstate", sizeof("sqlstate")-1, "00000", ZEND_ACC_PROTECTED TSRMLS_CC);
  562. REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods);
  563. ce = mysqli_driver_class_entry;
  564. zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1);
  565. MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries);
  566. MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_driver_property_info_entries);
  567. zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL);
  568. ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
  569. REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
  570. ce = mysqli_link_class_entry;
  571. zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1);
  572. MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries);
  573. MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_link_property_info_entries);
  574. zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL);
  575. REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods);
  576. ce = mysqli_warning_class_entry;
  577. ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED;
  578. zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1);
  579. MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries);
  580. MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_warning_property_info_entries);
  581. zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL);
  582. REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods);
  583. ce = mysqli_result_class_entry;
  584. zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1);
  585. MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries);
  586. MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries);
  587. mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator;
  588. mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs;
  589. zend_class_implements(mysqli_result_class_entry TSRMLS_CC, 1, zend_ce_traversable);
  590. zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL);
  591. REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods);
  592. ce = mysqli_stmt_class_entry;
  593. zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1);
  594. MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries);
  595. MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_stmt_property_info_entries);
  596. zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL);
  597. /* mysqli_options */
  598. REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT);
  599. REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT);
  600. REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT);
  601. REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT);
  602. REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT);
  603. #if defined(MYSQLI_USE_MYSQLND)
  604. REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
  605. REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
  606. #endif
  607. #ifdef MYSQLND_STRING_TO_INT_CONVERSION
  608. REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_CS | CONST_PERSISTENT);
  609. #endif
  610. #if MYSQL_VERSION_ID > 50110 || defined(MYSQLI_USE_MYSQLND)
  611. REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
  612. #endif
  613. #if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
  614. REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_CS | CONST_PERSISTENT);
  615. #endif
  616. /* mysqli_real_connect flags */
  617. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
  618. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
  619. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
  620. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
  621. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT);
  622. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT);
  623. #ifdef CLIENT_SSL_VERIFY_SERVER_CERT
  624. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT", CLIENT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
  625. #if defined(MYSQLI_USE_MYSQLND)
  626. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT", CLIENT_SSL_DONT_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
  627. #endif
  628. #endif
  629. #if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
  630. REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS", CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
  631. REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
  632. #endif
  633. /* for mysqli_query */
  634. REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT);
  635. REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT);
  636. #if defined (MYSQLI_USE_MYSQLND)
  637. REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT);
  638. REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT);
  639. #endif
  640. /* for mysqli_fetch_assoc */
  641. REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_CS | CONST_PERSISTENT);
  642. REGISTER_LONG_CONSTANT("MYSQLI_NUM", MYSQLI_NUM, CONST_CS | CONST_PERSISTENT);
  643. REGISTER_LONG_CONSTANT("MYSQLI_BOTH", MYSQLI_BOTH, CONST_CS | CONST_PERSISTENT);
  644. /* for mysqli_stmt_set_attr */
  645. REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH", STMT_ATTR_UPDATE_MAX_LENGTH, CONST_CS | CONST_PERSISTENT);
  646. #if MYSQL_VERSION_ID > 50003 || defined(MYSQLI_USE_MYSQLND)
  647. REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_CS | CONST_PERSISTENT);
  648. REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_CS | CONST_PERSISTENT);
  649. REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_CS | CONST_PERSISTENT);
  650. REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_CS | CONST_PERSISTENT);
  651. REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_CS | CONST_PERSISTENT);
  652. #endif
  653. #if MYSQL_VERSION_ID > 50007 || defined(MYSQLI_USE_MYSQLND)
  654. REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_CS | CONST_PERSISTENT);
  655. #endif
  656. /* column information */
  657. REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_CS | CONST_PERSISTENT);
  658. REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
  659. REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
  660. REGISTER_LONG_CONSTANT("MYSQLI_MULTIPLE_KEY_FLAG", MULTIPLE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
  661. REGISTER_LONG_CONSTANT("MYSQLI_BLOB_FLAG", BLOB_FLAG, CONST_CS | CONST_PERSISTENT);
  662. REGISTER_LONG_CONSTANT("MYSQLI_UNSIGNED_FLAG", UNSIGNED_FLAG, CONST_CS | CONST_PERSISTENT);
  663. REGISTER_LONG_CONSTANT("MYSQLI_ZEROFILL_FLAG", ZEROFILL_FLAG, CONST_CS | CONST_PERSISTENT);
  664. REGISTER_LONG_CONSTANT("MYSQLI_AUTO_INCREMENT_FLAG", AUTO_INCREMENT_FLAG, CONST_CS | CONST_PERSISTENT);
  665. REGISTER_LONG_CONSTANT("MYSQLI_TIMESTAMP_FLAG", TIMESTAMP_FLAG, CONST_CS | CONST_PERSISTENT);
  666. REGISTER_LONG_CONSTANT("MYSQLI_SET_FLAG", SET_FLAG, CONST_CS | CONST_PERSISTENT);
  667. REGISTER_LONG_CONSTANT("MYSQLI_NUM_FLAG", NUM_FLAG, CONST_CS | CONST_PERSISTENT);
  668. REGISTER_LONG_CONSTANT("MYSQLI_PART_KEY_FLAG", PART_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
  669. REGISTER_LONG_CONSTANT("MYSQLI_GROUP_FLAG", GROUP_FLAG, CONST_CS | CONST_PERSISTENT);
  670. REGISTER_LONG_CONSTANT("MYSQLI_ENUM_FLAG", ENUM_FLAG, CONST_CS | CONST_PERSISTENT);
  671. REGISTER_LONG_CONSTANT("MYSQLI_BINARY_FLAG", BINARY_FLAG, CONST_CS | CONST_PERSISTENT);
  672. #if MYSQL_VERSION_ID > 50001 || defined(MYSQLI_USE_MYSQLND)
  673. REGISTER_LONG_CONSTANT("MYSQLI_NO_DEFAULT_VALUE_FLAG", NO_DEFAULT_VALUE_FLAG, CONST_CS | CONST_PERSISTENT);
  674. #endif
  675. #if (MYSQL_VERSION_ID > 51122 && MYSQL_VERSION_ID < 60000) || (MYSQL_VERSION_ID > 60003) || defined(MYSQLI_USE_MYSQLND)
  676. REGISTER_LONG_CONSTANT("MYSQLI_ON_UPDATE_NOW_FLAG", ON_UPDATE_NOW_FLAG, CONST_CS | CONST_PERSISTENT);
  677. #endif
  678. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DECIMAL", FIELD_TYPE_DECIMAL, CONST_CS | CONST_PERSISTENT);
  679. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY", FIELD_TYPE_TINY, CONST_CS | CONST_PERSISTENT);
  680. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SHORT", FIELD_TYPE_SHORT, CONST_CS | CONST_PERSISTENT);
  681. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG", FIELD_TYPE_LONG, CONST_CS | CONST_PERSISTENT);
  682. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_FLOAT", FIELD_TYPE_FLOAT, CONST_CS | CONST_PERSISTENT);
  683. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DOUBLE", FIELD_TYPE_DOUBLE, CONST_CS | CONST_PERSISTENT);
  684. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NULL", FIELD_TYPE_NULL, CONST_CS | CONST_PERSISTENT);
  685. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIMESTAMP", FIELD_TYPE_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
  686. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONGLONG", FIELD_TYPE_LONGLONG, CONST_CS | CONST_PERSISTENT);
  687. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INT24", FIELD_TYPE_INT24, CONST_CS | CONST_PERSISTENT);
  688. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATE", FIELD_TYPE_DATE, CONST_CS | CONST_PERSISTENT);
  689. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIME", FIELD_TYPE_TIME, CONST_CS | CONST_PERSISTENT);
  690. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATETIME", FIELD_TYPE_DATETIME , CONST_CS | CONST_PERSISTENT);
  691. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_YEAR", FIELD_TYPE_YEAR, CONST_CS | CONST_PERSISTENT);
  692. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDATE", FIELD_TYPE_NEWDATE, CONST_CS | CONST_PERSISTENT);
  693. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_ENUM", FIELD_TYPE_ENUM, CONST_CS | CONST_PERSISTENT);
  694. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SET", FIELD_TYPE_SET, CONST_CS | CONST_PERSISTENT);
  695. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY_BLOB", FIELD_TYPE_TINY_BLOB, CONST_CS | CONST_PERSISTENT);
  696. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_MEDIUM_BLOB", FIELD_TYPE_MEDIUM_BLOB, CONST_CS | CONST_PERSISTENT);
  697. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG_BLOB", FIELD_TYPE_LONG_BLOB, CONST_CS | CONST_PERSISTENT);
  698. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BLOB", FIELD_TYPE_BLOB, CONST_CS | CONST_PERSISTENT);
  699. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_CS | CONST_PERSISTENT);
  700. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_CS | CONST_PERSISTENT);
  701. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_CS | CONST_PERSISTENT);
  702. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_CS | CONST_PERSISTENT);
  703. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_CS | CONST_PERSISTENT);
  704. #ifdef FIELD_TYPE_JSON
  705. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_JSON", FIELD_TYPE_JSON, CONST_CS | CONST_PERSISTENT);
  706. #endif
  707. #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
  708. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_CS | CONST_PERSISTENT);
  709. REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_CS | CONST_PERSISTENT);
  710. #endif
  711. REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_CS | CONST_PERSISTENT);
  712. REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_DIR", MYSQL_SET_CHARSET_DIR, CONST_CS | CONST_PERSISTENT);
  713. /* bind support */
  714. REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT);
  715. #ifdef MYSQL_DATA_TRUNCATED
  716. REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_CS | CONST_PERSISTENT);
  717. #endif
  718. /* reporting */
  719. REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_CS | CONST_PERSISTENT);
  720. REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_CS | CONST_PERSISTENT);
  721. REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_CS | CONST_PERSISTENT);
  722. REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_CS | CONST_PERSISTENT);
  723. REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);
  724. /* We use non-nested macros with expansion, as VC has problems */
  725. #ifdef MYSQLI_USE_MYSQLND
  726. REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT);
  727. #else
  728. #ifdef DBUG_ON
  729. REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT);
  730. #else
  731. REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT);
  732. #endif
  733. #endif
  734. REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT);
  735. REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT);
  736. #ifdef SERVER_QUERY_WAS_SLOW
  737. REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_CS | CONST_PERSISTENT);
  738. #endif
  739. #ifdef SERVER_PS_OUT_PARAMS
  740. REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_CS | CONST_PERSISTENT);
  741. #endif
  742. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_CS | CONST_PERSISTENT);
  743. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_CS | CONST_PERSISTENT);
  744. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_CS | CONST_PERSISTENT);
  745. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS", REFRESH_HOSTS, CONST_CS | CONST_PERSISTENT);
  746. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS", REFRESH_STATUS, CONST_CS | CONST_PERSISTENT);
  747. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS", REFRESH_THREADS, CONST_CS | CONST_PERSISTENT);
  748. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_CS | CONST_PERSISTENT);
  749. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_CS | CONST_PERSISTENT);
  750. #ifdef REFRESH_BACKUP_LOG
  751. REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT);
  752. #endif
  753. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_CS | CONST_PERSISTENT);
  754. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_CS | CONST_PERSISTENT);
  755. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_CS | CONST_PERSISTENT);
  756. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_CHAIN", TRANS_COR_AND_CHAIN, CONST_CS | CONST_PERSISTENT);
  757. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_NO_CHAIN", TRANS_COR_AND_NO_CHAIN, CONST_CS | CONST_PERSISTENT);
  758. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_RELEASE", TRANS_COR_RELEASE, CONST_CS | CONST_PERSISTENT);
  759. REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_NO_RELEASE", TRANS_COR_NO_RELEASE, CONST_CS | CONST_PERSISTENT);
  760. #ifdef MYSQLI_USE_MYSQLND
  761. mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC);
  762. #endif
  763. return SUCCESS;
  764. }
  765. /* }}} */
  766. /* {{{ PHP_MSHUTDOWN_FUNCTION
  767. */
  768. PHP_MSHUTDOWN_FUNCTION(mysqli)
  769. {
  770. #ifndef MYSQLI_USE_MYSQLND
  771. #if MYSQL_VERSION_ID >= 40000
  772. #ifdef PHP_WIN32
  773. unsigned long client_ver = mysql_get_client_version();
  774. /*
  775. Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
  776. PHP bug#41350 MySQL bug#25621
  777. */
  778. if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
  779. mysql_server_end();
  780. }
  781. #else
  782. mysql_server_end();
  783. #endif
  784. #endif
  785. #endif
  786. zend_hash_destroy(&mysqli_driver_properties);
  787. zend_hash_destroy(&mysqli_result_properties);
  788. zend_hash_destroy(&mysqli_stmt_properties);
  789. zend_hash_destroy(&mysqli_warning_properties);
  790. zend_hash_destroy(&mysqli_link_properties);
  791. zend_hash_destroy(&classes);
  792. UNREGISTER_INI_ENTRIES();
  793. return SUCCESS;
  794. }
  795. /* }}} */
  796. /* {{{ PHP_RINIT_FUNCTION
  797. */
  798. PHP_RINIT_FUNCTION(mysqli)
  799. {
  800. #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
  801. if (mysql_thread_init()) {
  802. return FAILURE;
  803. }
  804. #endif
  805. MyG(error_msg) = NULL;
  806. MyG(error_no) = 0;
  807. MyG(report_mode) = 0;
  808. return SUCCESS;
  809. }
  810. /* }}} */
  811. #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
  812. static void php_mysqli_persistent_helper_for_every(void *p)
  813. {
  814. TSRMLS_FETCH();
  815. mysqlnd_end_psession((MYSQLND *) p);
  816. } /* }}} */
  817. static int php_mysqli_persistent_helper_once(zend_rsrc_list_entry *le TSRMLS_DC)
  818. {
  819. if (le->type == php_le_pmysqli()) {
  820. mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
  821. zend_ptr_stack_apply(&plist->free_links, php_mysqli_persistent_helper_for_every);
  822. }
  823. return ZEND_HASH_APPLY_KEEP;
  824. } /* }}} */
  825. #endif
  826. /* {{{ PHP_RSHUTDOWN_FUNCTION
  827. */
  828. PHP_RSHUTDOWN_FUNCTION(mysqli)
  829. {
  830. /* check persistent connections, move used to free */
  831. #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
  832. mysql_thread_end();
  833. #endif
  834. if (MyG(error_msg)) {
  835. efree(MyG(error_msg));
  836. }
  837. #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
  838. /* psession is being called when the connection is freed - explicitly or implicitly */
  839. zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_helper_once TSRMLS_CC);
  840. #endif
  841. return SUCCESS;
  842. }
  843. /* }}} */
  844. /* {{{ PHP_MINFO_FUNCTION
  845. */
  846. PHP_MINFO_FUNCTION(mysqli)
  847. {
  848. char buf[32];
  849. php_info_print_table_start();
  850. php_info_print_table_header(2, "MysqlI Support", "enabled");
  851. php_info_print_table_row(2, "Client API library version", mysql_get_client_info());
  852. snprintf(buf, sizeof(buf), "%ld", MyG(num_active_persistent));
  853. php_info_print_table_row(2, "Active Persistent Links", buf);
  854. snprintf(buf, sizeof(buf), "%ld", MyG(num_inactive_persistent));
  855. php_info_print_table_row(2, "Inactive Persistent Links", buf);
  856. snprintf(buf, sizeof(buf), "%ld", MyG(num_links));
  857. php_info_print_table_row(2, "Active Links", buf);
  858. #if !defined(MYSQLI_USE_MYSQLND)
  859. php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION);
  860. php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR);
  861. #endif
  862. php_info_print_table_end();
  863. DISPLAY_INI_ENTRIES();
  864. }
  865. /* }}} */
  866. /* Dependancies */
  867. static const zend_module_dep mysqli_deps[] = {
  868. #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
  869. ZEND_MOD_REQUIRED("spl")
  870. #endif
  871. #if defined(MYSQLI_USE_MYSQLND)
  872. ZEND_MOD_REQUIRED("mysqlnd")
  873. #endif
  874. ZEND_MOD_END
  875. };
  876. /* {{{ mysqli_module_entry
  877. */
  878. zend_module_entry mysqli_module_entry = {
  879. #if ZEND_MODULE_API_NO >= 20050922
  880. STANDARD_MODULE_HEADER_EX, NULL,
  881. mysqli_deps,
  882. #elif ZEND_MODULE_API_NO >= 20010901
  883. STANDARD_MODULE_HEADER,
  884. #endif
  885. "mysqli",
  886. mysqli_functions,
  887. PHP_MINIT(mysqli),
  888. PHP_MSHUTDOWN(mysqli),
  889. PHP_RINIT(mysqli),
  890. PHP_RSHUTDOWN(mysqli),
  891. PHP_MINFO(mysqli),
  892. "0.1", /* Replace with version number for your extension */
  893. PHP_MODULE_GLOBALS(mysqli),
  894. PHP_GINIT(mysqli),
  895. NULL,
  896. NULL,
  897. STANDARD_MODULE_PROPERTIES_EX
  898. };
  899. /* }}} */
  900. #ifdef COMPILE_DL_MYSQLI
  901. ZEND_GET_MODULE(mysqli)
  902. #endif
  903. /* {{{ mixed mysqli_stmt_construct()
  904. constructor for statement object.
  905. Parameters:
  906. object -> mysqli_stmt_init
  907. object, query -> mysqli_prepare
  908. */
  909. PHP_FUNCTION(mysqli_stmt_construct)
  910. {
  911. MY_MYSQL *mysql;
  912. zval *mysql_link;
  913. MY_STMT *stmt;
  914. MYSQLI_RESOURCE *mysqli_resource;
  915. char *statement;
  916. int statement_len;
  917. switch (ZEND_NUM_ARGS())
  918. {
  919. case 1: /* mysql_stmt_init */
  920. if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
  921. return;
  922. }
  923. MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
  924. stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
  925. stmt->stmt = mysql_stmt_init(mysql->mysql);
  926. break;
  927. case 2:
  928. if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) {
  929. return;
  930. }
  931. MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
  932. stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
  933. if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
  934. mysql_stmt_prepare(stmt->stmt, (char *)statement, statement_len);
  935. }
  936. break;
  937. default:
  938. WRONG_PARAM_COUNT;
  939. break;
  940. }
  941. if (!stmt->stmt) {
  942. efree(stmt);
  943. RETURN_FALSE;
  944. }
  945. #ifndef MYSQLI_USE_MYSQLND
  946. stmt->link_handle = Z_OBJ_HANDLE(*mysql_link);
  947. zend_objects_store_add_ref_by_handle(stmt->link_handle TSRMLS_CC);
  948. #endif
  949. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  950. mysqli_resource->ptr = (void *)stmt;
  951. mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID;
  952. ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
  953. }
  954. /* }}} */
  955. /* {{{ mixed mysqli_result_construct()
  956. constructor for result object.
  957. Parameters:
  958. object [, mode] -> mysqli_store/use_result
  959. */
  960. PHP_FUNCTION(mysqli_result_construct)
  961. {
  962. MY_MYSQL *mysql;
  963. MYSQL_RES *result = NULL;
  964. zval *mysql_link;
  965. MYSQLI_RESOURCE *mysqli_resource;
  966. long resmode = MYSQLI_STORE_RESULT;
  967. switch (ZEND_NUM_ARGS()) {
  968. case 1:
  969. if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
  970. return;
  971. }
  972. break;
  973. case 2:
  974. if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) {
  975. return;
  976. }
  977. break;
  978. default:
  979. WRONG_PARAM_COUNT;
  980. }
  981. MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
  982. switch (resmode) {
  983. case MYSQLI_STORE_RESULT:
  984. result = mysql_store_result(mysql->mysql);
  985. break;
  986. case MYSQLI_USE_RESULT:
  987. result = mysql_use_result(mysql->mysql);
  988. break;
  989. default:
  990. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
  991. }
  992. if (!result) {
  993. RETURN_FALSE;
  994. }
  995. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  996. mysqli_resource->ptr = (void *)result;
  997. mysqli_resource->status = MYSQLI_STATUS_VALID;
  998. ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
  999. }
  1000. /* }}} */
  1001. /* {{{ php_mysqli_fetch_into_hash_aux
  1002. */
  1003. void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC)
  1004. {
  1005. #if !defined(MYSQLI_USE_MYSQLND)
  1006. MYSQL_ROW row;
  1007. unsigned int i;
  1008. MYSQL_FIELD *fields;
  1009. unsigned long *field_len;
  1010. if (!(row = mysql_fetch_row(result))) {
  1011. RETURN_NULL();
  1012. }
  1013. if (fetchtype & MYSQLI_ASSOC) {
  1014. fields = mysql_fetch_fields(result);
  1015. }
  1016. array_init(return_value);
  1017. field_len = mysql_fetch_lengths(result);
  1018. for (i = 0; i < mysql_num_fields(result); i++) {
  1019. if (row[i]) {
  1020. zval *res;
  1021. MAKE_STD_ZVAL(res);
  1022. #if MYSQL_VERSION_ID > 50002
  1023. if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) {
  1024. my_ulonglong llval;
  1025. char tmp[22];
  1026. switch (field_len[i]) {
  1027. case 8:llval = (my_ulonglong) bit_uint8korr(row[i]);break;
  1028. case 7:llval = (my_ulonglong) bit_uint7korr(row[i]);break;
  1029. case 6:llval = (my_ulonglong) bit_uint6korr(row[i]);break;
  1030. case 5:llval = (my_ulonglong) bit_uint5korr(row[i]);break;
  1031. case 4:llval = (my_ulonglong) bit_uint4korr(row[i]);break;
  1032. case 3:llval = (my_ulonglong) bit_uint3korr(row[i]);break;
  1033. case 2:llval = (my_ulonglong) bit_uint2korr(row[i]);break;
  1034. case 1:llval = (my_ulonglong) uint1korr(row[i]);break;
  1035. }
  1036. /* even though lval is declared as unsigned, the value
  1037. * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
  1038. * use MYSQLI_LL_SPEC.
  1039. */
  1040. snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
  1041. ZVAL_STRING(res, tmp, 1);
  1042. } else
  1043. #endif
  1044. {
  1045. #if PHP_API_VERSION < 20100412
  1046. /* check if we need magic quotes */
  1047. if (PG(magic_quotes_runtime)) {
  1048. Z_TYPE_P(res) = IS_STRING;
  1049. Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC);
  1050. } else {
  1051. #endif
  1052. ZVAL_STRINGL(res, row[i], field_len[i], 1);
  1053. #if PHP_API_VERSION < 20100412
  1054. }
  1055. #endif
  1056. }
  1057. if (fetchtype & MYSQLI_NUM) {
  1058. add_index_zval(return_value, i, res);
  1059. }
  1060. if (fetchtype & MYSQLI_ASSOC) {
  1061. if (fetchtype & MYSQLI_NUM) {
  1062. Z_ADDREF_P(res);
  1063. }
  1064. add_assoc_zval(return_value, fields[i].name, res);
  1065. }
  1066. } else {
  1067. if (fetchtype & MYSQLI_NUM) {
  1068. add_index_null(return_value, i);
  1069. }
  1070. if (fetchtype & MYSQLI_ASSOC) {
  1071. add_assoc_null(return_value, fields[i].name);
  1072. }
  1073. }
  1074. }
  1075. #else
  1076. mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI);
  1077. #endif
  1078. }
  1079. /* }}} */
  1080. /* {{{ php_mysqli_fetch_into_hash
  1081. */
  1082. void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object)
  1083. {
  1084. MYSQL_RES *result;
  1085. zval *mysql_result;
  1086. long fetchtype;
  1087. zval *ctor_params = NULL;
  1088. zend_class_entry *ce = NULL;
  1089. if (into_object) {
  1090. char *class_name;
  1091. int class_name_len;
  1092. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) {
  1093. return;
  1094. }
  1095. if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) {
  1096. ce = zend_standard_class_def;
  1097. } else {
  1098. ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
  1099. }
  1100. if (!ce) {
  1101. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
  1102. return;
  1103. }
  1104. fetchtype = MYSQLI_ASSOC;
  1105. } else {
  1106. if (override_flags) {
  1107. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
  1108. return;
  1109. }
  1110. fetchtype = override_flags;
  1111. } else {
  1112. fetchtype = MYSQLI_BOTH;
  1113. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) {
  1114. return;
  1115. }
  1116. }
  1117. }
  1118. MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
  1119. if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
  1120. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH");
  1121. RETURN_FALSE;
  1122. }
  1123. php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype TSRMLS_CC);
  1124. if (into_object && Z_TYPE_P(return_value) == IS_ARRAY) {
  1125. zval dataset = *return_value;
  1126. zend_fcall_info fci;
  1127. zend_fcall_info_cache fcc;
  1128. zval *retval_ptr;
  1129. object_and_properties_init(return_value, ce, NULL);
  1130. zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
  1131. if (ce->constructor) {
  1132. fci.size = sizeof(fci);
  1133. fci.function_table = &ce->function_table;
  1134. fci.function_name = NULL;
  1135. fci.symbol_table = NULL;
  1136. fci.object_ptr = return_value;
  1137. fci.retval_ptr_ptr = &retval_ptr;
  1138. fci.params = NULL;
  1139. fci.param_count = 0;
  1140. fci.no_separation = 1;
  1141. if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
  1142. if (zend_fcall_info_args(&fci, ctor_params TSRMLS_CC) == FAILURE) {
  1143. /* Two problems why we throw exceptions here: PHP is typeless
  1144. * and hence passing one argument that's not an array could be
  1145. * by mistake and the other way round is possible, too. The
  1146. * single value is an array. Also we'd have to make that one
  1147. * argument passed by reference.
  1148. */
  1149. zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
  1150. return;
  1151. }
  1152. }
  1153. fcc.initialized = 1;
  1154. fcc.function_handler = ce->constructor;
  1155. fcc.calling_scope = EG(scope);
  1156. fcc.called_scope = Z_OBJCE_P(return_value);
  1157. fcc.object_ptr = return_value;
  1158. if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
  1159. zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
  1160. } else {
  1161. if (retval_ptr) {
  1162. zval_ptr_dtor(&retval_ptr);
  1163. }
  1164. }
  1165. if (fci.params) {
  1166. efree(fci.params);
  1167. }
  1168. } else if (ctor_params) {
  1169. zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
  1170. }
  1171. }
  1172. }
  1173. /* }}} */
  1174. /*
  1175. * Local variables:
  1176. * tab-width: 4
  1177. * c-basic-offset: 4
  1178. * End:
  1179. * vim600: noet sw=4 ts=4 fdm=marker
  1180. * vim<600: noet sw=4 ts=4
  1181. */