Ale*_*ber 30 php inheritance namespaces
假设我在不同的文件中有以下类:
<?php
namespace MyNS;
class superclass {
public function getNamespace(){
return __NAMESPACE__;
}
}
?>
<?php
namespace MyNS\SubNS;
class childclass extends superclass { }
?>
Run Code Online (Sandbox Code Playgroud)
如果我实例化"childclass"并调用getNamespace(),则返回"MyNS".
有没有办法从子类中获取当前命名空间而不重新声明方法?
我已经在每个类中创建一个静态$ namespace变量并使用它来引用它,super::$namespace但这并不是很优雅.
Håv*_*d S 21
__NAMESPACE__是一个编译时常量,这意味着它只在编译时有用.您可以将其视为一个宏,其中inserted将使用当前命名空间替换自身.因此,没有办法让__NAMESPACE__超类引用子类的命名空间.您将不得不求助于在每个子类中分配的某种变量,就像您已经在做的那样.
作为替代方法,您可以使用反射来获取类的命名空间名称:
$reflector = new ReflectionClass('A\\Foo'); // class Foo of namespace A
var_dump($reflector->getNamespaceName());
Run Code Online (Sandbox Code Playgroud)
有关更多(未完成的)文档,请参阅PHP手册.请注意,您需要使用PHP 5.3.0或更高版本才能使用反射.
use*_*929 13
您也可以在getNamespace()方法中执行此操作:
return get_class($this);
Run Code Online (Sandbox Code Playgroud)
从子类调用时,结果将是:
MyNS\SubNS\childclass
Run Code Online (Sandbox Code Playgroud)
如果你不想要最后的类名,只需砍掉从最后到最后的所有内容.
就我而言,我需要在父类中创建一个方法,该方法可以call_user_func()在某些子类中调用静态方法。如果您知道完整的类名,那就call_user_func()没有问题了。诀窍是在子类的命名空间中调用静态方法。
所以我们有即
\MyTools\AbstractParent
\Something\Else\Foo extends \MyTools\AbstractParent
\Something\Else\Bar extends \MyTools\AbstractParent
Run Code Online (Sandbox Code Playgroud)
我们现在需要一个方法AbstractParent。从子类调用的该方法Foo将能够Bar::doMe()通过前置其自己的名称空间来调用。
以下是使用动态调用的方法:
namespace MyTools;
abstract class AbstractParent {
public static method doMe(){}
public function callSomethingStaticInClass($class){
// current namespace IS NOT MyTools
// so you cannot use __NAMESPACE__
$currentClass = get_class($this);
$refl = new ReflectionClass($currentClass);
$namespace = $refl->getNamespaceName();
// now we know what the subclass namespace is...
// so we prefix the short class name
$class = $namespace . '\\' . $class;
$method = 'doMe';
return call_user_func(array( $class, $method ));
}
};
namespace Something\Else;
class Foo extends AbstractParent { }
class Bar extends AbstractParent { }
$foo = new Foo();
$foo->callSomethingStaticInClass('Bar');
Run Code Online (Sandbox Code Playgroud)
要使其与静态调用一起使用,请替换get_class($this)为get_called_class()