2

I want to get the namespace of a class property through ReflectionClass.

namespace Foo\Bar;
use Foo\Quux\B;

class A{

   /**
   * @var B $b
   */
   protected $b = null;

   ...

}

In another class I'm creating a ReflectionClass object and trying to get the namespace of property b so I could create ReflectionClass for it's class.

$namespace = "Foo\\Bar";
$classname = "A";
$rc = new \ReflectionClass("$namespace\\$classname");
$type = getVarType($rc->getProperty("b")->getDocComment()); // returns B
$ns = $rc->getProperty("b")-> ... // I want to find out the namespace of class B
$rc1 = new \ReflectionClass("$ns\\$type");

Is there a possibility to find out which namespaces the class A uses? Then I could pair the namespaces which class A is using with the discovered property type.

I know I can solve this problem with a type hinting like this: @var Foo\Quux\B $b, but I have many classes like the class A with many properties and methods using types like b and I don't want to refactor the whole code.

Is it possible to find the namespaces from the use statement or I have to use explicit type hinting?

Thanks!

2 Answers2

1

You should be able to use getNamespaceName to find that out, but getProperty can tell you that as well

namespace Foo;

class A {
    protected $something;
}

namespace Bar;

class B {
    protected $a;

    public function __construct(){
        $this->a = new \Foo\A();
    }
}

$reflection = new \ReflectionClass('Bar\\B');
$a = $reflection->getProperty("a");
var_dump($a);

You'll get

object(ReflectionProperty)#2 (2) {
["name"]=> string(1) "a"
["class"]=> string(5) "Bar\B"
}

Machavity
  • 30,841
  • 27
  • 92
  • 100
  • Thank you for the answer, but this is not the result I want. I would like the returned class to be `Foo\A`, so I could recursively look into it, ie. create `new \ReflectionClass("Foo\\A");` – Pavel Kocábek Apr 06 '17 at 16:28
  • So do a `str_replace` on the class returned and you can do exactly what you're describing – Machavity Apr 06 '17 at 16:30
  • The thing is, that I don't really know which class or namespace to expect in the first place. The class `B` in your code example might also have a property `$c`, which class sholud be for example `Foobar\C` or `Bar\C`. I don't really know if php is capable of discovering the real class otherwise than looking into DocComment where the full namespace will be written. – Pavel Kocábek Apr 06 '17 at 16:47
  • @PavelKocábek the properties of class `B` should not be based on `B` unless they are of a class that extends from `B`. This answer is correct – That Realty Programmer Guy Oct 01 '21 at 11:35
1

One solution is to find the use statement which declare the class used in your doc comment. This will make it possible to retrieve the full namespace from the class name.

You cannot do that directly using ReflectionClass but this post can be interesting or you can use BetterReflection for that.