$this assignment and call_user_func question

php.internals

Greg Beaver

23 years ago
Hi, I've heard rumors that there are plans to take away the ability to assign to $this in php 5. If this is true, I would like to place a vote to keep it, as it can be very useful in conjunction with __call()/__get()/__set() to implement run-time aggregation seamlessly In addition, will call_user_func() support static methods before 1.0? call_user_func('class::method', $args); Regards, Greg
-- phpDocumentor http://www.phpdoc.org

(Marcus Börger)

23 years ago
Hello Greg, Wednesday, July 16, 2003, 12:08:29 AM, you wrote: GB> Hi, GB> I've heard rumors that there are plans to take away the ability to GB> assign to $this in php 5. If this is true, I would like to place a vote GB> to keep it, as it can be very useful in conjunction with GB> __call()/__get()/__set() to implement run-time aggregation seamlessly Why do you want to trick yourself and the engine? Can't you find a correct solution? Best regards, Marcus mailto:helly@php.net

Melvyn Sopacua

23 years ago
Hi Marcus, On Wednesday 16 July 2003 00:11, Marcus Börger wrote:
> Wednesday, July 16, 2003, 12:08:29 AM, you wrote: > > GB> Hi, > > GB> I've heard rumors that there are plans to take away the ability to > GB> assign to $this in php 5. If this is true, I would like to place a > vote GB> to keep it, as it can be very useful in conjunction with > GB> __call()/__get()/__set() to implement run-time aggregation seamlessly > > Why do you want to trick yourself and the engine? Can't you find a correct > solution?
I'm not farmiliar with the example Greg is getting at, but the following bit me recently: class DomFromString extends DomDocument { function DomFromString($string) { $this = domxml_open_mem($string); } function foo() { echo('foo'); } } $doc = new DomFromString($xml); $Root = $doc->document_element(); var_dump($doc, $Root); echo($doc->foo()); // call to undefined function I'm farmiliar with the trick-element of this code and why it won't work, but the way to do something similar now, is to *not* extend the extension provided class, use a $this->real_instance and provide methods that re-route the already existing methods to $this->real_instance. Unless there's something I'm missing, I find the latter solution has a much larger trick element and adds a lot of unnecessary typing. Note that the goal here, is to extend a class of which may not have the source (or the time/ability to modify it) AND override it's constructor or the constructor is provided by a function, rather than 'new' principle.
> Marcus mailto:helly@php.net
-- Melvyn

(Marcus Börger)

23 years ago
Hello Melvyn, Wednesday, July 16, 2003, 1:27:52 AM, you wrote: MS> Hi Marcus, MS> On Wednesday 16 July 2003 00:11, Marcus Börger wrote:
>> Wednesday, July 16, 2003, 12:08:29 AM, you wrote: >> >> GB> Hi, >> >> GB> I've heard rumors that there are plans to take away the ability to >> GB> assign to $this in php 5. If this is true, I would like to place a >> vote GB> to keep it, as it can be very useful in conjunction with >> GB> __call()/__get()/__set() to implement run-time aggregation seamlessly >> >> Why do you want to trick yourself and the engine? Can't you find a correct >> solution?
MS> I'm not farmiliar with the example Greg is getting at, but the following bit MS> me recently: MS> class DomFromString extends DomDocument MS> { MS> function DomFromString($string) MS> { MS> $this = domxml_open_mem($string); MS> } This should be a factory patter...static function ...return domxml_open... MS> function foo() MS> { MS> echo('foo'); MS> } MS> } MS> $doc = new DomFromString($xml); $Root = $doc->>document_element(); MS> var_dump($doc, $Root); echo($doc->>foo()); // call to undefined function MS> I'm farmiliar with the trick-element of this code and why it won't work, but MS> the way to do something similar now, is to *not* extend the extension MS> provided class, use a $this->real_instance and provide methods that re-route MS> the already existing methods to $this->real_instance. MS> Unless there's something I'm missing, I find the latter solution has a much MS> larger trick element and adds a lot of unnecessary typing. MS> Note that the goal here, is to extend a class of which may not have the source MS> (or the time/ability to modify it) AND override it's constructor or the MS> constructor is provided by a function, rather than 'new' principle. You can of course overwrite the constructor in a derived class and all. So you are missing the possibility to exchange the contants of a dom clas, that's all you do this tricky stuff for? Best regards, Marcus mailto:helly@php.net

Melvyn Sopacua

23 years ago
Hi again, On Wednesday 16 July 2003 10:01, Marcus Börger wrote: [ ... ]
> MS> I'm not farmiliar with the example Greg is getting at, but the > following bit MS> me recently: > MS> class DomFromString extends DomDocument > MS> { > MS> function DomFromString($string) > MS> { > MS> $this = domxml_open_mem($string); > MS> } > This should be a factory patter...static function ...return domxml_open...
Which returns a domxml object, without method 'foo'.
> MS> Note that the goal here, is to extend a class of which may not have the > source MS> (or the time/ability to modify it) AND override it's > constructor or the MS> constructor is provided by a function, rather than > 'new' principle. > > > You can of course overwrite the constructor in a derived class and all.
How would you know how to write the parents' constructor, if it's opaque? If the constructor creates a resource, how would you mimmick this in PHP?
> So > you are missing the possibility to exchange the contants of a dom clas, > that's all you do this tricky stuff for?
The dom class is an example, but let's not focus on dom here. It does illustrate the problem however, because the constructor for a string based DomDocument is the PHP_FUNCTION(xmldoc). Which means, the following does not work: class DomFromString extends DomDocument { function foo() { echo('foo'); } } $dom = new DomFromString($xml); var_dump($dom); This is because there are three *function* constructors, which do something usefull, which are returning the same object. I really don't see a way, to extend this object. The primary reason is: BC, missing methods, adding convenience methods. Since PHP5 should also give a boost to PECL, I think there should be a way to extend a C-based class, somehow. I really don't favor the $this assignment as well, but what other option is there? Or is this specifick for the way the domxml module is setup, and people shouldn't write their classes like that?
-- Melvyn

