Hi all,
Static callbacks behave differently between 5.2 and 5.3, I recently
noticed this when trying to install PEAR, it printed a warning each time
call_user_func and call_user_func_array was used.
After some tracking down it seems like the callback option for
zend_parse_parameters was backported from 6 but the strict check was
left as is.
<?php
class MyClass { function test($var) { echo "$var\n"; } }
MyClass::Test('regular');
call_user_func(array('MyClass', 'test'), 'callback');
?>
The prints E_STRICT
errors in PHP 5.2 but in 5.3 you get a single
E_STRICT
error followed by a warning for call_user_func.
You can resolve this by adding the static keyword to the method
declaration but regardless it's inconsistent as stands. I think the
strict flag needs to be removed for 5.3.
Patch is attached to resolve the issue.
Scott
Hi,
I planned to do some various callbacks related cleanups on 5_3.
If that's ok with you, I'll come with a patch within the following
days that should fix various issues, including your patch if still
necessary.
Regards
Hi all,
Static callbacks behave differently between 5.2 and 5.3, I recently
noticed this when trying to install PEAR, it printed a warning each time
call_user_func and call_user_func_array was used.After some tracking down it seems like the callback option for
zend_parse_parameters was backported from 6 but the strict check was
left as is.<?php
class MyClass { function test($var) { echo "$var\n"; } }
MyClass::Test('regular');
call_user_func(array('MyClass', 'test'), 'callback');
?>The prints
E_STRICT
errors in PHP 5.2 but in 5.3 you get a single
E_STRICT
error followed by a warning for call_user_func.You can resolve this by adding the static keyword to the method
declaration but regardless it's inconsistent as stands. I think the
strict flag needs to be removed for 5.3.Patch is attached to resolve the issue.
Scott
Index: ZendEngine2/zend_API.c
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.17
diff -u -r1.296.2.27.2.34.2.17 zend_API.c
--- ZendEngine2/zend_API.c 24 Jan 2008 10:49:26 -0000 1.296.2.27.2.34.2.17
+++ ZendEngine2/zend_API.c 30 Jan 2008 10:37:45 -0000
@@ -2568,7 +2568,7 @@
zend_function *func;
zval **obj;
if (!zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, NULL, &ce, &func, &obj TSRMLS_CC)) {
if (!zend_is_callable_ex(callable, 0, callable_name, NULL, &ce, &func, &obj TSRMLS_CC)) { return FAILURE; }
--
--
Etienne Kneuss
http://www.colder.ch
Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal
Hi,
If you could rename IS_CALLABLE_CHECK_NO_ACCESS too that would be great,
at first glance I expected it to check access on the callback. In
reality its to skip the access check, so might be worth checking from a
clarity point of view. IS_CALLABLE_SKIP_ACCESS_CHECK or
IS_CALLABLE_ACCESS_CHECK_SKIP.
Scott
Etienne Kneuss wrote:
Hi,
I planned to do some various callbacks related cleanups on 5_3.
If that's ok with you, I'll come with a patch within the following
days that should fix various issues, including your patch if still
necessary.Regards
Hi all,
Static callbacks behave differently between 5.2 and 5.3, I recently
noticed this when trying to install PEAR, it printed a warning each time
call_user_func and call_user_func_array was used.After some tracking down it seems like the callback option for
zend_parse_parameters was backported from 6 but the strict check was
left as is.<?php
class MyClass { function test($var) { echo "$var\n"; } }
MyClass::Test('regular');
call_user_func(array('MyClass', 'test'), 'callback');
?>The prints
E_STRICT
errors in PHP 5.2 but in 5.3 you get a single
E_STRICT
error followed by a warning for call_user_func.You can resolve this by adding the static keyword to the method
declaration but regardless it's inconsistent as stands. I think the
strict flag needs to be removed for 5.3.Patch is attached to resolve the issue.
Scott
Index: ZendEngine2/zend_API.c
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.17
diff -u -r1.296.2.27.2.34.2.17 zend_API.c
--- ZendEngine2/zend_API.c 24 Jan 2008 10:49:26 -0000 1.296.2.27.2.34.2.17
+++ ZendEngine2/zend_API.c 30 Jan 2008 10:37:45 -0000
@@ -2568,7 +2568,7 @@
zend_function *func;
zval **obj;
if (!zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, NULL, &ce, &func, &obj TSRMLS_CC)) {
if (!zend_is_callable_ex(callable, 0, callable_name, NULL, &ce, &func, &obj TSRMLS_CC)) { return FAILURE; }
Hello Scott,
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.
marcus
Wednesday, January 30, 2008, 11:48:50 AM, you wrote:
Hi all,
Static callbacks behave differently between 5.2 and 5.3, I recently
noticed this when trying to install PEAR, it printed a warning each time
call_user_func and call_user_func_array was used.
After some tracking down it seems like the callback option for
zend_parse_parameters was backported from 6 but the strict check was
left as is.
<?php
class MyClass { function test($var) { echo "$var\n"; } }
MyClass::Test('regular');
call_user_func(array('MyClass', 'test'), 'callback');
?>>
The prints
E_STRICT
errors in PHP 5.2 but in 5.3 you get a single
E_STRICT
error followed by a warning for call_user_func.
You can resolve this by adding the static keyword to the method
declaration but regardless it's inconsistent as stands. I think the
strict flag needs to be removed for 5.3.
Patch is attached to resolve the issue.
Scott
Best regards,
Marcus
Hello Scott,
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.
I believe the bug was to make non-static methods to behave differently depending on the way you call them.
If calling class::method() directly produces E_STRICT
notice, then calling call::method() as a callback should do the same.
--
Wbr,
Antony Dovgal
Marcus,
I fully agree that you should add static keywords if you intend to call
a method statically, but it's not always possible. Some people are still
maintaing a code base that runs in both PHP 4 and 5 without any
significant changes.
The other problem here is inconsistency, I can call the method
statically at the moment but I can't do it via a callback? Either the
behaviour needs to match or revert it back to an E_STRICT
message until
PHP 6.
Scott
Marcus Boerger wrote:
Hello Scott,
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.marcus
Wednesday, January 30, 2008, 11:48:50 AM, you wrote:
Hi all,
Static callbacks behave differently between 5.2 and 5.3, I recently
noticed this when trying to install PEAR, it printed a warning each time
call_user_func and call_user_func_array was used.After some tracking down it seems like the callback option for
zend_parse_parameters was backported from 6 but the strict check was
left as is.<?php
class MyClass { function test($var) { echo "$var\n"; } }
MyClass::Test('regular');
call_user_func(array('MyClass', 'test'), 'callback');
?>>The prints
E_STRICT
errors in PHP 5.2 but in 5.3 you get a single
E_STRICT
error followed by a warning for call_user_func.You can resolve this by adding the static keyword to the method
declaration but regardless it's inconsistent as stands. I think the
strict flag needs to be removed for 5.3.Patch is attached to resolve the issue.
Scott
Best regards,
Marcus
Quoting Marcus Boerger helly@php.net:
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.
The bug is that with callbacks in PHP 5.3+, E_STRICT
is enforced even
when E_STRICT
is turned off. See bug #43231 (I've been unable to use
PHP 5.3 since November because of this):
http://bugs.php.net/bug.php?id=43231
This works fine:
class foo {
function bar() {
echo 'hi';
}
}
foo::bar();
This throws a warning:
call_user_func(array('foo', 'bar'));
Both should certainly be E_STRICT
errors. The 2nd one should not throw
a warning if E_STRICT
is off, though.
-chuck
Marcus Boerger wrote:
Hello Scott,
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.
Hi Marcus,
How is forcing users to replace call_user_func(array('Classname',
'func')) with eval('Classname::func') a good policy?
When this example code:
<?php
error_reporting(E_NOTICE|E_WARNING|E_ERROR);
class A { function B (){}}
A::B();
?>
functions differently from this code:
<?php
error_reporting(E_NOTICE|E_WARNING|E_ERROR);
class A { function B (){}}
call_user_func(array('A','B'));
?>
And in a minor version increment, this in fact introduces a bug, and
doesn't fix one.
I think the fix may be to simply add retval=0 in
zend_is_callable_check_func() here:
if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
retval = 0;
} else {
if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), *ce_ptr
TSRMLS_CC)) {
*zobj_ptr_ptr = &EG(This);
zend_error(E_STRICT, "Non-static method %s::%s() cannot be called
statically, assuming $this from compatible context %s", (*ce_ptr)->name,
fptr->common.function_name, Z_OBJCE_P(EG(This))->name);
} else {
zend_error(E_STRICT, "Non-static method %s::%s() cannot be called
statically", (*ce_ptr)->name, fptr->common.function_name);
}
}
basically what is happening is that E_STRICT
makes the callback invalid,
which is not technically true - the callback is valid, just not strictly
correct.
I can make a patch next week, if someone doesn't beat me to it. We need
a retval=0 in the inner else clause
Greg
Greg Beaver wrote:
Marcus Boerger wrote:
Hello Scott,
actually it was a bug. We, sorry I, did not spot this in earlier versions.
Now saying you rely on a bug in PHP 5 to be able to execute PHP 4 code
simply does not work.Hi Marcus,
How is forcing users to replace call_user_func(array('Classname',
'func')) with eval('Classname::func') a good policy?When this example code:
<?php
error_reporting(E_NOTICE|E_WARNING|E_ERROR);
class A { function B (){}}
A::B();
?>functions differently from this code:
<?php
error_reporting(E_NOTICE|E_WARNING|E_ERROR);
class A { function B (){}}
call_user_func(array('A','B'));
?>And in a minor version increment, this in fact introduces a bug, and
doesn't fix one.I think the fix may be to simply add retval=0 in
zend_is_callable_check_func() here:if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) { retval = 0; } else { if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), *ce_ptr
TSRMLS_CC)) {
*zobj_ptr_ptr = &EG(This);
zend_error(E_STRICT, "Non-static method %s::%s() cannot be called
statically, assuming $this from compatible context %s", (*ce_ptr)->name,
fptr->common.function_name, Z_OBJCE_P(EG(This))->name);
} else {
zend_error(E_STRICT, "Non-static method %s::%s() cannot be called
statically", (*ce_ptr)->name, fptr->common.function_name);
}
}basically what is happening is that
E_STRICT
makes the callback invalid,
which is not technically true - the callback is valid, just not strictly
correct.I can make a patch next week, if someone doesn't beat me to it. We need
a retval=0 in the inner else clause
Yes, I agree that we need to be consistent here.
error_reporting(E_ALL|E_STRICT);
class foo { function bar() { echo "gah"; } }
call_user_func('foo::bar');
foo::bar();
This needs to throw an E_STRICT
in both cases. Right now we get an
E_WARNING
and the call doesn't work for the first, and an E_STRICT
for
the second. Having these behave differently makes no sense.
And likewise, is_callable('foo::bar') should return true.
-Rasmus