How can I get the classname from a static call in an extended PHP class?

Viewed 69668

I have two classes: Action and MyAction. The latter is declared as:

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

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

Class Action {
 function n(){/* something */}
}

And when I call it:

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

But each declaration in the parent class has access only to the parent class __CLASS__ variable, which has the value “Action”.

Is there any possible way to do this?

7 Answers

__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
class MainSingleton { 
  private static $instances = array(); 
  private static function get_called_class() {
    $t = debug_backtrace();
    return $t[count($t)-1]["class"];
  }  

  public static function getInstance() { 
    $class = self::get_called_class();
    if(!isset(self::$instances[$class]) ) { 
      self::$instances[$class] = new $class; 
    } 
    return self::$instances[$class]; 
  } 

}

class Singleton extends MainSingleton { 
  public static function getInstance()
  {
    return parent::getInstance();
  }     
  protected function __construct() { 
    echo "A". PHP_EOL; 
  } 

  protected function __clone() {} 

  public function test() { 
    echo " * test called * "; 
  } 
} 

Singleton::getInstance()->test(); 
Singleton::getInstance()->test();

(PHP 5 >= 5.3.0, PHP 7)
get_called_class — The "Late Static Binding" class name

<?php

class Model
{
  public static function find()
  {
    return get_called_class();
  }
}

class User extends Model
{
}


echo User::find();

this link might be helpfull

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.

Related