daveoncode
daveoncode

Reputation: 19588

Get PHP class namespace dynamically

How can I retrieve a class namespace automatically?

The magic var __NAMESPACE__ is unreliable since in subclasses it's not correctly defined.

Example:

class Foo\bar\A -> __NAMESPACE__ === Foo\bar

class Ping\pong\B extends Foo\bar\A -> __NAMESPACE__ === Foo\bar (it should be Ping\pong)

ps: I noticed the same wrong behavior using __CLASS__, but I solved using get_called_class()... is there something like get_called_class_namespace()? How can I implement such function?

UPDATE:
I think the solution is in my own question, since I realized get_called_class() returns the fully qualified class name and thus I can extract the namespace from it :D ...Anyway if there is a more effective approach let me know ;)

Upvotes: 17

Views: 50254

Answers (3)

Stephen Stephenson
Stephen Stephenson

Reputation: 657

Use Reflection class.

$class_name = get_class($this);

$reflection_class = new \ReflectionClass($class_name);

$namespace = $reflection_class->getNamespaceName();

Upvotes: 11

David Lin
David Lin

Reputation: 13353

In PHP 5.5, ::class is available which makes things 10X easier. E.g. A::class

Upvotes: 14

shadyyx
shadyyx

Reputation: 16055

The namespace of class Foo\Bar\A is Foo\Bar, so the __NAMESPACE__ is working very well. What you are looking for is probably namespaced classname that you could easily get by joining echo __NAMESPACE__ . '\\' . __CLASS__;.

Consider next example:

namespace Foo\Bar\FooBar;

use Ping\Pong\HongKong;

class A extends HongKong\B {

    function __construct() {
        echo __NAMESPACE__;
    }
}

new A;

Will print out Foo\Bar\FooBar which is very correct...

And even if you then do

namespace Ping\Pong\HongKong;

use Foo\Bar\FooBar;

class B extends FooBar\A {

    function __construct() {
        new A;
    }
}

it will echo Foo\Bar\FooBar, which again is very correct...

EDIT: If you need to get the namespace of the nested class within the main that is nesting it, simply use:

namespace Ping\Pong\HongKong;

use Foo\Bar\FooBar;

class B extends FooBar\A {

    function __construct() {
        $a = new A;
        echo $a_ns = substr(get_class($a), 0, strrpos(get_class($a), '\\'));
    }
}

Upvotes: 21

Related Questions