exussum
exussum

Reputation: 18578

variable class name ignoring current namespace

Im confused at why a variable class name seems to ignore the current name space ?

I would expect the following to be the same

<?php
namespace so\level1{

  class test{
    function __construct() {
      echo "working correctly\r\n"; 
    }
  }

}

namespace so {
  $a = new level1\test();
  $b = 'level1\\test';
  $c = new $b();
}

Instead $c is a new \level1\test instead of a \so\level1\test

This seems to contradict http://php.net/manual/en/language.namespaces.fallback.php

Class names always resolve to the current namespace name

http://php.net/manual/en/language.namespaces.rules.php

Says

Inside a namespace, all qualified names not translated according to import rules have the current namespace prepended. For example, if a call to C\D\e() is performed within namespace A\B, it is translated to A\B\C\D\e().

I have no import rules, so it also seems to suggest $a and $c are the same

Is there any documentation I am missing ? or is the behaviour wrong ?

Output of above

working correctly
PHP Fatal error:  Class 'level1\test' not found in /tmp/namespace.php on line 15
PHP Stack trace:
PHP   1. {main}() /tmp/namespace.php:0

using PHP 5.5.9 and 5.5.21

adding

namespace level1 {
  class test{
    function __construct() {
      echo "Not working correctly\r\n";
    }
  }
}

Makes the second name space resolve, But it seems like incorrect behaviour

To confirm, this seems incorrect because of the following

<?php
namespace so {
  $test = "namespace";
  $var = "test";
  echo $$var;
}

This resolves "correctly" but inconsistently with the above.

Though call_user_func behaves in a similar way to the classes

namespace so {
  function testing() {
    echo "in namespace";
  }
  call_user_func(__NAMESPACE__ . "\\testing");
}

in the last case, it is actually documented. using a variable function behaves in the same way

Upvotes: 2

Views: 189

Answers (1)

Rizier123
Rizier123

Reputation: 59701

The answer is, it doesn't work, because if you start using dynamic class names the "current namespace" is the global namespace.

But it seems like incorrect behavior, no as I said if you use dynamic class names the "current namespace" is the global one and not the one which it is written in.

But with one point you're kind of right. This isn't explicit said in the manual.

So how to solve this now? You just can use the magic constant __NAMESPACE__ to get the current namespace and you can simply do this:

namespace so\level1{

  class test{
    function __construct() {
      echo "working correctly\r\n"; 
    }
  }

}

namespace so {
  $a = new level1\test();
  $b = __NAMESPACE__ . '\\level1\\test';
  $c = new $b();
}

Output:

working correctly working correctly

Upvotes: 3

Related Questions