helly           Tue Jan 24 20:19:49 2006 UTC

  Added files:                 
    /php-src/ext/reflection/tests       007.phpt 

  Modified files:              
    /php-src/ext/reflection     php_reflection.c 
  Log:
  - Implemented #36141 Add ReflectionClass::newInstanceArgs($args)
  
  
http://cvs.php.net/viewcvs.cgi/php-src/ext/reflection/php_reflection.c?r1=1.200&r2=1.201&diff_format=u
Index: php-src/ext/reflection/php_reflection.c
diff -u php-src/ext/reflection/php_reflection.c:1.200 
php-src/ext/reflection/php_reflection.c:1.201
--- php-src/ext/reflection/php_reflection.c:1.200       Tue Jan 17 12:18:52 2006
+++ php-src/ext/reflection/php_reflection.c     Tue Jan 24 20:19:49 2006
@@ -20,7 +20,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_reflection.c,v 1.200 2006/01/17 12:18:52 dmitry Exp $ */
+/* $Id: php_reflection.c,v 1.201 2006/01/24 20:19:49 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -3193,8 +3193,6 @@
        METHOD_NOTSTATIC(reflection_class_ptr);
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       object_init_ex(return_value, ce);
-
        /* Run the constructor if there is one */
        if (ce->constructor) {
                zval ***params;
@@ -3212,6 +3210,8 @@
                        RETURN_FALSE;
                }
 
+               object_init_ex(return_value, ce);
+
                fci.size = sizeof(fci);
                fci.function_table = EG(function_table);
                fci.function_name = NULL;
@@ -3237,6 +3237,79 @@
                        zval_ptr_dtor(&retval_ptr);
                }
                efree(params);
+       } else if (!ZEND_NUM_ARGS()) {
+               object_init_ex(return_value, ce);
+       } else {
+               
zend_throw_exception_ex(U_CLASS_ENTRY(reflection_exception_ptr), 0 TSRMLS_CC, 
"Class %v does not have a constructor, so you cannot pass any constructor 
arguments", ce->name);
+       }
+}
+/* }}} */
+
+/* {{{ proto public stdclass ReflectionClass::newInstanceArgs(array args)
+   Returns an instance of this class */
+ZEND_METHOD(reflection_class, newInstanceArgs)
+{
+       zval *retval_ptr;
+       reflection_object *intern;
+       zend_class_entry *ce;
+       int argc;
+       HashTable *args;
+       
+       
+       METHOD_NOTSTATIC(reflection_class_ptr);
+       GET_REFLECTION_OBJECT_PTR(ce);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == 
FAILURE) {
+               return;
+       }
+       argc = args->nNumOfElements;
+       
+       /* Run the constructor if there is one */
+       if (ce->constructor) {
+               zval ***params;
+               zend_fcall_info fci;
+               zend_fcall_info_cache fcc;
+
+               if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+                       
zend_throw_exception_ex(U_CLASS_ENTRY(reflection_exception_ptr), 0 TSRMLS_CC, 
"Access to non-public constructor of class %v", ce->name);
+                       return;
+               }
+
+               params = safe_emalloc(sizeof(zval **), argc, 0);
+               zend_hash_apply_with_argument(args, 
(apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);       
+               params -= argc;
+
+               object_init_ex(return_value, ce);
+
+               fci.size = sizeof(fci);
+               fci.function_table = EG(function_table);
+               fci.function_name = NULL;
+               fci.symbol_table = NULL;
+               fci.object_pp = &return_value;
+               fci.retval_ptr_ptr = &retval_ptr;
+               fci.param_count = argc;
+               fci.params = params;
+               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) {
+                       efree(params);
+                       zval_ptr_dtor(&retval_ptr);
+                       zend_error(E_WARNING, "Invocation of %v's constructor 
failed", ce->name);
+                       RETURN_NULL();
+               }
+               if (retval_ptr) {
+                       zval_ptr_dtor(&retval_ptr);
+               }
+               efree(params);
+       } else if (!ZEND_NUM_ARGS()) {
+               object_init_ex(return_value, ce);
+       } else {
+               
zend_throw_exception_ex(U_CLASS_ENTRY(reflection_exception_ptr), 0 TSRMLS_CC, 
"Class %v does not have a constructor, so you cannot pass any constructor 
arguments", ce->name);
        }
 }
 /* }}} */
