Reflection API

php.internals

George Schlossnagle

23 years ago
Here is a first implementation of the reflection api, for functions (class PHP_Function in you diagram) http://www.schlossnagle.org/~george/php/reflection.diff http://www.schlossnagle.org/~george/php/zend_reflection_api.c http://www.schlossnagle.org/~george/php/zend_reflection_api.h Comments? Thoughts? George On Wednesday, June 18, 2003, at 12:53 PM, Sebastian Bergmann wrote:
> Sebastian Bergmann wrote: >> http://www.sebastian-bergmann.de/stuff/reflection.png > > I refactored it a bit: > > http://www.sebastian-bergmann.de/stuff/reflection-update.png > > IMHO it is essential that PHP_Field and PHP_Method implement a > common interface (like their counterparts from java.lang.reflect do) > to ease iterating through a class's members, for instance. > > -- > Sebastian Bergmann > http://sebastian-bergmann.de/ > http://phpOpenTracker.de/ > > http://www.professionelle-softwareentwicklung-mit-php5.de/ > > -- > PHP 5 Development Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- George Schlossnagle -- Principal Consultant -- OmniTI Computer Consulting, Inc. -- +1.410.872.4910 x202 -- 1024D/1100A5A0 1370 F70A 9365 96C9 2F5E 56C2 B2B9 262F 1100 A5A0

Andi Gutmans

23 years ago
I must be thick. I don't quite understand how the source relates to what is described in the .png. Take for example the following from the api.c file: static zend_function_entry php_function_functions[] = { ZEND_FE(php_function, NULL) ZEND_FE(php_function_isinternal, NULL) ZEND_FALIAS(isinternal, php_function_isinternal, NULL) ZEND_FE(php_function_isuserdefined, NULL) ZEND_FALIAS(isuserdefined, php_function_isinternal, NULL) ZEND_FE(php_function_getname, NULL) ZEND_FALIAS(getname, php_function_getname, NULL) ZEND_FE(php_function_getfilename, NULL) ZEND_FALIAS(getfilename, php_function_getfilename, NULL) ZEND_FE(php_function_getstartline, NULL) ZEND_FALIAS(getstartline, php_function_getstartline, NULL) ZEND_FE(php_function_getendline, NULL) ZEND_FALIAS(getendline, php_function_getendline, NULL) ZEND_FE(php_function_getdoccomment, NULL) ZEND_FALIAS(getdoccomment, php_function_getdoccomment, NULL) ZEND_FE(php_function_getstaticvariables, NULL) ZEND_FALIAS(getstaticvariables, php_function_getstaticvariables, NULL) ZEND_FE(php_function_invoke, NULL) ZEND_FALIAS(invoke, php_function_invoke, NULL) {NULL, NULL, NULL} Are these functions meant to be called by the user? They are *pretty* ugly. Can you show a small piece of example code on how this reflection API is supposed to be used? Once we make sure it looks good to everyone I have no problem with you commiting your work. Andi At 03:18 PM 29/6/2003 -0400, George Schlossnagle wrote:

George Schlossnagle