(Marcus Börger)

23 years ago
Hello Melvyn, Wednesday, July 16, 2003, 12:00:43 PM, you wrote: MS> Hi again, MS> Since PHP5 should also give a boost to PECL, I think there should be a way to MS> extend a C-based class, somehow. I really don't favor the $this assignment as MS> well, but what other option is there? Or is this specifick for the way the MS> domxml module is setup, and people shouldn't write their classes like that? I really can't follow you...it's all to weird. anyway maybe you have a problem with the domxml class. Maybe you don't understand oo at all, i don't know. The one thing i can think of is that you try to overcome th oo principle of 'is-a' what is a bad idea. I think you need to use 'has-a' instead. class bla { prublic $dom; function __construct() { $dom = new .... } } and then youse proxies. As i can read in your comments it seems you to lazy to write the necessary proxies. Well we don't have aggregation any longer with php5 and we don't have delegation at all. Maybe that is your real problem.
-- Best regards, Marcus mailto:helly@php.net

Melvyn Sopacua

23 years ago
Hi Marcus, On Wednesday 16 July 2003 12:14, Marcus Börger wrote:
> MS> Since PHP5 should also give a boost to PECL, I think there should be a > way to MS> extend a C-based class, somehow. I really don't favor the $this > assignment as MS> well, but what other option is there? Or is this > specifick for the way the MS> domxml module is setup, and people shouldn't > write their classes like that? > > I really can't follow you...it's all to weird. > anyway maybe you have a problem with the domxml class. Maybe you don't > understand oo at all, i don't know.
There are surely things I don't understand, but this isn't one of them.
> The one thing i can think of is that you try to overcome th oo principle of > 'is-a' what is a bad idea.
Yep, that's exactly what I was trying to do. A shame you feel it's a bad idea, as it allows code to remain dynamic.
> class bla { > prublic $dom; > function __construct() { > $dom = new .... > } > } > > and then youse proxies. As i can read in your comments it seems you to lazy > to write the necessary proxies.
Lazyness is one motivation I won't deny. Another is excessive code - it seems like a complete waste to me. A third is, it won't be forwards compatible. I will have to sync the proxies, with whatever methods are added/changed on the original object.
-- Melvyn

(Marcus Börger)

23 years ago
Hello Melvyn, Wednesday, July 16, 2003, 12:44:32 PM, you wrote: MS> Hi Marcus, MS> On Wednesday 16 July 2003 12:14, Marcus Börger wrote:
>> MS> Since PHP5 should also give a boost to PECL, I think there should be a >> way to MS> extend a C-based class, somehow. I really don't favor the $this >> assignment as MS> well, but what other option is there? Or is this >> specifick for the way the MS> domxml module is setup, and people shouldn't >> write their classes like that? >> >> I really can't follow you...it's all to weird. >> anyway maybe you have a problem with the domxml class. Maybe you don't >> understand oo at all, i don't know.
MS> There are surely things I don't understand, but this isn't one of them.
>> The one thing i can think of is that you try to overcome th oo principle of >> 'is-a' what is a bad idea.
MS> Yep, that's exactly what I was trying to do. A shame you feel it's a bad idea, MS> as it allows code to remain dynamic.
>> class bla { >> prublic $dom; >> function __construct() { >> $dom = new .... >> } >> } >> >> and then youse proxies. As i can read in your comments it seems you to lazy >> to write the necessary proxies.
MS> Lazyness is one motivation I won't deny. Another is excessive code - it seems MS> like a complete waste to me. A third is, it won't be forwards compatible. I MS> will have to sync the proxies, with whatever methods are added/changed on the MS> original object. In this case: a) Overcoming 'is-a' is no option at all. b) Propably we have to discuss aggregation/delegation once again. Feel free to do a RFC on those.
-- Best regards, Marcus mailto:helly@php.net

Stefan Walk

23 years ago
On Tue, Jul 15, 2003 at 06:08:29PM -0400, Greg Beaver wrote:
> In addition, will call_user_func() support static methods before 1.0? > call_user_func('class::method', $args);
call_user_func(array('class','method'), $args); Should work.
-- Regards, Stefan Walk <swalk@prp0.prp.physik.tu-darmstadt.de>

Timm Friebe

23 years ago
On Wed, 2003-07-16 at 00:08, Greg Beaver wrote:
> Hi,
[...] As Marcus already replied on this part and as I agree, I'll leave out any comments:)
> In addition, will call_user_func() support static methods before 1.0? > call_user_func('class::method', $args);
This is already supported (in PHP4). Simply use array("class", "method") for the first argument instead of array($instance, "method"). thekid@friebes:~ > php -r 'class Foo { function bar($arg) { var_dump($arg, $this); echo "--\n"; }} call_user_func(array("Foo", "bar"), "static"); call_user_func(array(new Foo(), "bar"), "non-static");' string(6) "static" NULL
-- string(10) "non-static" object(foo)(0) { } -- $this is NULL for the call via array("Foo", "bar") - meaning this method has been called statically. thekid@friebes:~ > php -v PHP 4.3.1 (cli) (built: Feb 23 2003 20:37:24) Copyright (c) 1997-2002 The PHP Group Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies - Timm