After looking at the introduction of datastore, and starting to use MVC method to write PHP, I wanted to use PHP to write a model for redis, which can realize some basic functions of datastore... So I encountered such a problem-.-
Things like __CLASS__ in PHP are statically bound. If they are not overloaded in a subclass, what you get by inheriting the parent class method is still the name of the parent class instead of the name of the subclass. For example:
class A{
function __construct(){
echo __CLASS__;
}
static function name(){
echo __CLASS__;
}
}
class B extends A{}
At this time, whether B is instantiated or the static method is directly called, the echo will be A. Qeephp uses subclass overloading to solve this problem, but if you don't create a new subclass, you have to overload the corresponding method of calling the class name... This is considered a defect of PHP in OOP. , I tried python and there was no such problem.
Google it. Find two functions get_class() and get_called_class(). get_class() is used for instance calls. Adding parameters ($this) can solve the problem of subclass inheritance calls, while get_called_class() is used for static method calls, but... this thing is only available after PHP 5.3. ...5.3 is still a long way off... Fortunately, this function can be implemented manually before 5.2: refer to http://php.net/manual/en/function.get-called-class.php. Some experts have added a few below. A pre-5.3 implementation.
if(!function_exists(get_called_class)) {
class class_tools
{
private static $i = 0;
private static $fl = null;
public static function get_called_class()
{
$bt = debug_backtrace();
//Use the call_user_func or call_user_func_array function to call the class method. The processing is as follows
if (array_key_exists(3, $bt)
&& array_key_exists(function, $bt[3])
&& in_array($bt[3][function], array(call_user_func, call_user_func_array))
) {
//If the parameter is an array
if (is_array($bt[3][args][0])) {
$toret = $bt[3][args][0][0];
return $toret;
}else if(is_string($bt[3][args][0])) {//If the parameter is a string
//If it is a string and the string contains the :: symbol, it is considered to be the correct parameter type, and the class name is calculated and returned
if(false !== strpos($bt[3][args][0], ::)) {
$toret = explode(::, $bt[3][args][0]);
return $toret[0];
}
}
}
//Use the normal way to call class methods, such as:A::make()
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();
}
}
So now you can modify the example like this:
class A{
function __construct(){
echo get_class($this);
}
static function name(){
echo get_called_class();
}
}
class B extends A{}
This will allow B to directly inherit the method of obtaining the current class name~