]> granicus.if.org Git - php/commitdiff
Modify mysqli_fetch_object() to be able to instantiate a selected class and
authorMarcus Boerger <helly@php.net>
Sat, 6 Sep 2003 19:34:48 +0000 (19:34 +0000)
committerMarcus Boerger <helly@php.net>
Sat, 6 Sep 2003 19:34:48 +0000 (19:34 +0000)
pass parameters to the constructor.

ext/mysqli/mysqli.c
ext/mysqli/mysqli_api.c
ext/mysqli/mysqli_nonapi.c
ext/mysqli/php_mysqli.h

index 6a4b5968486a5adde6fc506f62fd0fa1315e8bc4..2c0b603323f66a07253337cf83e9a2aee4f16554 100644 (file)
@@ -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));
index 94a16f20dc1c1b2fd236fb66816cc3e1e717ede4..7d96c846b77b75370544e6f45db8b5abf09cf24a 100644 (file)
@@ -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);
 }
 /* }}} */
 
index e98253c714ee95367b9d0bbe26c4ad365d559eb7..6d43be176887d038724ae37711b06a3b4b0dfd19 100644 (file)
@@ -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);  
 }
 /* }}} */
 
index 4b0ca2668562dfc4559a9bcd5a9f340c8e453fc7..e437f754be10551cebf91318eff0374b903ea476 100644 (file)
@@ -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);