mysqli_result_iterator.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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: mysqli.c 299335 2010-05-13 11:05:09Z andrey $
  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 "php_mysqli_structs.h"
  28. #include "mysqli_priv.h"
  29. #include "zend_interfaces.h"
  30. extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs;
  31. typedef struct {
  32. zend_object_iterator intern;
  33. mysqli_object *result;
  34. zval *current_row;
  35. my_longlong row_num;
  36. } php_mysqli_result_iterator;
  37. /* {{{ */
  38. zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
  39. {
  40. php_mysqli_result_iterator *iterator;
  41. if (by_ref) {
  42. zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
  43. }
  44. iterator = ecalloc(1, sizeof(php_mysqli_result_iterator));
  45. Z_ADDREF_P(object);
  46. iterator->intern.data = (void*)object;
  47. iterator->intern.funcs = &php_mysqli_result_iterator_funcs;
  48. iterator->result = (mysqli_object *) zend_object_store_get_object(object TSRMLS_CC);
  49. iterator->row_num = -1;
  50. return (zend_object_iterator*)iterator;
  51. }
  52. /* }}} */
  53. /* {{{ */
  54. static void php_mysqli_result_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
  55. {
  56. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  57. /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */
  58. if (iterator->intern.data) {
  59. zval_ptr_dtor((zval**)&iterator->intern.data);
  60. }
  61. if (iterator->current_row) {
  62. zval_ptr_dtor(&iterator->current_row);
  63. }
  64. efree(iterator);
  65. }
  66. /* }}} */
  67. /* {{{ */
  68. static int php_mysqli_result_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
  69. {
  70. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  71. return iterator->current_row && Z_TYPE_P(iterator->current_row) == IS_ARRAY ? SUCCESS : FAILURE;
  72. }
  73. /* }}} */
  74. /* {{{ */
  75. static void php_mysqli_result_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
  76. {
  77. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  78. *data = &iterator->current_row;
  79. }
  80. /* }}} */
  81. /* {{{ */
  82. static void php_mysqli_result_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
  83. {
  84. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  85. mysqli_object *intern = iterator->result;
  86. MYSQL_RES *result;
  87. MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID);
  88. if (iterator->current_row) {
  89. zval_ptr_dtor(&iterator->current_row);
  90. }
  91. MAKE_STD_ZVAL(iterator->current_row);
  92. php_mysqli_fetch_into_hash_aux(iterator->current_row, result, MYSQLI_ASSOC TSRMLS_CC);
  93. if (Z_TYPE_P(iterator->current_row) == IS_ARRAY) {
  94. iterator->row_num++;
  95. }
  96. }
  97. /* }}} */
  98. /* {{{ */
  99. static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
  100. {
  101. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  102. mysqli_object *intern = iterator->result;
  103. MYSQL_RES *result;
  104. MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID);
  105. if (mysqli_result_is_unbuffered(result)) {
  106. #if MYSQLI_USE_MYSQLND
  107. if (result->unbuf->eof_reached) {
  108. #else
  109. if (result->eof) {
  110. #endif
  111. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data fetched with MYSQLI_USE_RESULT can be iterated only once");
  112. return;
  113. }
  114. } else {
  115. mysql_data_seek(result, 0);
  116. }
  117. iterator->row_num = -1;
  118. php_mysqli_result_iterator_move_forward(iter TSRMLS_CC);
  119. }
  120. /* }}} */
  121. /* {{{ php_mysqli_result_iterator_current_key */
  122. static void php_mysqli_result_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
  123. {
  124. php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
  125. ZVAL_LONG(key, iterator->row_num);
  126. }
  127. /* }}} */
  128. /* {{{ php_mysqli_result_iterator_funcs */
  129. zend_object_iterator_funcs php_mysqli_result_iterator_funcs = {
  130. php_mysqli_result_iterator_dtor,
  131. php_mysqli_result_iterator_valid,
  132. php_mysqli_result_iterator_current_data,
  133. php_mysqli_result_iterator_current_key,
  134. php_mysqli_result_iterator_move_forward,
  135. php_mysqli_result_iterator_rewind,
  136. };
  137. /* }}} */
  138. /*
  139. * Local variables:
  140. * tab-width: 4
  141. * c-basic-offset: 4
  142. * End:
  143. * vim600: noet sw=4 ts=4 fdm=marker
  144. * vim<600: noet sw=4 ts=4
  145. */