Bug #51527 [Com]: is_callable() returning true for non-static callbacks

2010-07-19 Thread hnzksq at gmail dot com
Edit report at http://bugs.php.net/bug.php?id=51527edit=1

 ID:   51527
 Comment by:   hnzksq at gmail dot com
 Reported by:  weierophin...@php.net
 Summary:  is_callable() returning true for non-static callbacks
 Status:   Open
 Type: Bug
 Package:  Class/Object related
 Operating System: Linux
 PHP Version:  5.3.2

 New Comment:

?php



/**

 * @author zhouw

 * @copyright 2010

 */



class Foo

{

public function bar()

{

return 'foo bar';

}

}



$callback = array('Foo', 'bar');

if (is_callable($callback)) {

echo call_user_func($callback);

}



?



我测试可以用的。


Previous Comments:

[2010-05-07 16:39:56] crrodriguez at opensuse dot org

philduby at phriendly dot net : what you mention seems to be  another 

bug/misfeature.


[2010-05-05 07:03:50] philduby at phriendly dot net

Another variation that actually (unexpectedly) works:

Calling is_callable and call_user_func from inside an instance
(non-static) method using any of: 'self::otherInstanceMethod',
array('self','otherInstanceMethod'), array(self,'otherInstanceMethod')
succeed.  It appears that (the context for) '$this' is carried over from
the original method, even though the calls are being done statically.



Calling self::otherInstanceMethod() directly also succeeds.  It appears
that methods called from an instance method 'inherit' the context for
$this.  A bit unexpected, but *reasonable*.

Win XP SP3

PHP 5.3.1 (xampp)


[2010-04-12 11:50:33] paj...@php.net

I don't like the optional flag idea. You can disable strictness using
error_reporting already.



However I would like to see this change in trunk, can you come up with a
RFC pls?


[2010-04-10 20:19:45] weierophin...@php.net

@johannes Perhaps an optional strict flag to is_callable() would
address this? 

That would keep BC, while allowing for better checking for = PHP-5
apps. Usage 

would be:



$callback = array('Foo', 'bar');



if (is_callable($callback, true)) {

// Passed strict check

} else {

// failed strict check

}



Thoughts?


[2010-04-10 17:55:25] johan...@php.net

The method can always be called statically. The access to $this might be
forbidden but the method itself can be called. is_callable() doesn't
mean it will execute properly. (the $this error is basically the same as
a call to an undefined funciton in there or such)



To change this the only way would be to forbid calling non-static
methods statically. Maybe this can be done nowadays (we needed the
behavior for PHP 4 compatibility) but that's no bug but requires a RFC
and discussion on internals as this might break quite a few applications
(many PEAR-based things, many legacy applications not fully converted
to PHP 5 )




The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

http://bugs.php.net/bug.php?id=51527


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1


Bug #51527 [Com]: is_callable() returning true for non-static callbacks

2010-05-07 Thread crrodriguez at opensuse dot org
Edit report at http://bugs.php.net/bug.php?id=51527edit=1

 ID:   51527
 Comment by:   crrodriguez at opensuse dot org
 Reported by:  weierophin...@php.net
 Summary:  is_callable() returning true for non-static callbacks
 Status:   Open
 Type: Bug
 Package:  Class/Object related
 Operating System: Linux
 PHP Version:  5.3.2

 New Comment:

philduby at phriendly dot net : what you mention seems to be  another 

bug/misfeature.


Previous Comments:

[2010-05-05 07:03:50] philduby at phriendly dot net

Another variation that actually (unexpectedly) works:

Calling is_callable and call_user_func from inside an instance
(non-static) method using any of: 'self::otherInstanceMethod',
array('self','otherInstanceMethod'), array(self,'otherInstanceMethod')
succeed.  It appears that (the context for) '$this' is carried over from
the original method, even though the calls are being done statically.



Calling self::otherInstanceMethod() directly also succeeds.  It appears
that methods called from an instance method 'inherit' the context for
$this.  A bit unexpected, but *reasonable*.

Win XP SP3

PHP 5.3.1 (xampp)


[2010-04-12 11:50:33] paj...@php.net

I don't like the optional flag idea. You can disable strictness using
error_reporting already.



However I would like to see this change in trunk, can you come up with a
RFC pls?


[2010-04-10 20:19:45] weierophin...@php.net

@johannes Perhaps an optional strict flag to is_callable() would
address this? 

That would keep BC, while allowing for better checking for = PHP-5
apps. Usage 

would be:



$callback = array('Foo', 'bar');



if (is_callable($callback, true)) {

// Passed strict check

} else {

// failed strict check

}



Thoughts?


[2010-04-10 17:55:25] johan...@php.net

The method can always be called statically. The access to $this might be
forbidden but the method itself can be called. is_callable() doesn't
mean it will execute properly. (the $this error is basically the same as
a call to an undefined funciton in there or such)



To change this the only way would be to forbid calling non-static
methods statically. Maybe this can be done nowadays (we needed the
behavior for PHP 4 compatibility) but that's no bug but requires a RFC
and discussion on internals as this might break quite a few applications
(many PEAR-based things, many legacy applications not fully converted
to PHP 5 )


[2010-04-10 16:43:31] weierophin...@php.net

@pajoye: Yes, this particular example was callable. However, if the
method is 

actually an instance method, and has references to $this, is_callable()
still 

returns true -- making it an invalid test to use to determine whether or
not it's 

safe to then call call_user_func(). Instead, to really determine if the
callback 

is valid, you have to start doing a bunch of reflection -- checking to
see if the 

method is defined and static, or if there is a __callStatic defined that
would 

intercept the call.



That's the more serious implication of the behavior, and why it needs to
be 

fixed.




The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

http://bugs.php.net/bug.php?id=51527


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1


Bug #51527 [Com]: is_callable() returning true for non-static callbacks

2010-05-04 Thread philduby at phriendly dot net
Edit report at http://bugs.php.net/bug.php?id=51527edit=1

 ID:   51527
 Comment by:   philduby at phriendly dot net
 Reported by:  weierophin...@php.net
 Summary:  is_callable() returning true for non-static callbacks
 Status:   Open
 Type: Bug
 Package:  Class/Object related
 Operating System: Linux
 PHP Version:  5.3.2

 New Comment:

Another variation that actually (unexpectedly) works:

Calling is_callable and call_user_func from inside an instance
(non-static) method using any of: 'self::otherInstanceMethod',
array('self','otherInstanceMethod'), array(self,'otherInstanceMethod')
succeed.  It appears that (the context for) '$this' is carried over from
the original method, even though the calls are being done statically.



Calling self::otherInstanceMethod() directly also succeeds.  It appears
that methods called from an instance method 'inherit' the context for
$this.  A bit unexpected, but *reasonable*.

Win XP SP3

PHP 5.3.1 (xampp)


Previous Comments:

[2010-04-12 11:50:33] paj...@php.net

I don't like the optional flag idea. You can disable strictness using
error_reporting already.



However I would like to see this change in trunk, can you come up with a
RFC pls?


[2010-04-10 20:19:45] weierophin...@php.net

@johannes Perhaps an optional strict flag to is_callable() would
address this? 

That would keep BC, while allowing for better checking for = PHP-5
apps. Usage 

would be:



$callback = array('Foo', 'bar');



if (is_callable($callback, true)) {

// Passed strict check

} else {

// failed strict check

}



Thoughts?


[2010-04-10 17:55:25] johan...@php.net

The method can always be called statically. The access to $this might be
forbidden but the method itself can be called. is_callable() doesn't
mean it will execute properly. (the $this error is basically the same as
a call to an undefined funciton in there or such)



To change this the only way would be to forbid calling non-static
methods statically. Maybe this can be done nowadays (we needed the
behavior for PHP 4 compatibility) but that's no bug but requires a RFC
and discussion on internals as this might break quite a few applications
(many PEAR-based things, many legacy applications not fully converted
to PHP 5 )


[2010-04-10 16:43:31] weierophin...@php.net

@pajoye: Yes, this particular example was callable. However, if the
method is 

actually an instance method, and has references to $this, is_callable()
still 

returns true -- making it an invalid test to use to determine whether or
not it's 

safe to then call call_user_func(). Instead, to really determine if the
callback 

is valid, you have to start doing a bunch of reflection -- checking to
see if the 

method is defined and static, or if there is a __callStatic defined that
would 

intercept the call.



That's the more serious implication of the behavior, and why it needs to
be 

fixed.


[2010-04-10 16:29:12] paj...@php.net

It is actually callable. But calling it statically breaks the strict
standards, but the strict standards will break BC in many situations.



I would suggest to make this change in trunk only.




The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

http://bugs.php.net/bug.php?id=51527


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1


Bug #51527 [Com]: is_callable() returning true for non-static callbacks

2010-04-10 Thread weierophin...@php.net
Edit report at http://bugs.php.net/bug.php?id=51527edit=1

 ID:   51527
 Comment by:   weierophin...@php.net
 Reported by:  weierophin...@php.net
 Summary:  is_callable() returning true for non-static callbacks
 Status:   Open
 Type: Bug
 Package:  Class/Object related
 Operating System: Linux
 PHP Version:  5.3.2

 New Comment:

@pajoye: Yes, this particular example was callable. However, if the
method is 

actually an instance method, and has references to $this, is_callable()
still 

returns true -- making it an invalid test to use to determine whether or
not it's 

safe to then call call_user_func(). Instead, to really determine if the
callback 

is valid, you have to start doing a bunch of reflection -- checking to
see if the 

method is defined and static, or if there is a __callStatic defined that
would 

intercept the call.



That's the more serious implication of the behavior, and why it needs to
be 

fixed.


Previous Comments:

[2010-04-10 16:29:12] paj...@php.net

It is actually callable. But calling it statically breaks the strict
standards, but the strict standards will break BC in many situations.



I would suggest to make this change in trunk only.


[2010-04-10 16:07:17] weierophin...@php.net

Description:

is_callable() is returning a false-positive for callbacks that reference
non-

static methods. As an example, if I have defined a class 'Foo' with an
instance 

(i.e., non-static) method 'bar', and define the callback array('Foo',
'bar'), 

is_callable() will falsely return true.



Additionally, if you then pass this callback to call_user_func(), this
latter 

function will actually try to call the method statically -- and raise an


E_STRICT about the callback being invalid. If the method has any
references to 

$this, it then fails with an E_FATAL, but otherwise it will run the
method as if 

it were static.



This behavior is unexpected, and unintuitive. Calling non-static methods
as if 

they were static, even when they do not reference $this, violates
visibility. I 

would expect is_callable() to return false in these instances, and for 

call_user_func() to immediately raise an E_FATAL if the method is not
defined as 

static.

Test script:
---
class Foo

{

public function bar()

{

return 'foo bar';

}

}



$callback = array('Foo', 'bar');

if (is_callable($callback)) {

echo call_user_func($callback);

}

Expected result:

No output.

Actual result:
--
PHP Strict Standards:  call_user_func() expects parameter 1 to be a
valid 

callback, non-static method Foo::bar() should not be called statically



Strict Standards: call_user_func() expects parameter 1 to be a valid
callback, 

non-static method Test\Foo::bar() should not be called statically

foo bar






-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1


Bug #51527 [Com]: is_callable() returning true for non-static callbacks

2010-04-10 Thread weierophin...@php.net
Edit report at http://bugs.php.net/bug.php?id=51527edit=1

 ID:   51527
 Comment by:   weierophin...@php.net
 Reported by:  weierophin...@php.net
 Summary:  is_callable() returning true for non-static callbacks
 Status:   Bogus
 Type: Bug
 Package:  Class/Object related
 Operating System: Linux
 PHP Version:  5.3.2

 New Comment:

@johannes Perhaps an optional strict flag to is_callable() would
address this? 

That would keep BC, while allowing for better checking for = PHP-5
apps. Usage 

would be:



$callback = array('Foo', 'bar');



if (is_callable($callback, true)) {

// Passed strict check

} else {

// failed strict check

}



Thoughts?


Previous Comments:

[2010-04-10 17:55:25] johan...@php.net

The method can always be called statically. The access to $this might be
forbidden but the method itself can be called. is_callable() doesn't
mean it will execute properly. (the $this error is basically the same as
a call to an undefined funciton in there or such)



To change this the only way would be to forbid calling non-static
methods statically. Maybe this can be done nowadays (we needed the
behavior for PHP 4 compatibility) but that's no bug but requires a RFC
and discussion on internals as this might break quite a few applications
(many PEAR-based things, many legacy applications not fully converted
to PHP 5 )


[2010-04-10 16:43:31] weierophin...@php.net

@pajoye: Yes, this particular example was callable. However, if the
method is 

actually an instance method, and has references to $this, is_callable()
still 

returns true -- making it an invalid test to use to determine whether or
not it's 

safe to then call call_user_func(). Instead, to really determine if the
callback 

is valid, you have to start doing a bunch of reflection -- checking to
see if the 

method is defined and static, or if there is a __callStatic defined that
would 

intercept the call.



That's the more serious implication of the behavior, and why it needs to
be 

fixed.


[2010-04-10 16:29:12] paj...@php.net

It is actually callable. But calling it statically breaks the strict
standards, but the strict standards will break BC in many situations.



I would suggest to make this change in trunk only.


[2010-04-10 16:07:17] weierophin...@php.net

Description:

is_callable() is returning a false-positive for callbacks that reference
non-

static methods. As an example, if I have defined a class 'Foo' with an
instance 

(i.e., non-static) method 'bar', and define the callback array('Foo',
'bar'), 

is_callable() will falsely return true.



Additionally, if you then pass this callback to call_user_func(), this
latter 

function will actually try to call the method statically -- and raise an


E_STRICT about the callback being invalid. If the method has any
references to 

$this, it then fails with an E_FATAL, but otherwise it will run the
method as if 

it were static.



This behavior is unexpected, and unintuitive. Calling non-static methods
as if 

they were static, even when they do not reference $this, violates
visibility. I 

would expect is_callable() to return false in these instances, and for 

call_user_func() to immediately raise an E_FATAL if the method is not
defined as 

static.

Test script:
---
class Foo

{

public function bar()

{

return 'foo bar';

}

}



$callback = array('Foo', 'bar');

if (is_callable($callback)) {

echo call_user_func($callback);

}

Expected result:

No output.

Actual result:
--
PHP Strict Standards:  call_user_func() expects parameter 1 to be a
valid 

callback, non-static method Foo::bar() should not be called statically



Strict Standards: call_user_func() expects parameter 1 to be a valid
callback, 

non-static method Test\Foo::bar() should not be called statically

foo bar






-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1