Req #68593 [Com]: Namespace not resolved at runtime like with static::
| From: | nikic@php.net | Date: | Thu, 11 Dec 2014 23:21:03 +0000 |
| Subject: | Req #68593 [Com]: Namespace not resolved at runtime like with static:: | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-189024@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=68593&edit=1
ID: 68593
Comment by: nikic@php.net
Reported by: llmll at gmx dot de
Summary: Namespace not resolved at runtime like with static::
Status: Duplicate
Type: Feature/Change Request
Package: Scripting Engine problem
Operating System: any
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
The current behavior is intended and correct. Class names, including unqualified class names, are
always resolved at compile time.
The confusion probably comes from the incorrect or at least misleading wording on http://php.net/manual/en/language.namespaces.rules.php.
That document conflates name resolution (which is always compile-time for class names) and
autoloading (which is the runtime operation). It should probably be clarified (don't know why
it even mentions autoloading there - that's not related to name resolution).
Previous Comments:
------------------------------------------------------------------------
[2014-12-11 23:09:30] llmll at gmx dot de
Hi requinix@php.net,
stay calm. A bug is no reason to shout at people.
Coding is not a matter of feeling but of precision. There is runtime and there is write-time and
there is a big difference which you play down. Why not ponder on the problem, and then admit and
correct it? Everybody will benefit from clarification.
(I remember doing the same convincing for the necessity of static::, when years ago PHP lacked late
static binding and only had the nowadays completely useless self:: operator. In time, people
appreciated the late static binding :-))
Now comes the difficult part. In our project we really need to address the current namespace at
runtime, as it offered in PHP's documentation. I see no way of explaining the why and how to
you, considering your prior reasoning.
Just for reference for others, here is how we compensate for it:
public static function typeNameOfPeer($aClass) {
return static::moduleName() . '\\' . $aClass;
}
moduleName() returns the current class' namespace. So if we want to call a class dynamically in
the current namespace, we need to write:
$class = static::typeNameOfPeer('RelativeNameOfClass');
$class::callAMethod();
I was hoping to get in touch with another maintainer. Please don't be offended or take it
personally when I request the bug to be transferred to a colleague who knows PHP namespaces and
inheritance mechanics. Thanks.
------------------------------------------------------------------------
[2014-12-11 22:37:06] requinix@php.net
No. We argued about this in your other bug report.
The. Current. Behavior. Is. Correct.
If you feel the documentation needs clarification to explain the resolution process better - that
unqualified class names in code are always resolved according to the namespace WHERE THE CODE IS
ACTUALLY WRITTEN - then submit a patch against it:
1. Go to the relevant page and click the Edit link in the top-right corner
2. Log in (or stay anonymous)
3. Make your change to the documentation's source XML
4. Save and submit the change for review
------------------------------------------------------------------------
[2014-12-11 22:07:26] llmll at gmx dot de
Description:
------------
The problem is equivalent to self:: and static:: but on the namespace realm. self:: resolves to the
defining class while static:: resolves to the current instance class.
Take a second to understand the test script and expected result.
Reopening #68485 as current behaviour deviates clearly from the documentation, which the original
maintainer failed to grasp.
Test script:
---------------
// original namespace
namespace Alpha;
class Helper {
public static $Value = "ALPHA";
}
class Caller {
public static function Write() {
// call to relative neighbour class Helper, resolves to \Alpha\Helper::
echo Helper::$Value;
}
}
// now both classes are inherited into another namespace
namespace Beta;
class Helper extends \Alpha\Helper {
public static $Value = 'BETA';
}
class Caller extends \Alpha\Caller {}
\Beta\Caller::Write();
Expected result:
----------------
This should print "BETA". PHP namespace resolution documentation states:
Inside namespace (say A\B), calls to unqualified or qualified class names (not fully qualified class
names) are resolved at >>> RUN-TIME <<<. This only makes sense, if at runtime the
current class scope and the current namespace are taken into account to resolve the class. Otherwise
resolving at runtime or at compiletime makes no difference.
Actual result:
--------------
The call to Helper::$Value is resolved at complie-time which is breaking inheritance logic.
Helper:: should resolve to the instance namespace, because it is called without a namespace
qualifier, meaning we want the relative class to the current namespace. Otherwise we could have
written the fully-qualified \Alpha\Helper to fix the used Helper class, even in child classes.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68593&edit=1