@@ -4094,6 +4167,7 @@
        ZEND_ME(reflection_class, getModifiers, NULL, 0)
        ZEND_ME(reflection_class, isInstance, NULL, 0)
        ZEND_ME(reflection_class, newInstance, NULL, 0)
+       ZEND_ME(reflection_class, newInstanceArgs, NULL, 0)
        ZEND_ME(reflection_class, getParentClass, NULL, 0)
        ZEND_ME(reflection_class, isSubclassOf, NULL, 0)
        ZEND_ME(reflection_class, getStaticProperties, NULL, 0)
@@ -4272,7 +4346,7 @@
        php_info_print_table_start();
        php_info_print_table_header(2, "Reflection", "enabled");
 
-       php_info_print_table_row(2, "Version", "$Id: php_reflection.c,v 1.200 
2006/01/17 12:18:52 dmitry Exp $");
+       php_info_print_table_row(2, "Version", "$Id: php_reflection.c,v 1.201 
2006/01/24 20:19:49 helly Exp $");
 
        php_info_print_table_end();
 } /* }}} */

http://cvs.php.net/viewcvs.cgi/php-src/ext/reflection/tests/007.phpt?view=markup&rev=1.1
Index: php-src/ext/reflection/tests/007.phpt
+++ php-src/ext/reflection/tests/007.phpt
--TEST--
ReflectionClass::newInstance[Args]
--FILE--
<?php

function test($class)
{
        echo "====>$class\n";
        try
        {
                $ref = new ReflectionClass($class);
        }
        catch (ReflectionException $e)
        {
                var_dump($e->getMessage());
                return; // only here
        }

        echo "====>newInstance()\n";
        try
        {
                var_dump($ref->newInstance());
        }
        catch (ReflectionException $e)
        {
                var_dump($e->getMessage());
        }
        
        echo "====>newInstance(25)\n";
        try
        {
                var_dump($ref->newInstance(25));
        }
        catch (ReflectionException $e)
        {
                var_dump($e->getMessage());
        }

        echo "====>newInstance(25, 42)\n";
        try
        {
                var_dump($ref->newInstance(25, 42));
        }
        catch (ReflectionException $e)
        {
                var_dump($e->getMessage());
        }
        
        echo "\n";
}

function __autoload($class)
{
        echo __FUNCTION__ . "($class)\n";
}

test('Class_does_not_exist');

Class NoCtor
{
}

test('NoCtor');

Class WithCtor
{
        function __construct()
        {
                echo __METHOD__ . "()\n";
                var_dump(func_get_args());
        }
}

test('WithCtor');

Class WithCtorWithArgs
{
        function __construct($arg)
        {
                echo __METHOD__ . "($arg)\n";
                var_dump(func_get_args());
        }
}

test('WithCtorWithArgs');

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--

====>Class_does_not_exist
__autoload(Class_does_not_exist)
string(41) "Class Class_does_not_exist does not exist"
====>NoCtor
====>newInstance()
object(NoCtor)#%d (0) {
}
====>newInstance(25)
string(86) "Class NoCtor does not have a constructor, so you cannot pass any 
constructor arguments"
====>newInstance(25, 42)
string(86) "Class NoCtor does not have a constructor, so you cannot pass any 
constructor arguments"

====>WithCtor
====>newInstance()
WithCtor::__construct()
array(0) {
}
object(WithCtor)#%d (0) {
}
====>newInstance(25)
WithCtor::__construct()
array(1) {
  [0]=>
  int(25)
}
object(WithCtor)#%d (0) {
}
====>newInstance(25, 42)
WithCtor::__construct()
array(2) {
  [0]=>
  int(25)
  [1]=>
  int(42)
}
object(WithCtor)#%d (0) {
}

====>WithCtorWithArgs
====>newInstance()

Warning: Missing argument 1 for WithCtorWithArgs::__construct() in %s007.php on 
line %d

Notice: Undefined variable: arg in %s007.php on line %d
WithCtorWithArgs::__construct()
array(0) {
}
object(WithCtorWithArgs)#%d (0) {
}
====>newInstance(25)
WithCtorWithArgs::__construct(25)
array(1) {
  [0]=>
  int(25)
}
object(WithCtorWithArgs)#%d (0) {
}
====>newInstance(25, 42)
WithCtorWithArgs::__construct(25)
array(2) {
  [0]=>
  int(25)
  [1]=>
  int(42)
}
object(WithCtorWithArgs)#%d (0) {
}

===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to