Get name of extending class with static method call (PHP5)

php.internals

Torsten Roehr

21 years ago
Hi devs, after a long discussion on php-general [1], searching the archives and trying every proposed solution without success I'm asking for your help to solve the following problem: class Car { function drive() { // I need the name of the calling class here // in my case it should be 'Porsche' } } class Porsche extends Car { } Porsche::drive(); With PHP4 it was possible to get the correct class name with debug_backtrace(). This behaviour has been changed in PHP5. How can I get the name of the extending class that invoked the method in drive()? Thanks in advance! Best regards, Torsten Roehr [1] http://marc.theaimsgroup.com/?t=110546013200009&r=1&w=2 (following the thread with a news client might be easier)

Johannes Schlueter

21 years ago
> With PHP4 it was possible to get the correct class name with > debug_backtrace(). This behaviour has been changed in PHP5. > How can I get the name of the extending class that invoked the method in > drive()?
There was a short discussion on this on this list, too some month ago. The result was that there is (at least currently) no way to get the right class. My CVS Log tells me that I needed this last April so I think the discussion was around that time, maybe a bit later - if someone wants to search the archives. johannes

Torsten Roehr

21 years ago
"Johannes Schlueter" <johannes@php.net> wrote in message news:20050112161637.86918.qmail@pb1.pair.com...
> > With PHP4 it was possible to get the correct class name with > > debug_backtrace(). This behaviour has been changed in PHP5. > > How can I get the name of the extending class that invoked the method in > > drive()? > > There was a short discussion on this on this list, too some month ago. The > result was that there is (at least currently) no way to get the right > class.
That's what I found out as well while searching the archives. Any more ideas? Something so straightforward and fundamental should be possible!?! Best regards, Torsten Roehr

Christian Schneider

21 years ago
Torsten Roehr wrote:
> Something so straightforward and fundamental should be possible!?!
Maybe is isn't as fundamental as you think? I never came across this problem in years of PHP programming. But then again I use classes with static calls for nothing but separate namespaces :-) I'm pretty sure there is another (possibly more elegant) solution. This is not a flame but a suggestion to rethink the problem you are trying to solve. - Chris

Torsten Roehr

21 years ago
"Christian Schneider" <cschneid@cschneid.com> wrote in message news:41E5790D.2090402@cschneid.com...
> Torsten Roehr wrote: > > Something so straightforward and fundamental should be possible!?! > > Maybe is isn't as fundamental as you think? I never came across this > problem in years of PHP programming. But then again I use classes with > static calls for nothing but separate namespaces :-) > > I'm pretty sure there is another (possibly more elegant) solution. This > is not a flame but a suggestion to rethink the problem you are trying to > solve. > > - Chris
Hi Chris, no problem - not feeling flamed here ;) Maybe I should elaborate a bit more what I'm needing this for. I would like to write a load method in a superclass that can be used by all subclasses. I'm just passing in the SQL statement as a parameter. The load method commits the query, loops through the result set and creates/returns a collection of objects. The method needs to know the name of the class to create objects of this class. Example: $persons = Person::load($sql); // returns collection of Person objects $cars = Car::load($sql); // returns collection of Car objects All classes can use the same load method and the database access (for selects) is only needed in this method and can therefore be changed easily. It's a bit simplified but I hope you get the idea. Also from the heated discussion on php-general you can see that there are quite a few people facing the described problem. Best regards, Torsten Roehr

Christian Schneider

21 years ago
Hey Torsten, Torsten Roehr wrote:
> $persons = Person::load($sql); // returns collection of Person objects > $cars = Car::load($sql); // returns collection of Car objects
Simple solutions: 1) $persons = DB::load('Person', $sql); foreach ($persons as $person)... 2) $person = new Person($sql); while ($person->iterate())... 3) Adding get_class() to all DB classes (like Person) as suggested by Daniel Convissor. Solution 1) is IMHO close enough to your solution. Personally I prefer (and we are using) solution 2) here as it also is more space efficient for large number of results returned from the DB (only one Person object is needed). On top of that we create classes automatically at runtime from DB tables which removed the need to write stub classes (and makes solution 3) feasible again). I suggest that we take this discussion off-line now as it is not really an internals discussion anymore. - Chris

