FYI: -----Forwarded Message-----
> From: Timm Friebe <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Subject: [Zend Engine 2] Rethinking overloaded calls > Date: 17 Nov 2002 17:40:44 +0100 > > I'd like to pick up on Alan Knowles' suggestion to php-dev from a couple > of days ago. There was some +1s and some argumentation against it, > saying we already have a standard: __get and __set. > > The thing is: __get and __set are only called for non-existant members. > What Alan suggested is declaring getters and setters that would be > always called. Come to think about it, what's the point anyway in having > __get and __set only be called for non-existant members, anyway? I can > see a nice usage for __call (for non-existant methods) - SOAP. __get and > __set being called for non-existant members would make people construct > ugly things such as [1] simply to have the functionality of getters and > setters for their variables. > > It was argued that if getters and setters were introduced, there'd have > to be an extra hashtable lookup for each set and get operation, which, > of course, has a performance impact. Well, with the example[1] provided, > the performance would be even worse due to the fact that the user is > doing it in PHP. Plus, people who write OOP code do this because they > want to make their code more maintainable. They don't do it for reasons > of speed - they'd be writing their web applications with PHP embedded > into HTML, not using functions (nevermind classes). Or they'd just ditch > PHP and write it all in C. But that's not the point. Using OOP is about > team work, maintainability and code reuse, which makes it more efficient > since developers' time can be saved - and there is nothing as expensive > as that. I can decide between employing one additional developer for > half a year or simply buying another server. People in deciding > positions buy bigger, better and faster hardware first. > > Just for proof of concept, I took Zend Engine 1 and some code from > ext/overload and implemented getters and setters in a similar way > suggested by Alan (see example [2]). In ZE2, this would be even easier > since one would only need to patch the zend_std_write_property and > zend_std_read_property functions. > > I know, of course, that in Zend Engine 2, I could simply use private or > protected members and write getters and setters for them to ensure that > noone goes ahead and "abuses" the API by directly using member > variables, but this is valid for PHP, but not in C, AFAIS. Having Zend > Engine take care of property access via API functions that could be used > by ext/*-programmers would be of real benefit: With the OOP power > provided by ZE2, we might one day see extensions written in C providing > classes. The base PEAR class could be seamlessly integrated (./configure > --with-pear=/usr/local/), for example, not requiring the user to > actually know where (in the filesystem) the PEAR extension framework is, > actually making PEAR a lot faster and (from the user's point of view) > more integrated. > > I was actually think of doing exactly this for my own framework (which > comes closer to the Java architecture) - I could boost performance by > rewriting the base class "Object" in C and registering it as an internal > class. It's required by any class within the framework anyway and thus > parsed and compiled on every request (same goes for some other classes > such as Exception, XPClass, ...). Then again, to hell with > performance:-) - although it would probably make sense here. > > So here's my suggestion: Drop __get and __set in favor of declared > getters and setters unless there's a good reason (I can't think of) to > keep them. Keep __call since there's a point in having it[3]. It's not > abusing the "PHP way" - think of how protected members have to be > declared in child classes. Declaration makes things clear to programmers > instead of having those magic __*-functions, makes code cleaner (just > see [1] and imagine some more ifs or switch/case-statements there) and > does not enforce coding standards on users (some might prefer > set_lastchange, some setLastchange, some lastchange and _lastchange, for > instance). Plus, always call getters and setters if declared. > > To save memory and gain performance, there could be some sort of member > name mangling (as seen in private and protected members) instead of > another two hashtables in zend_class_entry for getters and setters > (assuming pointer arithmetic is faster than hashtable lookups). > > ---------------------------------------------------------------------------- > 1] Example for work-around: > class Forum::Article { > var $_lastchange; > // more property declarations > > function __set($k, $v) { > if ('lastchange' == $k) { > $this->_lastchange= is_a($v, 'Date') ? $v : new Date($v); > } > // more ifs or maybe a switch / case? > } > > function __get($k) { > if ('lastchange' == $k) return $this->_lastchange; > // more ifs or maybe a switch / case? > } > } > > 2] Example for new functionality: > class Forum::Article { > var $lastchange write setLastchange; > var $author read getAuthor; > var $text read getText write setText; > > function setLastchange($v) { > $this->lastchange= is_a($v, 'Date') ? $v : new Date($v); > } > > // [...Shortened for brevity...] > } > > 3] Where __call makes sense: > class SOAP::Client { > // ... > > function invoke($args) { > // ... > } > > function __call($f, $args) { > $this->method= $f; > return $this->invoke($args); > } > } > > // ... > $c= new SOAP::Client( > new SOAP::Transport::Http($url), > 'urn:xmethodsBabelFish', > 'Babelfish' > ); > $text= $c->translate( > 'Hallo', > BABELFISH_LANG_GERMAN, > BABELFISH_LANG_ENGLISH > ); > // see http://xmethods.net/ve2/ViewListing.po?serviceid=14 > ---------------------------------------------------------------------------- > > -- > Timm > Any sufficiently advanced bug is indistinguishable from a feature > -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php