23 years ago
On Monday, June 30, 2003, at 12:04 PM, Andi Gutmans wrote:
> I must be thick. I don't quite understand how the source relates to > what is described in the .png. Take for example the following from the > api.c file:
I talked this over with Marcus. The FE/FALIAS pairs are designed to avoid namespace conflicts with the other (not yet existent) reflection classes. I better solution will be to write a new macro that allows ZEND_FUNCTION(php_function_getstartline) to be registered as a class method directly as 'getstartline). I'll modify my patch shortly. If something like that exists already, a pointer to it would be swell. Otherwise the functions work as follows: <?php /** Doc comment goes here */ function counter() { static $i = 0; return $i++; } $obj = new PHP_Function("counter"); print $obj->getName()." was decared in ".$obj->getFileName()." starting at ".$obj->getStartLine(). "and ending at ".$obj->getEndline."\n"; print "Here is what it's docs have to say: "$obj->getDocComment(). "\n"; if($statics = $obj->staticVariables()) { print $obj->getName()." has the following static variables:\n".print_r($statics); } print $obj->invoke(); Something like that.
> > static zend_function_entry php_function_functions[] = { > ZEND_FE(php_function, NULL) ZEND_FE(php_function_isinternal, NULL) > ZEND_FALIAS(isinternal, php_function_isinternal, NULL) > ZEND_FE(php_function_isuserdefined, NULL) ZEND_FALIAS(isuserdefined, > php_function_isinternal, NULL) ZEND_FE(php_function_getname, NULL) > ZEND_FALIAS(getname, php_function_getname, NULL) > ZEND_FE(php_function_getfilename, NULL) ZEND_FALIAS(getfilename, > php_function_getfilename, NULL) ZEND_FE(php_function_getstartline, > NULL) ZEND_FALIAS(getstartline, php_function_getstartline, NULL) > ZEND_FE(php_function_getendline, NULL) ZEND_FALIAS(getendline, > php_function_getendline, NULL) ZEND_FE(php_function_getdoccomment, > NULL) ZEND_FALIAS(getdoccomment, php_function_getdoccomment, NULL) > ZEND_FE(php_function_getstaticvariables, NULL) > ZEND_FALIAS(getstaticvariables, php_function_getstaticvariables, NULL) > ZEND_FE(php_function_invoke, NULL) ZEND_FALIAS(invoke, > php_function_invoke, NULL) {NULL, NULL, NULL} > > > Are these functions meant to be called by the user? They are *pretty* > ugly. > Can you show a small piece of example code on how this reflection API > is supposed to be used? > Once we make sure it looks good to everyone I have no problem with you > commiting your work. > > Andi > > At 03:18 PM 29/6/2003 -0400, George Schlossnagle wrote: >> Here is a first implementation of the reflection api, for functions >> (class PHP_Function in you diagram) >> >> http://www.schlossnagle.org/~george/php/reflection.diff >> http://www.schlossnagle.org/~george/php/zend_reflection_api.c >> http://www.schlossnagle.org/~george/php/zend_reflection_api.h >> >> Comments? Thoughts? >> George >> >> >> On Wednesday, June 18, 2003, at 12:53 PM, Sebastian Bergmann wrote: >> >>> Sebastian Bergmann wrote: >>>> http://www.sebastian-bergmann.de/stuff/reflection.png >>> >>> I refactored it a bit: >>> >>> http://www.sebastian-bergmann.de/stuff/reflection-update.png >>> >>> IMHO it is essential that PHP_Field and PHP_Method implement a >>> common interface (like their counterparts from java.lang.reflect >>> do) >>> to ease iterating through a class's members, for instance. >>> >>> -- >>> Sebastian Bergmann >>> http://sebastian-bergmann.de/ >>> http://phpOpenTracker.de/ >>> >>> http://www.professionelle-softwareentwicklung-mit-php5.de/ >>> >>> -- >>> PHP 5 Development Mailing List (http://www.php.net/) >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >> -- George Schlossnagle >> -- Principal Consultant >> -- OmniTI Computer Consulting, Inc. >> -- +1.410.872.4910 x202 >> -- 1024D/1100A5A0 1370 F70A 9365 96C9 2F5E 56C2 B2B9 262F 1100 A5A0 >> >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php > >
-- George Schlossnagle -- Principal Consultant -- OmniTI Computer Consulting, Inc. -- +1.410.872.4910 x202 -- 1024D/1100A5A0 1370 F70A 9365 96C9 2F5E 56C2 B2B9 262F 1100 A5A0

George Schlossnagle

23 years ago
On Monday, June 30, 2003, at 11:32 AM, George Schlossnagle wrote:
> On Monday, June 30, 2003, at 12:04 PM, Andi Gutmans wrote: > >> I must be thick. I don't quite understand how the source relates to >> what is described in the .png. Take for example the following from >> the api.c file: > > I talked this over with Marcus. The FE/FALIAS pairs are designed to > avoid namespace conflicts with the other (not yet existent) reflection > classes. I better solution will be to write a new macro that allows > ZEND_FUNCTION(php_function_getstartline) to be registered as a class > method directly as 'getstartline). I'll modify my patch shortly. If > something like that exists already, a pointer to it would be swell.
A look in sqlite answered my question - I should be using ZEND_NAMED_FE. Will update patch momentarily.