Torsten Roehr

21 years ago
> -----Original Message----- > From: Christian Schneider [mailto:cschneid@cschneid.com] > Sent: Wednesday, January 12, 2005 9:05 PM > To: Torsten Roehr > Cc: internals@lists.php.net > Subject: Re: Get name of extending class with static method call (PHP5) > > > Hey Torsten, > > Torsten Roehr wrote: > > $persons = Person::load($sql); // returns collection of Person objects > > $cars = Car::load($sql); // returns collection of Car objects > > Simple solutions: > 1) $persons = DB::load('Person', $sql); foreach ($persons as $person)... > 2) $person = new Person($sql); while ($person->iterate())... > 3) Adding get_class() to all DB classes (like Person) as suggested by > Daniel Convissor. > > Solution 1) is IMHO close enough to your solution. Personally I prefer > (and we are using) solution 2) here as it also is more space efficient > for large number of results returned from the DB (only one Person object > is needed). On top of that we create classes automatically at runtime > from DB tables which removed the need to write stub classes (and makes > solution 3) feasible again). > > I suggest that we take this discussion off-line now as it is not really > an internals discussion anymore. > > - Chris
Hi Chris, thank you very much for the proposed solutions - I will take them into consideration. But the problem still persists and will come up in different situations, not just in mine. I am keen to hear some more opinions from other gurus on this list. Thank you in advance! Best regards, Torsten Roehr

Andrey Hristov

21 years ago
Christian Schneider wrote:
> Torsten Roehr wrote: > >> Something so straightforward and fundamental should be possible!?! > > > Maybe is isn't as fundamental as you think? I never came across this > problem in years of PHP programming. But then again I use classes with > static calls for nothing but separate namespaces :-) > > I'm pretty sure there is another (possibly more elegant) solution. This > is not a flame but a suggestion to rethink the problem you are trying to > solve. > > - Chris >
Hi Chris, I have faced this limitation of the languagee when I was trying to simplify code which uses Singleton and uses to have n-time the code for caching copied around. Every new class that one subclass has to copy the code. A bit overwork, isn't it? At the end we agreed on a solution with __CLASS__ in the extending classes. class Foo { function getInstanceInt($params, $class_name= __CLASS__) { var_dump($params, $class_name); /*...*/ } } class Bar extends Foo { function getInstance() { Foo::getInstanceInt(func_get_args(), __CLASS__); } } $a= Bar::getInstance(1,2,3); So the getInstance() in the subclasses is quite simple. One also may declare argument names. Here I haven't done that for simplicity. Regards, Andrey

Torsten Roehr

21 years ago
"Andrey Hristov" <php@hristov.com> wrote in message news:41E774CA.8040808@hristov.com...
> Christian Schneider wrote: > > Torsten Roehr wrote: > > > >> Something so straightforward and fundamental should be possible!?! > > > > > > Maybe is isn't as fundamental as you think? I never came across this > > problem in years of PHP programming. But then again I use classes with > > static calls for nothing but separate namespaces :-) > > > > I'm pretty sure there is another (possibly more elegant) solution. This > > is not a flame but a suggestion to rethink the problem you are trying to > > solve. > > > > - Chris > > > Hi Chris, > I have faced this limitation of the languagee when I was trying to
simplify
> code which uses Singleton and uses to have n-time the code for caching > copied around. Every new class that one subclass has to copy the code. A
bit
> overwork, isn't it? At the end we agreed on a solution with __CLASS__ in
the
> extending classes. > > class Foo { > function getInstanceInt($params, $class_name= __CLASS__) { > var_dump($params, $class_name); > /*...*/ > } > } > class Bar extends Foo { > function getInstance() { > Foo::getInstanceInt(func_get_args(), __CLASS__); > } > } > $a= Bar::getInstance(1,2,3); > > So the getInstance() in the subclasses is quite simple. One also > may declare argument names. Here I haven't done that for simplicity. > > Regards, > Andrey
Hi Andrey, thanks for your posts. It seems that this is the only viable solution - passing the class name in as a parameter. Thanks and best regards, Torsten Roehr

