views:

5138

answers:

4

Hello anyone. Here is the situation. I have two classes: Action, and MyAction, last one is declared as:

class MyAction extends Action {/* some methods here */}

All i need is method in Action class(only in it, cuz there will be a lot of inherited classes, and i don't want to implement that method in all of them), which will return classname from static call. Here is what 'm talking about:

Class Action {
 function n(){/* some actions */}
}

And when i call it:

MyAction::n(); // it should return "MyAction"

But each declaration in parent class have access only to parent class(__CLASS__ variable has value "Action").

Is there any possible ways to do that?

+10  A: 

__CLASS__ always returns the name of the class in which it was used, so it's not much help with a static method. If the method wasn't static you could simply use get_class($this). e.g.

class Action {
    public function n(){
        echo get_class($this);
    }

}

class MyAction extends Action {

}

$foo=new MyAction;

$foo->n(); //displays 'MyAction'

Late static bindings, available in PHP 5.3+

Now that PHP 5.3 is released, you can use late static bindings, which let you resolve the target class for a static method call at runtime rather than when it is defined.

While the feature does not introduce a new magic constant to tell you the classname you were called through, it does provide a new function, get_called_class() which can tell you the name of the class a static method was called in. Here's an example:

Class Action {
    public static function n() {
        return get_called_class();
    }
}


class MyAction extends Action {

}


echo MyAction::n(); //displays MyAction
Paul Dixon
The only problem for the OP is that the feature is not yet available. PHP 5.3 is yet in beta.
Ionuț G. Stan
Oh good catch, I'd missed that
Paul Dixon
bad for PHP i think. Anyway, thanks =)
Anton
A: 

There is no way, in the available PHP versions, to do what you want. Paul Dixon's solution is the only one. I mean, the code example, as the late static bindings feature he's talking about is available as of PHP 5.3, which is in beta.

Ionuț G. Stan
+4  A: 

Now (when 5.3 has arrived) it's pretty simple:

http://ua.php.net/manual/en/function.get-called-class.php

Anton
+4  A: 

It's not the ideal solution, but it works on PHP < 5.3.0.

The code was copied from septuro.com

if(!function_exists('get_called_class')) {
 class class_tools {
  static $i = 0;
  static $fl = null;

  static function get_called_class() {
      $bt = debug_backtrace();

   if (self::$fl == $bt[2]['file'].$bt[2]['line']) {
       self::$i++;
   } else {
       self::$i = 0;
       self::$fl = $bt[2]['file'].$bt[2]['line'];
   }

   $lines = file($bt[2]['file']);

   preg_match_all('/([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/',
       $lines[$bt[2]['line']-1],
       $matches);

         return $matches[1][self::$i];
     }
 }

 function get_called_class() {
     return class_tools::get_called_class();
 }
}
Jrgns
nice workaround, though probably slow.
philfreo