George Schlossnagle

23 years ago
On Monday, June 30, 2003, at 11:35 AM, George Schlossnagle wrote:
> A look in sqlite answered my question - I should be using > ZEND_NAMED_FE. Will update patch momentarily.
Updated now. -- George Schlossnagle -- Principal Consultant -- OmniTI Computer Consulting, Inc. -- +1.410.872.4910 x202 -- 1024D/1100A5A0 1370 F70A 9365 96C9 2F5E 56C2 B2B9 262F 1100 A5A0

Andi Gutmans

23 years ago
At 11:44 AM 30/6/2003 -0400, George Schlossnagle wrote:
>On Monday, June 30, 2003, at 11:35 AM, George Schlossnagle wrote: >>A look in sqlite answered my question - I should be using >>ZEND_NAMED_FE. Will update patch momentarily. > >Updated now.
I still get the old .diff via the URL you posted. Can you please update it? Also, we should decide if we want to break the PHP function naming convention here. I assume most OO developers would prefer to write $obj->getName(), however, according to PHP standards it should be $obj->get_name(); In addition, as the engine is self-contained I think it would be better not to use PHP_ in the reflection API, i.e., instead of PHP_Function it would probably be nicer to use Reflection_Function or something similar. Let's finalize these issues and then personally I think we can go ahead and commit. Andi

George Schlossnagle

23 years ago
On Monday, June 30, 2003, at 02:48 PM, Andi Gutmans wrote:
> At 11:44 AM 30/6/2003 -0400, George Schlossnagle wrote: >> On Monday, June 30, 2003, at 11:35 AM, George Schlossnagle wrote: >>> A look in sqlite answered my question - I should be using >>> ZEND_NAMED_FE. Will update patch momentarily. >> >> Updated now. > > I still get the old .diff via the URL you posted. Can you please > update it?
The diff should be the same, since zend_reflection_api.[ch] aren't in cvs, they don't appear in the diff. They are there in their entirety as http://www.schlossnagle.org/~george/php/zend_reflection_api.c etc.
> > Also, we should decide if we want to break the PHP function naming > convention here. I assume most OO developers would prefer to write > $obj->getName(), however, according to PHP standards it should be > $obj->get_name();
I was under the impression that there was tacit agreement that moving forward OO extensions would use PEAR standard naming, while procedural would use classic PHP style. That's the way Exception is.
> > In addition, as the engine is self-contained I think it would be > better not to use PHP_ in the reflection API, i.e., instead of > PHP_Function it would probably be nicer to use Reflection_Function or > something similar.
Okee dokee. Will be up by the time you get this mail.
> > Let's finalize these issues and then personally I think we can go > ahead and commit.
Okee dokee. george

Andi Gutmans

23 years ago
At 02:01 PM 30/6/2003 -0400, George Schlossnagle wrote:
>On Monday, June 30, 2003, at 02:48 PM, Andi Gutmans wrote: > >>At 11:44 AM 30/6/2003 -0400, George Schlossnagle wrote: >>>On Monday, June 30, 2003, at 11:35 AM, George Schlossnagle wrote: >>>>A look in sqlite answered my question - I should be using >>>>ZEND_NAMED_FE. Will update patch momentarily. >>> >>>Updated now. >> >>I still get the old .diff via the URL you posted. Can you please update it? > >The diff should be the same, since zend_reflection_api.[ch] aren't in cvs, >they don't appear in the diff. They are there in their entirety as >http://www.schlossnagle.org/~george/php/zend_reflection_api.c etc.
Yeah I know but they aren't updated with the ZE_FNAME() change you said you're doing :)
>>Also, we should decide if we want to break the PHP function naming >>convention here. I assume most OO developers would prefer to write >>$obj->getName(), however, according to PHP standards it should be >>$obj->get_name(); > >I was under the impression that there was tacit agreement that moving >forward OO extensions would use PEAR standard naming, while procedural >would use classic PHP style. That's the way Exception is.
I don't remember such an agreement but as I prefer the getName() syntax I won't argue :) If anyone disagrees, speak now or keep silent forever.
>>In addition, as the engine is self-contained I think it would be better >>not to use PHP_ in the reflection API, i.e., instead of PHP_Function it >>would probably be nicer to use Reflection_Function or something similar. > >Okee dokee. Will be up by the time you get this mail.
Cool.
>>Let's finalize these issues and then personally I think we can go ahead >>and commit. > >Okee dokee.
:) Andi

