Re: __CLASS__ patch - use $__THIS__ or class_get_called_name()?

From: 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... Zeev
As 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!

« previous php.dev (#82164) next »