Skip to content

Commit

Permalink
Modify mysqli_fetch_object() to be able to instantiate a selected cla…
Browse files Browse the repository at this point in the history
…ss and

pass parameters to the constructor.
  • Loading branch information
helly25 committed Sep 6, 2003
1 parent f6239c3 commit 1ae13e5
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 20 deletions.
106 changes: 96 additions & 10 deletions ext/mysqli/mysqli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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");
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion ext/mysqli/mysqli_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
/* }}} */

Expand Down
12 changes: 4 additions & 8 deletions ext/mysqli/mysqli_nonapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,27 +120,23 @@ 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);
}
/* }}} */

/* {{{ proto array mysqli_fetch_assoc (object result)
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);
}
/* }}} */

Expand Down
2 changes: 1 addition & 1 deletion ext/mysqli/php_mysqli.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 1ae13e5

Please sign in to comment.