Hi all,

Referring to call_user_func_array() I would like to suggest a new function: new_object_array().
I'm working on a php5 application framework and I would like to implement something I call an unified factory. The problem is that I don't know how many parameters to expect.


Here's an example how it's meant to work:
<?PHP
class Kernel
{
public function __call($functionName, $functionParameters)
{
$className = substr($functionName, 3);
// code omitted here ...
// check for real $className ...
return new_object_array($className, $functionParameters);
}
public function newObject()
{
$functionParameters = func_get_args();
$className = array_shift($functionParameters);
// code omitted here ...
// check for real $className ...
return new_object_array($className, $functionParameters);
}
}


$Kernel = Kernel::getInstance();
$DbManager = $Kernel->getDbManager('param1', 'param2'); // 1st possibility to get new object
$XmlParser = $Kernel->newObject('XmlParser', 'param1', 'param2'); // 2nd possibility to get new object
?>


I have written an implementation of new_object_array(); <-- see attachment
Perhaps some things need to be rewritten ;)

I would be happy if you would consider to include this function in the standard distribution of php.

Yours sincerly,
Julian Reich
#include "php.h"

ZEND_FUNCTION(new_object_array);

zend_function_entry new_object_array_functions[] =
{
        ZEND_FE(new_object_array, NULL)
        {NULL, NULL, NULL}
};

zend_module_entry new_object_array_module_entry =
{
        STANDARD_MODULE_HEADER,
        "new_object_array()",
        new_object_array_functions,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NO_VERSION_YET,
        STANDARD_MODULE_PROPERTIES
};

#if COMPILE_DL_NEW_OBJECT_ARRAY
ZEND_GET_MODULE(new_object_array)
#endif

ZEND_FUNCTION(new_object_array)
{
        zval *object, *constructor_name, *constructor_return_value;
        zval **class_name, **constructor_parameters;
        zval ***constructor_real_parameters;
        zend_class_entry *ce;
        zend_class_entry **pce;
        HashTable *constructor_parameters_ht;
        int count, current = 0;

        if ((ZEND_NUM_ARGS() != 2) || (zend_get_parameters_ex(2, &class_name, 
&constructor_parameters) == FAILURE)) {
                ZEND_WRONG_PARAM_COUNT();
        }

        convert_to_string_ex(class_name);

        if (zend_lookup_class(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), &pce 
TSRMLS_CC) == FAILURE) {
                RETURN_FALSE;
        } else {
                ce = *pce;

                MAKE_STD_ZVAL(object);
                object_init_ex(object, ce);

                MAKE_STD_ZVAL(constructor_name);
                ZVAL_STRING(constructor_name, "__construct", 1);

                SEPARATE_ZVAL(constructor_parameters);
                convert_to_array_ex(constructor_parameters);

                constructor_parameters_ht = Z_ARRVAL_PP(constructor_parameters);

                count = zend_hash_num_elements(constructor_parameters_ht);
                constructor_real_parameters = safe_emalloc(sizeof(zval **), count, 0);

                for (zend_hash_internal_pointer_reset(constructor_parameters_ht);
                        zend_hash_get_current_data(constructor_parameters_ht, (void 
**) &constructor_real_parameters[current]) == SUCCESS;
                        zend_hash_move_forward(constructor_parameters_ht)
                        ) {
                        current++;
                }

                call_user_function_ex(NULL, &object, constructor_name, 
&constructor_return_value, count, constructor_real_parameters, 0, NULL TSRMLS_CC);

                *return_value = *object;
                zval_copy_ctor(return_value);
        }
}

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to