Hello Christian, Johannes,

Friday, August 8, 2008, 11:48:37 PM, you wrote:

> Hello Christian,

>   I updated your patch for 5.3 due to recent changes. It works pretty fine
> for me. Care to test again, especially with your new tests? Note that test
> ext/reflection/tests/closures_001.phpt does not work for me and I have no
> clue why. Well, besides that obviously the closure class no longer has an
> entry for __closure, so it is more a question of how to know when to add
> this. Also, it appears you do not have a cvs account, or did I overlook
> something?

> Modified patch attached, including the updated reflection tests.

Ok, it is actually easy to fix, we just check whether the thing is a
closure and add the method manually, done. New patch attached.

Johannes, this also adresses the switch from E_ERROR to E_RECOVERABLE_ERROR
for the closure handlers.

best regards
marcus

> Monday, August 4, 2008, 12:59:13 PM, you wrote:

>> Christian,

>> On Mon, 2008-08-04 at 11:33 +0400, Dmitry Stogov wrote:
>>> >> http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-fixes-5.3.patch
>>> >>  
>>> >>
>>> >> http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-fixes-6.patch
>>> >>  
>>> > 

>> without applying and testing the patch:

>> -       zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC,
>> (apply_func_args_t) _addmethod, 3, &ce, return_value, filter);
>> +       zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC,
>> (apply_func_args_t) _addmethod, 3, &ce, return_value, filter, intern->obj);

>> that looks a bit strange, probably you want 4 instead of 3 now?

>> johannes





> Best regards,
>  Marcus



Best regards,
 Marcus
Index: Zend/zend_closures.c
===================================================================
RCS file: /repository/ZendEngine2/zend_closures.c,v
retrieving revision 1.3.2.10
diff -u -p -d -r1.3.2.10 zend_closures.c
--- Zend/zend_closures.c        7 Aug 2008 13:35:51 -0000       1.3.2.10
+++ Zend/zend_closures.c        8 Aug 2008 22:31:51 -0000
@@ -26,11 +26,10 @@
 #include "zend_objects_API.h"
 #include "zend_globals.h"
 
-#define ZEND_INVOKE_FUNC_NAME "__invoke"
 #define ZEND_CLOSURE_PRINT_NAME "Closure object"
 
 #define ZEND_CLOSURE_PROPERTY_ERROR() \
