从PHP中的超类获取子类命名空间

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)

如果你不想要最后的类名,只需砍掉从最后到最后的所有内容.


Art*_*era 5

就我而言,我需要在父类中创建一个方法,该方法可以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()