Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:17491 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 99581 invoked by uid 1010); 2 Aug 2005 13:27:06 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 99512 invoked from network); 2 Aug 2005 13:27:05 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Aug 2005 13:27:05 -0000 X-Host-Fingerprint: 82.94.239.5 jdi.jdi-ict.nl Linux 2.5 (sometimes 2.4) (4) Received: from ([82.94.239.5:38434] helo=jdi.jdi-ict.nl) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id E2/CD-04646-CBF6FE24 for ; Tue, 02 Aug 2005 09:06:05 -0400 Received: from localhost (localhost [127.0.0.1]) by jdi.jdi-ict.nl (8.12.11/8.12.11) with ESMTP id j72D5x9e028532 for ; Tue, 2 Aug 2005 15:05:59 +0200 Received: from localhost (localhost [127.0.0.1]) by jdi.jdi-ict.nl (8.12.11/8.12.11) with ESMTP id j72D5qgN028509; Tue, 2 Aug 2005 15:05:54 +0200 Date: Tue, 2 Aug 2005 15:05:52 +0200 (CEST) X-X-Sender: derick@localhost To: PHP Developers Mailing List cc: Jan Borsodi , Raymond Bosman , Frederik Holljen , Tobias Schlitt Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: by amavisd-new at jdi-ict.nl Subject: Property Overloading RFC From: dr@ez.no (Derick Rethans) Hello! we're finding some problems with property overloading (__get() and __set()). Here is an RFC describing what we'd like to see changed. Please comment on this. Introduction: PHP currently supports property overloading with the magic functions __get() and __set(). Those methods are called when the code "echo $object->a" or "$object->a = 42" are executed and the property "a" is not declared in the class. The magic methods are responsibly for: - checking if the property actually "exists" - setting the value or returning the value depending on the action Problems: 1. There is no way to document the 'virtual' properties with any of the existing documentation tools (such as phpdoc and doxygen) 2. There is no way how the magic methods know if a specific 'virtual' property exists or not as those properties are not declared usually - unless you define an array with property names as a class constant (which is not allowed either). 3. There is no way for the magic methods to return a meaningfull error when a property doesn't "exist". Of course it is possible to throw an error with "trigger_error" or "throw" in case a property doesn't "exist" in a specific class, but the file and line numbers would not match the actually get/set action. debug_backtrace() can be used to retrieve the correct file and line, but as you have to do this for every class where you want to use setters and getters *and* you have to implement your own error message rendering function this is not really a suitable option either. Solutions: - For problem 1. we can introduce a keyword (or use an existing one) to define that it is a virtual property ('abstract' or 'virtual' come to mind). When declaring it like this it's easy to document, and we can also implement visibility for those virtual properties. Marcus already has a patch for this somewhere, which uses the "abstract" keyword for this purpose: - In combination to the introduced keyword we need an easy way to check if a passed property name is declared in the class as 'virtual'. Currently (with the 'abstract' keyword properly implemented) you'd have to do: isAbstract() ) { /* throw error */ } } catch ($e) { /* throw error */ } } } $b = new Base(); echo $b->foo; ?> This is ofcourse overly complicated. A better workable solution would be - without breaking BC (suggestions for syntax here are very welcome): foo; ?> - Problem 3 can be solved by: * allowing optional by-ref parameters to the __set and __get function, so that their signatures become: function __set($name, $value [, &$error] ) function __get($name [, &$error] ) If the parameter is not given things behave just like they do now -> __set and __get can not throw meaningful errors with the correct file/line of the conflicting statement If the parameter is used in the function's declaration and is set to "false" when the __set or __get function returns, the engine can throw an error on the assignment line with the correct file/line combination. If it's set to "true" (or "null") then the engine should not throw any error. * Use a different __set and __get function for 'abstract' properties, then the engine can already determine if you're doing something wrong before executing the __set and __get methods. regards, Derick -- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org