call_user_func, static calls, and $this

php.internals

Brad Bulger

23 years ago
this is old subject everyone is tired of i'm sure. but since large changes have been made to call_user_func[_array] recently, i want to confirm: if an object calls one of its methods ($thing->foo()), any static-type method calls made inside there - self::a(), parent::a(), fezbar::a() - will have $this defined, pointing to original calling object. self:: and parent:: are always relative to the containing class, regardless of this. two exceptions: - the method is declared as 'static'; if so, $this is never set - the method is called via call_user_func or call_user_func_array; if so, $this is not set the very last part seems like it *might* be a bug, or it might be a decision - that call_user_func(array('class','function'),$arg) will always force class::function() to behave as if declared statically. that is a bit of a problem for self:: and parent:: but that is ok if it is how it must be. if anyone can say about this, it would be kind. ps - i looked in old mail, sure this had been discussed - topic came up, but nothing for sure, except introduction of 'static' to prevent $this, which solves opposite problem :)

(Marcus Börger)

23 years ago
Hello Brad, Wednesday, August 13, 2003, 8:40:37 AM, you wrote: BB> this is old subject everyone is tired of i'm sure. but since large changes BB> have been made to call_user_func[_array] recently, i want to confirm: BB> if an object calls one of its methods ($thing->foo()), any static-type BB> method calls made inside there - self::a(), parent::a(), fezbar::a() - BB> will have $this defined, pointing to original calling object. BB> self:: and parent:: are always relative to the containing class, BB> regardless of this. BB> two exceptions: BB> - the method is declared as 'static'; if so, $this is never set BB> - the method is called via call_user_func or call_user_func_array; BB> if so, $this is not set BB> the very last part seems like it *might* be a bug, or it might be a BB> decision - that call_user_func(array('class','function'),$arg) BB> will always force class::function() to behave as if declared statically. BB> that is a bit of a problem for self:: and parent:: but that is ok if it BB> is how it must be. BB> if anyone can say about this, it would be kind. BB> ps - i looked in old mail, sure this had been discussed - topic came up, BB> but nothing for sure, except introduction of 'static' to prevent $this, BB> which solves opposite problem :) It is very simple: If this is defined in a static method it is a language error. However when mentioning this problem the acronym BC often gets used for what ever reason. I mean the idea of the new OO model was to have OO in php at least, wasn't it ? If this isn't defined in a dynamic (non static) method that it is obviously an error that can't be discussed away. Not even with BC reasons. Best regards, Marcus mailto:helly@php.net

Brad Bulger

23 years ago
Marcus Börger wrote:
> It is very simple:
uh oh. :)
> > If this is defined in a static method it is a language error. However when > mentioning this problem the acronym BC often gets used for what ever reason. I > mean the idea of the new OO model was to have OO in php at least, wasn't it ?
i can't say. you want to be able to call parent::method() and have $this available there, for sure. it is not truly a static call, it is just syntax that looks like static, i think. (but for sure i don't know!) 'static' modifier to function def was added, if i read archive right, for the reason you say. (though 'static function bar()' has no $this whether called as class::bar(), $x->bar(), or $this->bar() - so not really about how it is called, more about what it is.)
> If this isn't defined in a dynamic (non static) method that it is obviously an > error that can't be discussed away. Not even with BC reasons.
this is why i ask. whether method is effectively dynamic or effectively static depends on circumstances. it is tricky, for me to understand at least. (not hard thing to accomplish...)

(Marcus Börger)

23 years ago
Hello Brad, Wednesday, August 13, 2003, 9:51:23 AM, you wrote: BB> i can't say. you want to be able to call parent::method() and have $this BB> available there, for sure. it is not truly a static call, it is just syntax BB> that looks like static, i think. (but for sure i don't know!) 'static' BB> modifier to function def was added, if i read archive right, for the reason BB> you say. (though 'static function bar()' has no $this whether called as class::bar(), $x->>bar(), or $this->bar() - so not really about how it is BB> called, more about what it is.) parent::method() is static / dynamic if parent::method() is defined as static / dynamic. We do not distinguish by call but instead by method definition. marcus

Brad Bulger

23 years ago
semi-related: __call is somewhat reversed. it will catch call_user_func(array('self','fake')), but not self::fake() (same for parent vs parent:: or randomclass vs randomclass::) the visibility of $this is not changed, so you end up with no $this inside __call. it can be a surprise.

Zeev Suraski

23 years ago
At 09:40 13/08/2003, Brad Bulger wrote:
>if an object calls one of its methods ($thing->foo()), any static-type >method calls made inside there - self::a(), parent::a(), fezbar::a() - >will have $this defined, pointing to original calling object. >self:: and parent:: are always relative to the containing class, >regardless of this. > >two exceptions: > >- the method is declared as 'static'; if so, $this is never set > >- the method is called via call_user_func or call_user_func_array; > if so, $this is not set
This should be fixed. $this should be visible for methods invoked through call_user_function(). And you're absolutely right about your analysis of the :: operator. Contrary to popular belief it was NOT introduced for static function calls, but rather, for being able to invoke methods of parent classes (a much more common use for the :: operator in other languages too). Zeev