George Schlossnagle

23 years ago
On Monday, June 30, 2003, at 03:10 PM, Andi Gutmans wrote:
> At 02:01 PM 30/6/2003 -0400, George Schlossnagle wrote: > >> On Monday, June 30, 2003, at 02:48 PM, Andi Gutmans wrote: >> >>> At 11:44 AM 30/6/2003 -0400, George Schlossnagle wrote: >>>> On Monday, June 30, 2003, at 11:35 AM, George Schlossnagle wrote: >>>>> A look in sqlite answered my question - I should be using >>>>> ZEND_NAMED_FE. Will update patch momentarily. >>>> >>>> Updated now. >>> >>> I still get the old .diff via the URL you posted. Can you please >>> update it? >> >> The diff should be the same, since zend_reflection_api.[ch] aren't in >> cvs, they don't appear in the diff. They are there in their entirety >> as http://www.schlossnagle.org/~george/php/zend_reflection_api.c etc. > > Yeah I know but they aren't updated with the ZE_FNAME() change you > said you're doing :)
Oh. Should be fine now. Plus the naming change for the class. George

Andrei Zmievski

23 years ago
On Mon, 30 Jun 2003, George Schlossnagle wrote:
> Oh. Should be fine now. Plus the naming change for the class.
Why aren't you using PHP_METHOD() macro? -Andrei * Entropy isn't what it used to be. *

Sebastian Bergmann

23 years ago
Andi Gutmans wrote:
> Reflection_Function
+1
-- Sebastian Bergmann http://sebastian-bergmann.de/ http://phpOpenTracker.de/ Das Buch zu PHP 5: http://professionelle-softwareentwicklung-mit-php5.de/

Elfyn McBratney

23 years ago
On Mon, 30 Jun 2003, George Schlossnagle wrote:
> On Monday, June 30, 2003, at 12:04 PM, Andi Gutmans wrote: > > > I must be thick. I don't quite understand how the source relates to > > what is described in the .png. Take for example the following from the > > api.c file: > > I talked this over with Marcus. The FE/FALIAS pairs are designed to > avoid namespace conflicts with the other (not yet existent) reflection > classes. I better solution will be to write a new macro that allows > ZEND_FUNCTION(php_function_getstartline) to be registered as a class > method directly as 'getstartline). I'll modify my patch shortly. If > something like that exists already, a pointer to it would be swell. > > Otherwise the functions work as follows: > > <?php > > /** > Doc comment goes here > */ > function counter() { > static $i = 0; > return $i++; > } > > $obj = new PHP_Function("counter"); > > print $obj->getName()." was decared in ".$obj->getFileName()." starting > at ".$obj->getStartLine(). > "and ending at ".$obj->getEndline."\n"; > print "Here is what it's docs have to say: "$obj->getDocComment(). "\n"; > if($statics = $obj->staticVariables()) { > print $obj->getName()." has the following static > variables:\n".print_r($statics); > } > print $obj->invoke(); > > Something like that.
This looks really Cool!. BTW, have you looked at ZEND_NAMED_FE() in php-src/php/php.h ? I think that does what you need. Elfyn
--

Elfyn McBratney