-       zend_error(E_ERROR, "Closure object cannot have properties")
+       zend_error(E_RECOVERABLE_ERROR, "Closure object cannot have properties")
 
 typedef struct _zend_closure {
        zend_object    std;
@@ -38,7 +37,8 @@ typedef struct _zend_closure {
        zval          *this_ptr;
 } zend_closure;
 
-static zend_class_entry *zend_ce_closure;
+/* non-static since it needs to be referenced */
+ZEND_API zend_class_entry *zend_ce_closure;
 static zend_object_handlers closure_handlers;
 
 ZEND_METHOD(Closure, __invoke) /* {{{ */
@@ -50,7 +50,7 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
        arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
        if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == 
FAILURE) {
                efree(arguments);
-               zend_error(E_ERROR, "Cannot get arguments for calling closure");
+               zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for 
calling closure");
                RETVAL_FALSE;
        } else if (call_user_function_ex(CG(function_table), NULL, this_ptr, 
&closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) 
{
                RETVAL_FALSE;
@@ -74,21 +74,21 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
 
 static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* 
{{{ */
 {
-       zend_error(E_ERROR, "Instantiation of 'Closure' is not allowed");
+       zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not 
allowed");
        return NULL;
 }
 /* }}} */
 
 static int zend_closure_serialize(zval *object, unsigned char **buffer, 
zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
 {
-       zend_error(E_ERROR, "Serialization of 'Closure' is not allowed");
+       zend_error(E_RECOVERABLE_ERROR, "Serialization of 'Closure' is not 
allowed");
        return FAILURE;
 }
 /* }}} */
 
 static int zend_closure_unserialize(zval **object, zend_class_entry *ce, const 
unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) 
/* {{{ */
 {
-       zend_error(E_ERROR, "Unserialization of 'Closure' is not allowed");
+       zend_error(E_RECOVERABLE_ERROR, "Unserialization of 'Closure' is not 
allowed");
        return FAILURE;
 }
 /* }}} */
@@ -99,6 +99,24 @@ static int zend_closure_compare_objects(
 }
 /* }}} */
 
+ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* 
{{{ */
+{
+       zend_closure *closure = (zend_closure 
*)zend_object_store_get_object(obj TSRMLS_CC);    
+       zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
+
+       invoke = (zend_function*)emalloc(sizeof(zend_function));
+       invoke->common = closure->func.common;
+       invoke->type = ZEND_INTERNAL_FUNCTION;
+       invoke->internal_function.handler = ZEND_MN(Closure___invoke);
+       invoke->internal_function.module = 0;
+       invoke->internal_function.scope = zend_ce_closure;
+       invoke->internal_function.function_name = 
estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
+       invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | 
ZEND_ACC_CALL_VIA_HANDLER;
+       return invoke;
+       
+}
+/* }}} */
+
 static zend_function *zend_closure_get_method(zval **object_ptr, char 
*method_name, int method_len TSRMLS_DC) /* {{{ */
 {
        char *lc_name;
@@ -109,18 +127,8 @@ static zend_function *zend_closure_get_m
        if ((method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
                memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
        ) {
-               zend_closure *closure = (zend_closure 
*)zend_object_store_get_object(*object_ptr TSRMLS_CC);
-               zend_function *invoke = 
(zend_function*)emalloc(sizeof(zend_function));
-
-               invoke->common = closure->func.common;
-               invoke->type = ZEND_INTERNAL_FUNCTION;
-               invoke->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
-               invoke->internal_function.handler = ZEND_MN(Closure___invoke);
-               invoke->internal_function.module = 0;
-               invoke->internal_function.scope = zend_ce_closure;
-               invoke->internal_function.function_name = 
estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
                free_alloca(lc_name, use_heap);
-               return invoke;
+               return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
        }
        free_alloca(lc_name, use_heap);
        return NULL;
@@ -170,7 +178,7 @@ static void zend_closure_free_storage(vo
                zend_execute_data *ex = EG(current_execute_data);
                while (ex) {
                        if (ex->op_array == &closure->func.op_array) {
-                               zend_error(E_ERROR, "Cannot destroy active 
lambda function");
+                               zend_error(E_RECOVERABLE_ERROR, "Cannot destroy 
active lambda function");
                        }
                        ex = ex->prev_execute_data;
                }
Index: Zend/zend_closures.h
===================================================================
RCS file: /repository/ZendEngine2/zend_closures.h,v
retrieving revision 1.1.2.2
diff -u -p -d -r1.1.2.2 zend_closures.h
--- Zend/zend_closures.h        14 Jul 2008 09:48:59 -0000      1.1.2.2
+++ Zend/zend_closures.h        8 Aug 2008 22:31:51 -0000
@@ -24,10 +24,15 @@
 
 BEGIN_EXTERN_C()
 
+#define ZEND_INVOKE_FUNC_NAME "__invoke"
+
 void zend_register_closure_ce(TSRMLS_D);
 
+extern ZEND_API zend_class_entry *zend_ce_closure;
+
 ZEND_API void zend_create_closure(zval *res, zend_function *op_array, 
zend_class_entry *scope, zval *this_ptr TSRMLS_DC);
 ZEND_API int zend_get_closure(zval *obj, zend_class_entry **ce_ptr, 
zend_function **fptr_ptr, zval **zobj_ptr, zval ***zobj_ptr_ptr TSRMLS_DC);
+ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC);
 
 END_EXTERN_C()
 
Index: ext/reflection/php_reflection.c
===================================================================
RCS file: /repository/php-src/ext/reflection/php_reflection.c,v
retrieving revision 1.164.2.33.2.45.2.27
diff -u -p -d -r1.164.2.33.2.45.2.27 php_reflection.c
--- ext/reflection/php_reflection.c     8 Aug 2008 10:52:48 -0000       
1.164.2.33.2.45.2.27
+++ ext/reflection/php_reflection.c     8 Aug 2008 22:31:53 -0000
@@ -536,6 +536,14 @@ static void _class_string(string *str, z
                                            
zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 
0, &pos) != HASH_KEY_IS_STRING ||
                                            zend_binary_strcasecmp(key, 
key_len-1, mptr->common.function_name, len) == 0) {
 
+                                               zend_function *closure_mptr;
+                                               /* see if this is a closure */
+                                               if (ce == zend_ce_closure && 
obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
+                                                       
memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 &&
+                                                       (closure_mptr = 
zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL
+                                               ) {
+                                                       mptr = closure_mptr;
+                                               }
                                                string_printf(&dyn, "\n");
                                                _function_string(&dyn, mptr, 
ce, sub_indent.string TSRMLS_CC);
                                                count++;
@@ -1890,15 +1898,34 @@ ZEND_METHOD(reflection_parameter, __cons
                                convert_to_string_ex(method);
                                lcname_len = Z_STRLEN_PP(method);
                                lcname = 
zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len);
-                               if (zend_hash_find(&ce->function_table, lcname, 
lcname_len + 1, (void **) &fptr) == FAILURE) {
+                               if (ce == zend_ce_closure && 
Z_TYPE_PP(classref) == IS_OBJECT &&
+                                       (lcname_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
+                                       memcmp(lcname, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 &&
+                                       (fptr = 
zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL
+                               ) {
+                                       /* do nothing, fptr is already set */
+                               } else if (zend_hash_find(&ce->function_table, 
lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
                                        efree(lcname);
                                        
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
-                                               "Method %s::%s() does not 
exist", Z_STRVAL_PP(classref), Z_TYPE_PP(method), Z_STRVAL_PP(method));
+                                               "Method %s::%s() does not 
exist", ce->name, Z_STRVAL_PP(method));
                                        return;
                                }
                                efree(lcname);
                        }
                        break;
+               
+               case IS_OBJECT: {
+                               ce = Z_OBJCE_P(reference);
+                               
+                               if (ce == zend_ce_closure && (fptr = 
zend_get_closure_invoke_method(reference TSRMLS_CC)) != NULL) {
+                                       /* do nothing, fptr is already set */
+                               } else if (zend_hash_find(&ce->function_table, 
ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == 
FAILURE) {
+                                       
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+                                               "Method %s::%s() does not 
exist", ce->name, ZEND_INVOKE_FUNC_NAME);
+                                       return;
+                               }
+                       }
+                       break;
                        
                default:
                        _DO_THROW("The parameter class is expected to be either 
a string or an array(class, method)");
@@ -2207,7 +2234,7 @@ ZEND_METHOD(reflection_method, export)
 ZEND_METHOD(reflection_method, __construct)
 {
        zval *name, *classname;
-       zval *object;
+       zval *object, *orig_obj;
        reflection_object *intern;
        char *lcname;
        zend_class_entry **pce;
@@ -2217,7 +2244,11 @@ ZEND_METHOD(reflection_method, __constru
        int name_len, tmp_len;
        zval ztmp;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
TSRMLS_CC, "o", &classname) == SUCCESS) {
+               name_str = ZEND_INVOKE_FUNC_NAME;
+               name_len = sizeof(ZEND_INVOKE_FUNC_NAME)-1;
+               orig_obj = classname;
+       } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 
ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", 
&name_str, &name_len) == FAILURE) {
                        return;
                }
@@ -2230,6 +2261,11 @@ ZEND_METHOD(reflection_method, __constru
                ZVAL_STRINGL(classname, name_str, tmp_len, 1);
                name_len = name_len - (tmp_len + 2);
                name_str = tmp + 2;
+               orig_obj = NULL;
+       } else if (Z_TYPE_P(classname) == IS_OBJECT) {
+               orig_obj = classname;
+       } else {
+               orig_obj = NULL;
        }
 
        object = getThis();
@@ -2275,7 +2311,12 @@ ZEND_METHOD(reflection_method, __constru
        
        lcname = zend_str_tolower_dup(name_str, name_len);
 
-       if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) 
&mptr) == FAILURE) {
+       if (ce == zend_ce_closure && orig_obj && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
+               memcmp(lcname, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 &&
+               (mptr = zend_get_closure_invoke_method(orig_obj TSRMLS_CC)) != 
NULL
+       ) {
+               /* do nothing, mptr already set */
+       } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, 
(void **) &mptr) == FAILURE) {
                efree(lcname);
                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                        "Method %s::%s() does not exist", ce->name, name_str);
@@ -3139,7 +3180,13 @@ ZEND_METHOD(reflection_class, getMethod)
 
        GET_REFLECTION_OBJECT_PTR(ce);
        lc_name = zend_str_tolower_dup(name, name_len);
-       if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) 
&mptr) == SUCCESS) {
+       if (ce == zend_ce_closure && intern->obj && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
+               memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 &&
+               (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) 
!= NULL
+       ) {
+               reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
+               efree(lc_name);
+       } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, 
(void**) &mptr) == SUCCESS) {
                reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
                efree(lc_name);
        } else {
@@ -3152,19 +3199,36 @@ ZEND_METHOD(reflection_class, getMethod)
 /* }}} */
 
 /* {{{ _addmethod */
-static int _addmethod(zend_function *mptr TSRMLS_DC, int num_args, va_list 
args, zend_hash_key *hash_key)
+static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval 
*retval, long filter, zval *obj TSRMLS_DC)
 {
        zval *method;
-       zend_class_entry *ce = *va_arg(args, zend_class_entry**);
-       zval *retval = va_arg(args, zval*);
-       long filter = va_arg(args, long);
+       uint len = strlen(mptr->common.function_name);
+       zend_function *closure_mptr;
 
        if (mptr->common.fn_flags & filter) {
                ALLOC_ZVAL(method);
+               if (ce == zend_ce_closure && obj && (len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
+                       memcmp(mptr->common.function_name, 
ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 &&
+                       (closure_mptr = zend_get_closure_invoke_method(obj 
TSRMLS_CC)) != NULL
+               ) {
+                       mptr = closure_mptr;
+               }
                reflection_method_factory(ce, mptr, method TSRMLS_CC);
                add_next_index_zval(retval, method);
        }
-       return 0;
+}
+/* }}} */
+
+/* {{{ _addmethod */
+static int _addmethod_va(zend_function *mptr TSRMLS_DC, int num_args, va_list 
args, zend_hash_key *hash_key)
+{
+       zend_class_entry *ce = *va_arg(args, zend_class_entry**);
+       zval *retval = va_arg(args, zval*);
+       long filter = va_arg(args, long);
+       zval *obj = va_arg(args, zval *);
+       
+       _addmethod(mptr, ce, retval, filter, obj TSRMLS_CC);
+       return ZEND_HASH_APPLY_KEEP;
 }
 /* }}} */
 
@@ -3190,7 +3254,16 @@ ZEND_METHOD(reflection_class, getMethods
        GET_REFLECTION_OBJECT_PTR(ce);
 
        array_init(return_value);
-       zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, 
(apply_func_args_t) _addmethod, 3, &ce, return_value, filter);
+       zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, 
(apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj);
+       if (intern->obj && instanceof_function(ce, zend_ce_closure)) {
+               zend_function *closure = 
zend_get_closure_invoke_method(intern->obj TSRMLS_CC);
+               if (closure) {
+                       _addmethod(closure, ce, return_value, filter, 
intern->obj TSRMLS_CC);
+                       if (closure->type != ZEND_USER_FUNCTION && 
(closure->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) {
+                               efree(closure);
+                       }
+               }
+       }
 }
 /* }}} */
 
Index: ext/reflection/tests/closures_001.phpt
===================================================================
RCS file: ext/reflection/tests/closures_001.phpt
diff -N ext/reflection/tests/closures_001.phpt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ext/reflection/tests/closures_001.phpt      8 Aug 2008 22:31:53 -0000
@@ -0,0 +1,70 @@
+--TEST--
+Reflection on closures
+--FILE-- 
+<?php
+
+$closure = function ($a, $b = 0) { };
+
+$ro = new ReflectionObject ($closure);
+$rm = $ro->getMethod ('__invoke');
+var_dump ($rm->getNumberOfParameters());
+var_dump ($rm->getNumberOfRequiredParameters());
+$rms = $ro->getMethods();
+foreach ($rms as $rm) {
+       if ($rm->getName () == '__invoke') {
+               var_dump ($rm->getNumberOfParameters());
+               var_dump ($rm->getNumberOfRequiredParameters());
+       }
+}
+
+echo "---\n";
+
+$rm = new ReflectionMethod ($closure);
+var_dump ($rm->getName ());
+var_dump ($rm->getNumberOfParameters());
+var_dump ($rm->getNumberOfRequiredParameters());
+
+echo "---\n";
+
+$rp = new ReflectionParameter (array ($closure, '__invoke'), 0);
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter (array ($closure, '__invoke'), 1);
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter (array ($closure, '__invoke'), 'a');
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter (array ($closure, '__invoke'), 'b');
+var_dump ($rp->isOptional ());
+
+echo "---\n";
+
+$rp = new ReflectionParameter ($closure, 0);
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter ($closure, 1);
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter ($closure, 'a');
+var_dump ($rp->isOptional ());
+$rp = new ReflectionParameter ($closure, 'b');
+var_dump ($rp->isOptional ());
+
+?>
+===DONE===
+--EXPECTF--
+int(2)
+int(1)
+int(2)
+int(1)
+---
+string(8) "__invoke"
+int(2)
+int(1)
+---
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+---
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+===DONE===
Index: ext/reflection/tests/closures_002.phpt
===================================================================
RCS file: ext/reflection/tests/closures_002.phpt
diff -N ext/reflection/tests/closures_002.phpt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ext/reflection/tests/closures_002.phpt      8 Aug 2008 22:31:53 -0000
@@ -0,0 +1,25 @@
+--TEST--
+Reflection on invokable objects
+--FILE-- 
+<?php
+
+$rm = new ReflectionMethod (new C);
+var_dump ($rm->getName ());
+var_dump ($rm->getNumberOfParameters());
+var_dump ($rm->getNumberOfRequiredParameters());
+
+$rp = new ReflectionParameter (new C, 0);
+var_dump ($rp->isOptional ());
+
+class C {
+       function __invoke ($a) { }
+}
+
+?>
+===DONE===
+--EXPECTF--
+string(8) "__invoke"
+int(1)
+int(1)
+bool(false)
+===DONE===
Index: Zend/tests/closure_017.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/closure_017.phpt,v
retrieving revision 1.1.2.1
diff -u -p -d -r1.1.2.1 closure_017.phpt
--- Zend/tests/closure_017.phpt 14 Jul 2008 13:36:40 -0000      1.1.2.1
+++ Zend/tests/closure_017.phpt 8 Aug 2008 22:31:53 -0000
@@ -9,4 +9,4 @@ $a($a);
 
 ?>
 --EXPECTF--
-Fatal error: Cannot destroy active lambda function in %s on line %d
+Catchable fatal error: Cannot destroy active lambda function in %s on line %d
Index: Zend/tests/closure_022.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/closure_022.phpt,v
retrieving revision 1.1.2.2
diff -u -p -d -r1.1.2.2 closure_022.phpt
--- Zend/tests/closure_022.phpt 22 Jul 2008 07:29:31 -0000      1.1.2.2
+++ Zend/tests/closure_022.phpt 8 Aug 2008 22:31:53 -0000
@@ -8,5 +8,5 @@ $foo = function() use ($a) {
 $foo->a = 1;
 ?>
 --EXPECTF--
-Fatal error: Closure object cannot have properties in %sclosure_022.php on 
line 5
+Catchable fatal error: Closure object cannot have properties in 
%sclosure_022.php on line 5
 
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to