After reading the datastore introduction and using MVC to write php, I want to use php to write a model for redis to implement some basic functions of datastore... so I encountered such a problem -. -The _ CLASS in php is statically bound. if it is not reloaded in the subclass, the inherited parent class method still obtains the parent class name rather than the subclass name. For example, classA {func looked at the datastore entry and started to write php in MVC mode, so he wanted to write a model for redis using php, some basic functions of datastore can be implemented... so I encountered such a problem -.-
In php, the _ CLASS is statically bound. if the subclass is not overloaded, the method inherited from the parent CLASS will still get the name of the parent CLASS rather than the name of the subclass. For example:
Class {
Function _ construct (){
Echo _ CLASS __;
}
Static function name (){
Echo _ CLASS __;
}
}
Class B extends {}
In this case, whether B is instantiated or the static method is directly called, the echo will be. In qeephp, this problem is solved by using subclass overloading. However, if no new subclass is created, you have to reload the method of calling the class name ..... this is a defect of php in oop. I tried python and didn't have this problem.
Google. Find the get_class () and get_called_class () functions (). Get_class () is used for instance calling. adding a parameter ($ this) solves the problem of subclass inheritance calling, while get_called_class () is used for static method calling,... this is only available after php 5.3 .... 5.3 is still far away... fortunately, you can manually implement this function before 5.2: see below the http://php.net/manual/en/function.get-called-class.php has a master added several implementation methods before 5.3.
So now we can modify the example as follows:
In this way, B can inherit the method to obtain the current class name ~
class A{function __construct(){echo get_class($this);}static function name(){echo get_called_class();}}class B extends A{}
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 (); // call the class method using the call_user_func or call_user_func_array function to process the following 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 and the string contains the: symbol, the parameter is considered to be of the correct parameter type. if (false!) is calculated and the class name is returned! = Strpos ($ bt [3] ['args'] [0], ':') {$ toret = explode ('::', $ bt [3] ['args '] [0]); return $ toret [0] ;}}// call A class method through A normal method, for example, :: 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 ();}}