2

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

1 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

3 Comments

I realize that your answer describes the behaviour but with no documentation to dynamic namespaces being the global name space its behaviour still is inconststant
@exussum As I said, as far as I know this isn't explicit said in the manual anywhere, but if you want I can provide you a few links where you can read this "between the lines". And why should the behaviour still be inconstant?
From memory though can't test currently variables and functions defined in a similar way do not behave like the class will confirm tomorrow some pinks which hint at the behaviour will be good too

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.