23 years ago
On Mon, 30 Jun 2003, Elfyn McBratney wrote:
> On Mon, 30 Jun 2003, George Schlossnagle wrote: > > > On Monday, June 30, 2003, at 12:04 PM, Andi Gutmans wrote: > > > > > I must be thick. I don't quite understand how the source relates to > > > what is described in the .png. Take for example the following from the > > > api.c file: > > > > I talked this over with Marcus. The FE/FALIAS pairs are designed to > > avoid namespace conflicts with the other (not yet existent) reflection > > classes. I better solution will be to write a new macro that allows > > ZEND_FUNCTION(php_function_getstartline) to be registered as a class > > method directly as 'getstartline). I'll modify my patch shortly. If > > something like that exists already, a pointer to it would be swell. > > > > Otherwise the functions work as follows: > > > > <?php > > > > /** > > Doc comment goes here > > */ > > function counter() { > > static $i = 0; > > return $i++; > > } > > > > $obj = new PHP_Function("counter"); > > > > print $obj->getName()." was decared in ".$obj->getFileName()." starting > > at ".$obj->getStartLine(). > > "and ending at ".$obj->getEndline."\n"; > > print "Here is what it's docs have to say: "$obj->getDocComment(). "\n"; > > if($statics = $obj->staticVariables()) { > > print $obj->getName()." has the following static > > variables:\n".print_r($statics); > > } > > print $obj->invoke(); > > > > Something like that. > > This looks really Cool!. > > BTW, have you looked at ZEND_NAMED_FE() in php-src/php/php.h ? I think that does
^^^^^^^^^^^^^^^^^ s%/php/%/main%
> what you need. > > Elfyn
Hmm.. should have looked at your reply first, eh? :) Elfyn
--

Andrei Zmievski

23 years ago
On Mon, 30 Jun 2003, George Schlossnagle wrote:
> On Monday, June 30, 2003, at 12:04 PM, Andi Gutmans wrote: > > >I must be thick. I don't quite understand how the source relates to > >what is described in the .png. Take for example the following from the > >api.c file: > > I talked this over with Marcus. The FE/FALIAS pairs are designed to > avoid namespace conflicts with the other (not yet existent) reflection > classes. I better solution will be to write a new macro that allows > ZEND_FUNCTION(php_function_getstartline) to be registered as a class > method directly as 'getstartline). I'll modify my patch shortly. If > something like that exists already, a pointer to it would be swell.
#define ZEND_METHOD(class, name) ZEND_NAMED_FUNCTION(ZEND_FN(class##_##name)) It's already in zend_API.h -Andrei * Anything will fit if you push hard enough. *

Alan Knowles

23 years ago
It would be alot nicer if you could provide the majority of these as object variables (and/or) functions, it would enable print_r(new PHP_Function('counter')); which would save a lot of messing around, and writing code for general queries.. Regards Alan

Andrei Zmievski

23 years ago
On Tue, 01 Jul 2003, Alan Knowles wrote:
> It would be alot nicer if you could provide the majority of these as > object variables (and/or) functions, it would enable > print_r(new PHP_Function('counter')); > which would save a lot of messing around, and writing code for general > queries..
I posed this question on the list when I was designing the API and majority agreed that methods were preferred over properties. -Andrei * Non-volatile, random-access, analog memory store... a book. *

Sterling Hughes

23 years ago
Not to throw a wrench in the wheel, but properties seem to be the more appropriate pattern. Especially when taking PHP's object overloading abilities into play. Accessors are a Java paradigm that's as half-baked as it is repetitive, when you have overloading you no longer need property accessors. I vote (not to annoy george or anything, I'll write the code myself) that we use properties and overloading. It will make it much easier to instrospect the object with var_dump() and print_r(), and its the cleaner implementation.... -Sterling On Tue, 2003-07-01 at 09:34, Andrei Zmievski wrote:
> On Tue, 01 Jul 2003, Alan Knowles wrote: > > It would be alot nicer if you could provide the majority of these as > > object variables (and/or) functions, it would enable > > print_r(new PHP_Function('counter')); > > which would save a lot of messing around, and writing code for general > > queries.. > > I posed this question on the list when I was designing the API and > majority agreed that methods were preferred over properties. > > -Andrei > * Non-volatile, random-access, analog memory store... a book. *
-- "Whether you think you can or think you can't -- you are right." - Henry Ford

George Schlossnagle

23 years ago
On Tuesday, July 1, 2003, at 12:56 PM, Sterling Hughes wrote:
> Not to throw a wrench in the wheel, but properties seem to be the more > appropriate pattern. Especially when taking PHP's object overloading > abilities into play. Accessors are a Java paradigm that's as > half-baked > as it is repetitive, when you have overloading you no longer need > property accessors. > > I vote (not to annoy george or anything, I'll write the code myself) > that we use properties and overloading. It will make it much easier to > instrospect the object with var_dump() and print_r(), and its the > cleaner implementation....
It's not an annoyance - it's not my spec, I'm just implementing it. I'm happy to change the code to work via properties instead, it's not a major change. I would like to settle on a concensus first. George

moshe doron

23 years ago
> It's not an annoyance - it's not my spec, I'm just implementing it. > I'm happy to change the code to work via properties instead, it's not a > major change. I would like to settle on a concensus first.
+1 (maybe both)?

Jon Parise

23 years ago
On Thu, Jul 03, 2003 at 03:36:58PM +0200, moshe doron wrote:
> > It's not an annoyance - it's not my spec, I'm just implementing it. > > I'm happy to change the code to work via properties instead, it's not a > > major change. I would like to settle on a concensus first. > > +1 (maybe both)?
Please, not both. I think it would be best if there was one way to get at this information. I don't have a personal preference for either, though.
-- Jon Parise (jon@php.net) :: The PHP Project (http://www.php.net/)

Andi Gutmans

23 years ago
At 06:40 PM 3/7/2003 -0400, Jon Parise wrote:
>On Thu, Jul 03, 2003 at 03:36:58PM +0200, moshe doron wrote: > > > > It's not an annoyance - it's not my spec, I'm just implementing it. > > > I'm happy to change the code to work via properties instead, it's not a > > > major change. I would like to settle on a concensus first. > > > > +1 (maybe both)? > >Please, not both. I think it would be best if there was one way to >get at this information. I don't have a personal preference for >either, though.
I agree. We should only have one way and I personally prefer methods. Andi

Alan Knowles

23 years ago
having had a quick think about this, here some thoughts that may affect it. What is the API going to be used for. a) replacement for method_exists(), call_user_func() in code .. which makes sense for the object methods... b) quick testing of what an interface is - as in print_r() is quicker than opening the file/looking at the details... .. which makes sense for having a property access system... * imagine it.. - you need to look up the docs for a file, and you are editing something that uses it.. - just type in print_r(new reflection_class('HTML_Quickform')); in your current file, to remind you of the api.. I seriously doubt that it will be used by code analysis tools due the the need to load the file/class into the interpreter (which phpdoc/docu/codedoc dont do for speed/caching/conflict issues), so those are the only two common situations where I can envision it being use heavily. I dont see any major issues in using both access methods, they both have their uses and focus. Regards Alan Andi Gutmans wrote:

Andi Gutmans

23 years ago
At 01:55 PM 1/7/2003 -0400, George Schlossnagle wrote:
>On Tuesday, July 1, 2003, at 12:56 PM, Sterling Hughes wrote: > >>Not to throw a wrench in the wheel, but properties seem to be the more >>appropriate pattern. Especially when taking PHP's object overloading >>abilities into play. Accessors are a Java paradigm that's as half-baked >>as it is repetitive, when you have overloading you no longer need >>property accessors. >> >>I vote (not to annoy george or anything, I'll write the code myself) >>that we use properties and overloading. It will make it much easier to >>instrospect the object with var_dump() and print_r(), and its the >>cleaner implementation.... > >It's not an annoyance - it's not my spec, I'm just implementing it. >I'm happy to change the code to work via properties instead, it's not a >major change. I would like to settle on a concensus first.
I've already said so, but I definitely prefer methods. Andi

Andrei Zmievski

23 years ago
On Wed, 02 Jul 2003, Andi Gutmans wrote:
> I've already said so, but I definitely prefer methods.
So do I. Overloading properties is a bit of magical powder that's appropriate only in some cases. -Andrei * There is no knowledge that is not power. -- Ralph Waldo Emerson *