Edit report at https://bugs.php.net/bug.php?id=74257&edit=1
ID: 74257
Updated by: requinix@php.net
Reported by: david at grudl dot com
-Summary: Leading slash in namespace declaration
+Summary: "namespace \X" does not work to declare a namespace
-Status: Not a bug
+Status: Open
-Type: Bug
+Type: Documentation Problem
-Package: Compile Failure
+Package: Scripting Engine problem
PHP Version: 7.1.2
Block user comment: N
Private report: N
New Comment:
Keep in mind OP had to define X as a constant. In the real world namespaces have more meaningful
names and it's unlikely there will be a constant by the same name, so code would create an
error.
Additionally, "namespace\" is documented in "namespace keyword and __NAMESPACE__
constant"
http://php.net/manual/en/language.namespaces.nsconstants.php
Previous Comments:
------------------------------------------------------------------------
[2019-01-31 01:16:25] roy-orbison at devo dot net dot au
This is definitely a bug. If PHP devs really think it's a feature, why isn't it documented
in "Defining Namespaces"? There is no way anyone would expect the following to be anything
other than a definition.
namespace \Foo\Bar;
Accessing members of a namespace relative to global is done with a leading backslash, so why not the
same for defining? It should at least be a syntax error rather than evaluate and cause a fatal error
or silently fail. That type of expression could only read a constant without doing any assignment,
thus have no effect on other userspace state, right? So what's the point of allowing it without
even a warning?
------------------------------------------------------------------------
[2017-03-16 16:46:49] tpunt@php.net
^ See above comment...
------------------------------------------------------------------------
[2017-03-16 16:46:05] tpunt@php.net
This is not a bug, but rather a feature in namespaces known as relative names.
In short, the following line:
namespace \X;
is not a namespace *declaration*, but rather an *expression* that resolves to the symbol X of the
current namespace. The "namespace \" part (where space is optional) is either evaluated to
the currently defined namespace (it is simply ignored for the global namespace).
When utilising this feature, symbols that are not found in the current namespace will not fallback
to the globally defined functions or constants.
So, the following works:
var_dump(namespace\PHP_ZTS);
But the following will error (due to an undefined PHP_ZTS constant in the current namespace):
namespace test;
var_dump(namespace\PHP_ZTS);
Whilst obviously the following will work as expected (by falling back to the globally defined
PHP_ZTS constant):
namespace test;
var_dump(PHP_ZTS);
See the manual for further information: http://php.net/manual/en/language.namespaces.rules.php
------------------------------------------------------------------------
[2017-03-16 12:47:20] david at grudl dot com
Description:
------------
Leading slash in namespace declaration can cause silent ignorance of namespace declaration.
https://3v4l.org/DEZBT
Test script:
---------------
<?php
define('X', 'Y');
namespace \X;
class Test
{
}
echo Test::class;
Expected result:
----------------
Fatal error: Namespace declaration statement has to be the very first statement or after any declare
call in the script
Actual result:
--------------
'Test'
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74257&edit=1