Daniel Convissor

21 years ago
Torsten: On Wed, Jan 12, 2005 at 04:58:20PM +0100, Torsten Roehr wrote:
> How can I get the name of the extending class that invoked the method in > drive()?
class Car { function drive($child) { echo "parent driven in a $child\n"; } } class Porsche extends Car { function drive() { parent::drive(get_class()); } } Porsche::drive(); --Dan
-- T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y data intensive web and database programming http://www.AnalysisAndSolutions.com/ 4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409

Torsten Roehr

21 years ago
"Daniel Convissor" <danielc@analysisandsolutions.com> wrote in message news:20050112173425.GA1234@panix.com...
> Torsten: > > On Wed, Jan 12, 2005 at 04:58:20PM +0100, Torsten Roehr wrote: > > > How can I get the name of the extending class that invoked the method in > > drive()? > > class Car { > function drive($child) { > echo "parent driven in a $child\n"; > } > } > > class Porsche extends Car { > function drive() { > parent::drive(get_class()); > } > } > > Porsche::drive(); > > --Dan
Hi Dan, thanks for your answer. I know about this solution - but it requires the definition of drive() in *every* subclass. An alternative would be passing in the class name as a parameter: class Car { function drive($className) { echo 'parent driven in a $className'; } } class Porsche extends Car { } Porsche::drive('Porsche'); But this seems kind of stupid, doesn't it? Best regards, Torsten Roehr

Unnamed Person

21 years ago
"Torsten Roehr" <roehr@zilleon.com> writes:
> Hi devs, > > after a long discussion on php-general [1], searching the archives and > trying every proposed solution without success I'm asking for your help to > solve the following problem: > > class Car { > function drive() { > // I need the name of the calling class here > // in my case it should be 'Porsche' > } > } > > class Porsche extends Car { > } > > Porsche::drive();
You're previous thread says that you want drive() to be static, but you're not declaring it static. If it needn't be static, then you can do this: class Car { function drive() { echo get_class($this) . "\n"; } } class Porsche extends Car { } $carType = new Porsche(); $carType->drive();

Torsten Roehr

21 years ago
> -----Original Message----- > From: Derrell.Lipman@UnwiredUniverse.com > [mailto:Derrell.Lipman@UnwiredUniverse.com] > Sent: Wednesday, January 12, 2005 6:35 PM > To: Torsten Roehr > Cc: internals@lists.php.net > Subject: Re: [PHP-DEV] Get name of extending class with static method > call(PHP5) > > > "Torsten Roehr" <roehr@zilleon.com> writes: > > > Hi devs, > > > > after a long discussion on php-general [1], searching the archives and > > trying every proposed solution without success I'm asking for > your help to > > solve the following problem: > > > > class Car { > > function drive() { > > // I need the name of the calling class here > > // in my case it should be 'Porsche' > > } > > } > > > > class Porsche extends Car { > > } > > > > Porsche::drive(); > > You're previous thread says that you want drive() to be static, > but you're not > declaring it static. If it needn't be static, then you can do this: > > class Car > { > function drive() > { > echo get_class($this) . "\n"; > } > } > > class Porsche extends Car > { > } > > $carType = new Porsche(); > $carType->drive();
Hi Derrell, you are right, but I just forgot to declare it static. Unfortunately this doesn't change the situation - I still need it as a static call and therefore cannot use get_class(). Best regards, Torsten Roehr

Andrey Hristov

21 years ago
Hi, one may use __CLASS__ instead of get_class(). Andrey Torsten Roehr wrote: