|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-12-04 09:11 UTC] dkr at mindwerk dot de
Description:
------------
I don't really understand the following situation.. Made some comments in the code to explain it. There is something wrong with class and Object scopes: calling a non-static function of another class inside an object will cause __call (in dependence of existence in the other class) to different behaviors when using self:: instead of __CLASS__ in the non-static method.
Reproduce code:
---------------
<?php
class Foo
{
function __call($f,$a)
{
die("__called!\n");
}
function write($text) {
echo($text);
}
// defining debug as static will cause
// the whole thing to work properly
function debug($text) {
return call_user_func_array(
// "self" acts like making a lookup in
// class Bar, fails and then runs the
// magic method in this class, but why?
// i dont have extended the Bar class...
// __CLASS__ will work, but dont work for
// extended classes, as self should do it
array(self,'write'),
array($text,1)
);
}
}
class Bar {
function __construct()
{
Foo::debug("foobar\n");
}
// uncomment the following to make Foo::debug()
// throw the text foobar, ehm? note that we do NOT
// echo any content here... that is something like
// inheritance it should not do? will echo "foobar"..
/*
function __call($f,$a)
{
}
*/
}
$bar = new Bar(); // will cause php to die
Expected result:
----------------
foobar
Actual result:
--------------
__called!
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Dec 29 13:00:01 2025 UTC |
No, that is NOT BOGUS i think, there is something went wrong, and it took me quite a while finding the error in the app (using strace etc), and quite a while yet to reproduce this behavior with a small code snippet that will SEGFAULT. Note: Currently only tested on 5.2.11 and 5.2.0-8+etch15 Reproduce code: --------------- <?php class Foo { function __call($f,$a) { echo("__call activated on class: ".__CLASS__.PHP_EOL); } function write($text) { echo( 'Foo: '.$text.PHP_EOL ); } function debug($text) { return call_user_func_array( array(self,'write'), array($text,1) ); } } class Bar { function __construct() { Foo::debug("foobar"); } } class Baz { function __construct() { Foo::debug("foobar"); } // here he dies... function __call($f,$a) { echo("__call activated on class: ".__CLASS__.PHP_EOL); } } $bar = new Bar(); $baz = new Baz(); // will cause php to die ?> Expected result: ---------------- 1. Calling non-static function Foo::debug() in Bar::__construct() a) should throw an function not found error while "self::" is used, as the engine does a lookup in Bar and does not find any function. b) should not make the usage of Foo::__call() as it does not interact in the scope of Class Foo finally? 2. Calling Foo::debug() in Baz::__construct() in Baz::__construct() a) should use __call as it is defined in Baz, and should rely on the scope of this class and not the non static called class Foo.. Uncomment Foo::__call to let the whole thing get more weird, as the text "Baz::foobar" is normally echoed if Baz::__call is only defined there (only defined!) b) should never make the usage of Foo::call() as it does not interact in the scope of Class Foo finally? Actual result: -------------- dkr@*:~$ php test.php __call activated on class: Foo Segmentation fault dkr@*:~$ Actual result without Foo::__call(): ------------------------------------ dkr@*:~$ php phptest.php PHP Warning: call_user_func_array(): Unable to call self::write() in * on line * Foo: foobar dkr@*:~$__call activated on class: Foo Warning: String is not zero-terminated (ZZZZZZ���) (source: /home/felipe/dev/php5_2/Zend/zend_execute_API.c:414) in /home/felipe/dev/bug.php on line 15 [Tue Dec 8 14:59:22 2009] Script: '../bug.php' --------------------------------------- /home/felipe/dev/php5_2/Zend/zend_execute_API.c(414) : Block 0x08b757f0 status: /home/felipe/dev/php5_2/Zend/zend_variables.c(35) : Actual location (location was relayed) Beginning: Cached Freed (invalid) Start: OK End: OK --------------------------------------- Foo: foobar [Tue Dec 8 14:59:22 2009] Script: '../bug.php' /home/felipe/dev/php5_2/Zend/zend_object_handlers.c(767) : Freeing 0x08B75B80 (44 bytes), script=../bug.php [Tue Dec 8 14:59:22 2009] Script: '../bug.php' /home/felipe/dev/php5_2/Zend/zend_object_handlers.c(775) : Freeing 0x08B75E7C (6 bytes), script=../bug.php === Total 2 memory leaks detected ===Hm, i just think that this is an endless loop that should throw any error like "max function nesting reached" or something. The following codes are 2 easier examples that will fault: Reproduce code #1: ------------------ <?php class Foo { static function __call($f,$a) { static $call = 0; test(); } } function test() { call_user_func_array(array('Foo','__call'),array(0,array())); } test(); ?> Reproduce code #2: ------------------ <?php function Bar() { Foo(); } function Foo() { Bar(); } Foo(); ?> Expected result: ---------------- Fatal Error: Maximum calls of nested functions reached in ... on line ... Actual result: -------------- Segmentation fault