Re: __CLASS__ patch - use $__THIS__ or class_get_called_name()?
| From: | Alan Knowles | Date: | Sat, 06 Apr 2002 03:03:15 +0000 |
| Subject: | Re: __CLASS__ patch - use $__THIS__ or class_get_called_name()? | ||
| References: | 1 2 3 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-82164@lists.php.net to get a copy of this message | ||
Zeev Suraski wrote:
This should really be implemented 100% in compile time, if you touch zend_execute.c, BUZZ :) Anyway, incidentally, Jani implemented this very patch a few days ago. We'll probably import it within a couple of days after we verify that it doesn't cause any gotcha's... ZeevAs we chatted breifly on IRC,- Jani's patch implemented __FUNCTION__ and __CLASS__ as compile time values, hence in the example below they would return "base_class::test", and not extended_class::test <? class extended_class extends base_class { } class base_class { function test() {
echo __FUNCTION__ "::" __CLASS__;} } extended_class::test(); ?> while this is also very usefull, the real desire/need I had was to get the 'called' class name (some examples of usage are below), which is a bit more complex to retreive: - as it is part of the calling scope of zend_execute, but not currently passed down to the running scope... The implementation of this 'feature' does raise a few issue - should it be a constant, function call or a variable? Constant: __THIS__ Unlike all other magic constants, like __FILE__,_LINE__ etc. it is not possible (AFAICS) to 'set' the value at compile time. - hence the rather chessy hack to the Constant callback on the execute loop. - The more I look at this the worse it looks :) Function call: class_get_name() or class_get_called_name(); The present implemenation tagged extra information onto the function call (a pointer to the classname), I attepted to use a function call, this would involve adding an additional item to exectute globals eg. EG(active_class_name), and setting and unsetting, before after each function call. Variable: $_THIS or $THIS or $__THIS__ This would involve pretty much replicating the current ZE1 code that creates '$this' and do something like if EX(called_class_name) ... make it as a zval in the called method's scope. Considering this would __only__ happen on static method calls, and the size of the 'Class Name' is not normally Huge..., I think the very minor performance hit of creating this on static calls would be worth it..... and is simple to implement as well. (This is my favourite candidate at present :) The last option does not alter any key 'structures', which I found broke the ZendAPI, causeing some zend extensions to segfault :) -------Ok some code that uses it class database_tools { /* the normal 'get' method */ function &static_get($k,$v=NULL) {
$obj = new $__THIS__;
$obj->get($k,$v)
return $obj;
}
function get($k,$v=NULL) {
if ($v === NULL) {
$v = $k;
$keys = $this->_get_keys();
$k = $keys[0];
}
$this->$k = $v;
$this->select();
}
class db_users extends database_tools {
var $_table = "person";
function get($k,$v) {
$this->$k = $v;
if ($k = "firstname_letter");
$this->where_add("firstname like '$v%'");
$this->select();
}
}
class db_classrooms extends database_tools {
var $_table = "classrooms";
}
--- and the calling code examples...
$classroom = db_classrooms::static_get("number",12304);
$person = db_users::static_get(123);
$person = db_users::static_get("email","test@test.com");
$person = db_users::static_get("firstname_letter","a"); /
-- only way to do something similar without $__THIS__
$classroom = database_tools::static_get("db_classrooms","number",12304);
$person = database_tools::static_get("db_users",123);
$person = database_tools::static_get("db_users","email","test@test.com");
$person = database_tools::static_get("db_users","firstname_letter","a");
apart from the 'slightly shorter' naming :), the first example reads alot better.. - eg. I'm asking the users object for item 123..
whereas the database_tools is supposed to be a 'utility class' not an publically visable 'interface class'
that whole code could be simplified again if the get method knew it was being called statically.. and could call it'self!