diff options
Diffstat (limited to 'ext/mysqli')
-rw-r--r-- | ext/mysqli/mysqli.c | 106 | ||||
-rw-r--r-- | ext/mysqli/mysqli_api.c | 2 | ||||
-rw-r--r-- | ext/mysqli/mysqli_nonapi.c | 12 | ||||
-rw-r--r-- | ext/mysqli/php_mysqli.h | 2 |
4 files changed, 102 insertions, 20 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 6a4b596848..2c0b603323 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -29,6 +29,7 @@ #include "ext/standard/info.h" #include "ext/standard/php_string.h" #include "php_mysqli.h" +#include "zend_default_classes.h" #define MYSQLI_STORE_RESULT 0 #define MYSQLI_USE_RESULT 1 @@ -371,7 +372,7 @@ PHP_MINFO_FUNCTION(mysqli) /* {{{ php_mysqli_fetch_into_hash */ -void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags) +void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) { MYSQL_RES *result; zval *mysql_result; @@ -383,17 +384,38 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags unsigned long *field_len; PR_RESULT *prresult; PR_COMMAND *prcommand; + zval *ctor_params = NULL; + zend_class_entry *ce = NULL; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { - return; - } - - if (ZEND_NUM_ARGS() < 2 && !override_flags) { - fetchtype = MYSQLI_BOTH; - } + if (into_object) { + char *class_name; + int class_name_len; - if (override_flags) { - fetchtype = override_flags; + 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_NUM; + 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 *, prresult, PR_RESULT *, &mysql_result, "mysqli_result"); @@ -439,6 +461,70 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags } } + if (into_object) { + zval dataset = *return_value; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval *retval_ptr; + + object_and_properties_init(return_value, ce, NULL); + zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); + + if (ce->constructor) { + fci.size = sizeof(fci); + fci.function_table = &ce->function_table; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_pp = &return_value; + fci.retval_ptr_ptr = &retval_ptr; + if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) { + if (Z_TYPE_P(ctor_params) == IS_ARRAY) { + HashTable *ht = Z_ARRVAL_P(ctor_params); + Bucket *p; + + fci.param_count = 0; + fci.params = emalloc(sizeof(zval*) * ht->nNumOfElements); + p = ht->pListHead; + while (p != NULL) { + fci.params[fci.param_count++] = (zval**)p->pData; + p = p->pListNext; + } + } else { + /* Two problems why we throw exceptions here: PHP is typeless + * and hence passing one argument that's not an array could be + * by mistake and the other way round is possible, too. The + * single value is an array. Also we'd have to make that one + * argument passed by reference. + */ + zend_throw_exception(zend_exception_get_default(), "Parameter ctor_params must be an array", 0 TSRMLS_CC); + return; + } + } else { + fci.param_count = 0; + fci.params = NULL; + } + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; + fcc.calling_scope = EG(scope); + fcc.object_pp = &return_value; + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); + } else { + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + } + if (fci.params) { + efree(fci.params); + } + } else if (ctor_params) { + zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); + } + } + if (MyG(profiler)) { char tmp[10]; sprintf ((char *)&tmp,"row[%d]", mysql_num_fields(result)); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 94a16f20dc..7d96c846b7 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -899,7 +899,7 @@ PHP_FUNCTION(mysqli_fetch_lengths) Get a result row as an enumerated array */ PHP_FUNCTION(mysqli_fetch_row) { - php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM); + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0); } /* }}} */ diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index e98253c714..6d43be1768 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -120,7 +120,7 @@ PHP_FUNCTION(mysqli_connect_error) Fetch a result row as an associative array, a numeric array, or both */ PHP_FUNCTION(mysqli_fetch_array) { - php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0); } /* }}} */ @@ -128,19 +128,15 @@ PHP_FUNCTION(mysqli_fetch_array) Fetch a result row as an associative array */ PHP_FUNCTION(mysqli_fetch_assoc) { - php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC); + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0); } /* }}} */ -/* {{{ proto array mysqli_fetch_object (object result) +/* {{{ proto array mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]]) Fetch a result row as an object */ PHP_FUNCTION(mysqli_fetch_object) { - php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC); - - if (Z_TYPE_P(return_value) == IS_ARRAY) { - object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value)); - } + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1); } /* }}} */ diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 4b0ca26685..e437f754be 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -90,7 +90,7 @@ extern function_entry mysqli_functions[]; extern function_entry mysqli_link_methods[]; extern function_entry mysqli_stmt_methods[]; extern function_entry mysqli_result_methods[]; -extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int flag); +extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object); extern void php_clear_stmt_bind(STMT *stmt); extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); |