andrey Tue, 18 May 2010 10:39:26 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=299444
Log: Add iterator to mysqli_result. Works both for : - USE_RESULT, can be iterated only once, kind of forward iterator - STORE_RESULT, can be iterated multiple times Changed paths: U php/php-src/trunk/ext/mysqli/config.m4 U php/php-src/trunk/ext/mysqli/config.w32 U php/php-src/trunk/ext/mysqli/mysqli.c U php/php-src/trunk/ext/mysqli/mysqli_libmysql.h A php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c U php/php-src/trunk/ext/mysqli/php_mysqli_structs.h A php/php-src/trunk/ext/mysqli/tests/mysqli_query_iterators.phpt
Modified: php/php-src/trunk/ext/mysqli/config.m4 =================================================================== --- php/php-src/trunk/ext/mysqli/config.m4 2010-05-18 09:09:18 UTC (rev 299443) +++ php/php-src/trunk/ext/mysqli/config.m4 2010-05-18 10:39:26 UTC (rev 299444) @@ -77,7 +77,7 @@ if test "$PHP_MYSQLI" != "no"; then mysqli_sources="mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c \ mysqli_fe.c mysqli_report.c mysqli_driver.c mysqli_warning.c \ - mysqli_exception.c $mysqli_extra_sources" + mysqli_exception.c mysqli_result_iterator.c $mysqli_extra_sources" PHP_NEW_EXTENSION(mysqli, $mysqli_sources, $ext_shared) PHP_SUBST(MYSQLI_SHARED_LIBADD) Modified: php/php-src/trunk/ext/mysqli/config.w32 =================================================================== --- php/php-src/trunk/ext/mysqli/config.w32 2010-05-18 09:09:18 UTC (rev 299443) +++ php/php-src/trunk/ext/mysqli/config.w32 2010-05-18 10:39:26 UTC (rev 299444) @@ -18,6 +18,7 @@ "mysqli_fe.c " + "mysqli_nonapi.c " + "mysqli_prop.c " + + "mysqli_result_iterator.c " + "mysqli_report.c " + "mysqli_warning.c"; Modified: php/php-src/trunk/ext/mysqli/mysqli.c =================================================================== --- php/php-src/trunk/ext/mysqli/mysqli.c 2010-05-18 09:09:18 UTC (rev 299443) +++ php/php-src/trunk/ext/mysqli/mysqli.c 2010-05-18 10:39:26 UTC (rev 299444) @@ -32,6 +32,7 @@ #include "ext/standard/php_string.h" #include "php_mysqli_structs.h" #include "zend_exceptions.h" +#include "zend_interfaces.h" ZEND_DECLARE_MODULE_GLOBALS(mysqli) static PHP_GINIT_FUNCTION(mysqli); @@ -685,6 +686,9 @@ zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1); MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries); MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries); + mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator; + mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs; + zend_class_implements(mysqli_result_class_entry TSRMLS_CC, 1, zend_ce_traversable); zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL); REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods); @@ -1072,59 +1076,16 @@ } /* }}} */ -/* {{{ php_mysqli_fetch_into_hash + +/* {{{ php_mysqli_fetch_into_hash_aux */ -void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) +void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC) { - MYSQL_RES *result; - zval *mysql_result; - long fetchtype; - zval *ctor_params = NULL; - zend_class_entry *ce = NULL; -#if !defined(MYSQLI_USE_MYSQLND) + MYSQL_ROW row; unsigned int i; MYSQL_FIELD *fields; - MYSQL_ROW row; unsigned long *field_len; -#endif - if (into_object) { - char *class_name; - int class_name_len; - - 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) { - return; - } - if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { - ce = zend_standard_class_def; - } else { - ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); - } - if (!ce) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); - return; - } - fetchtype = MYSQLI_ASSOC; - } else { - if (override_flags) { - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { - return; - } - fetchtype = override_flags; - } else { - fetchtype = MYSQLI_BOTH; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { - return; - } - } - } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); - - if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH"); - RETURN_FALSE; - } - #if !defined(MYSQLI_USE_MYSQLND) if (!(row = mysql_fetch_row(result))) { RETURN_NULL(); @@ -1195,9 +1156,61 @@ } } #else - mysqlnd_fetch_into(result, MYSQLND_FETCH_ASSOC, return_value, MYSQLND_MYSQLI); + mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI); #endif +} +/* }}} */ + +/* {{{ php_mysqli_fetch_into_hash + */ +void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) +{ + MYSQL_RES *result; + zval *mysql_result; + long fetchtype; + zval *ctor_params = NULL; + zend_class_entry *ce = NULL; + + if (into_object) { + char *class_name; + int class_name_len; + + 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) { + return; + } + if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { + ce = zend_standard_class_def; + } else { + ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + } + if (!ce) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + return; + } + fetchtype = MYSQLI_ASSOC; + } else { + if (override_flags) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + fetchtype = override_flags; + } else { + fetchtype = MYSQLI_BOTH; + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { + return; + } + } + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH"); + RETURN_FALSE; + } + + php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype TSRMLS_CC); + if (into_object && Z_TYPE_P(return_value) != IS_NULL) { zval dataset = *return_value; zend_fcall_info fci; Modified: php/php-src/trunk/ext/mysqli/mysqli_libmysql.h =================================================================== --- php/php-src/trunk/ext/mysqli/mysqli_libmysql.h 2010-05-18 09:09:18 UTC (rev 299443) +++ php/php-src/trunk/ext/mysqli/mysqli_libmysql.h 2010-05-18 10:39:26 UTC (rev 299444) @@ -1,9 +1,9 @@ /* - ---------------------------------------------------------------------- - | PHP Version 6 | - ---------------------------------------------------------------------- - | Copyright (c) 2007 The PHP Group | - ---------------------------------------------------------------------- + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2010 The PHP Group | + +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | @@ -11,12 +11,11 @@ | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | - ---------------------------------------------------------------------- - | Authors: Georg Richter <ge...@mysql.com> | - | Andrey Hristov <and...@mysql.com> | - | Ulf Wendel <uwen...@mysql.com> | - ---------------------------------------------------------------------- - + +----------------------------------------------------------------------+ + | Authors: Georg Richter <ge...@php.net> | + | Andrey Hristov <and...@php.net> | + | Ulf Wendel <u...@php.net> | + +----------------------------------------------------------------------+ */ #ifndef MYSQLI_LIBMYSQL_H @@ -29,7 +28,8 @@ #define MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE 200 #define MYSQLND_OPT_INT_AND_YEAR_AS_INT 201 -#define mysqli_result_is_unbuffered(r) ((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) +/* r->data should be always NULL, at least in recent libmysql versions, the status changes once data is read*/ +#define mysqli_result_is_unbuffered(r) (((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL)) #define mysqli_server_status(c) (c)->server_status #define mysqli_stmt_get_id(s) ((s)->stmt_id) #define mysqli_stmt_warning_count(s) mysql_warning_count((s)->mysql) Added: php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c =================================================================== --- php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c (rev 0) +++ php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c 2010-05-18 10:39:26 UTC (rev 299444) @@ -0,0 +1,184 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | lice...@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <ge...@php.net> | + | Andrey Hristov <and...@php.net> | + | Ulf Wendel <u...@php.net> | + +----------------------------------------------------------------------+ + + $Id: mysqli.c 299335 2010-05-13 11:05:09Z andrey $ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "php_mysqli_structs.h" +#include "zend_interfaces.h" + + +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; + +typedef struct { + zend_object_iterator intern; + mysqli_object *result; + zval *current_row; + my_longlong row_num; +} php_mysqli_result_iterator; + + +/* {{{ */ +zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + iterator = ecalloc(1, sizeof(php_mysqli_result_iterator)); + + Z_ADDREF_P(object); + iterator->intern.data = (void*)object; + iterator->intern.funcs = &php_mysqli_result_iterator_funcs; + iterator->result = (mysqli_object *) zend_object_store_get_object(object TSRMLS_CC); + iterator->row_num = -1; + + return (zend_object_iterator*)iterator; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */ + if (iterator->intern.data) { + zval_ptr_dtor((zval**)&iterator->intern.data); + } + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + efree(iterator); +} +/* }}} */ + + +/* {{{ */ +static int php_mysqli_result_iterator_valid(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + return iterator->current_row && Z_TYPE_P(iterator->current_row) == IS_ARRAY ? SUCCESS : FAILURE; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *data = &iterator->current_row; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) +{ + + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + MAKE_STD_ZVAL(iterator->current_row); + php_mysqli_fetch_into_hash_aux(iterator->current_row, result, MYSQLI_ASSOC TSRMLS_CC); + if (Z_TYPE_P(iterator->current_row) == IS_ARRAY) { + iterator->row_num++; + } +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + + if (mysqli_result_is_unbuffered(result)) { +#if MYSQLI_USE_MYSQLND + if (result->unbuf && result->unbuf->eof_reached) { +#else + if (result->eof) { +#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data fetched with MYSQLI_USE_RESULT can be iterated only once"); + return; + } + } else { + mysql_data_seek(result, 0); + } + iterator->row_num = -1; + php_mysqli_result_iterator_move_forward(iter TSRMLS_CC); +} +/* }}} */ + + +/* {{{ */ +/* PHP6 has the following declaration + static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, zstr *str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +*/ +static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *int_key = iterator->row_num; + return HASH_KEY_IS_LONG; +} +/* }}} */ + + +/* {{{ php_mysqli_result_iterator_funcs */ +zend_object_iterator_funcs php_mysqli_result_iterator_funcs = { + php_mysqli_result_iterator_dtor, + php_mysqli_result_iterator_valid, + php_mysqli_result_iterator_current_data, + php_mysqli_result_iterator_current_key, + php_mysqli_result_iterator_move_forward, + php_mysqli_result_iterator_rewind, +}; +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ Modified: php/php-src/trunk/ext/mysqli/php_mysqli_structs.h =================================================================== --- php/php-src/trunk/ext/mysqli/php_mysqli_structs.h 2010-05-18 09:09:18 UTC (rev 299443) +++ php/php-src/trunk/ext/mysqli/php_mysqli_structs.h 2010-05-18 10:39:26 UTC (rev 299444) @@ -12,7 +12,9 @@ | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Georg Richter <ge...@php.net> | + | Authors: Georg Richter <ge...@php.net> | + | Andrey Hristov <and...@php.net> | + | Ulf Wendel <u...@php.net> | +----------------------------------------------------------------------+ $Id$ @@ -217,7 +219,11 @@ extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC); +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; +extern zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); +extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC); + #ifdef HAVE_SPL extern PHPAPI zend_class_entry *spl_ce_RuntimeException; #endif @@ -275,6 +281,21 @@ }\ } +#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \ +{ \ + MYSQLI_RESOURCE *my_res; \ + if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\ + return;\ + }\ + __ptr = (__type)my_res->ptr; \ + if (__check && my_res->status < __check) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + return;\ + }\ +} + + #define MYSQLI_SET_STATUS(__id, __value) \ { \ mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ Added: php/php-src/trunk/ext/mysqli/tests/mysqli_query_iterators.phpt =================================================================== --- php/php-src/trunk/ext/mysqli/tests/mysqli_query_iterators.phpt (rev 0) +++ php/php-src/trunk/ext/mysqli/tests/mysqli_query_iterators.phpt 2010-05-18 10:39:26 UTC (rev 299444) @@ -0,0 +1,201 @@ +--TEST-- +mysqli iterators +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + + echo "--- Testing default ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id"))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + foreach ($res as $row) { + var_dump($row); + } + } + echo "--- Testing USE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_USE_RESULT))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + echo "--- Testing STORE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_STORE_RESULT))) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +--- Testing default --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} + +Warning: main(): Couldn't fetch mysqli_result in %s on line %d +--- Testing USE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== + +Warning: main(): Data fetched with MYSQLI_USE_RESULT can be iterated only once in %s on line %d +--- Testing STORE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +done! \ No newline at end of file
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php