# namespace implementation (irritating warning and autoload)

- Thread: https://externals.io/message/36816
- Original archive: https://news-web.php.net/php.internals/36816
- Started by Julian Reich on 2008-04-05T19:57:05+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #36816 — Julian Reich — 2008-04-05T19:57:05+00:00

URL: https://externals.io/message/36816#36816

Hi,

I recently started porting an application to PHP 5.3.

1. While testing the new namespace implementation I noticed the  
following:

<?php
namespace Test1;
function fooBar() { echo 'Test1::fooBar()' . PHP_EOL; }

namespace Test2;
use Test1;
Test1::fooBar();

Executing the code above results in a warning: "The use statement with  
non-compound name 'Test1' has no effect in [...]".
I understand the rationale behind this warning but it simply isn't  
true: omitting the use statement results in a fatal error: "Class  
'Test2::Test1' not found in [...]".

Since the following code executes without warning or error I think the  
code above (without use statement) should also execute just fine.

<?php
namespace Test1::Test2;
function fooBar() { echo 'Test1::Test2::fooBar()' . PHP_EOL; }

namespace Test3;
Test1::Test2::fooBar();

But I'm not quite sure about the warning (about the non-compound use  
statement): I think the warning should either be dropped or its  
statement should be fulfilled.


2. I'm sorry for bringing this up again: The current name resolution  
order makes using the namespace feature in conjunction with  
autoloading less usable and somewhat error prone.

    a. To avoid that internal classes introduced to PHP somewhen in  
the future break my app I've to add a number of use statements that  
would not be necessary otherwise.
        So to be on the safe side one has to
           i.   "use" all classes from the current namespace which is  
annoying and  especially in bigger projects one might easily forget to  
"use" classes when making changes
           ii.  use exactly one file per namespace (this might work  
well especially with few classes per namespace that are mostly used  
together,
                 but one can easily think of a lot of situations you  
want to load just the classes that are really needed and in the end  
this is what autoload is for)
           iii. avoid the usage of autoload

    b. Applications might behave differently when packaged
           i.  one class per file using autoload (without "use"-ing  
classes from the  current namespace)
           ii. all classes in one file

    c. Implementors of autoloaders can keep the performance hit to a  
minimum using some kind of caching.

I think the current resolution order is a WTF-factor especially for  
unexperienced users or users coming from other languages.

I know that the above arguments might have been already on this list  
but I couldn't find some definitive decision to keep the current name  
resolution order. If I've missed that I'm sorry for the noise.


Regards,
Julian Reich

---

## #36817 — Jessie Hernandez — 2008-04-06T03:08:11+00:00

URL: https://externals.io/message/36816#36817 · In reply to: #36816

Julian,

Regarding the name resolution rules, I posted a patch a few months ago 
with what I think is a more reasonable lookup order 
(http://news.php.net/php.internals/34097), but did not get much 
feedback. Would you like to try it out? (let me know if it doesn't apply 
cleanly against the current PHP_5_3)


Regards,

Jessie Hernandez
Zend Certified Engineer (http://zend.com/zce.php?c=ZEND006359&r=222727282)



Julian Reich wrote:
> Hi,
> 
> I recently started porting an application to PHP 5.3.
> 
> 1. While testing the new namespace implementation I noticed the following:
> 
> <?php
> namespace Test1;
> function fooBar() { echo 'Test1::fooBar()' . PHP_EOL; }
> 
> namespace Test2;
> use Test1;
> Test1::fooBar();
> 
> Executing the code above results in a warning: "The use statement with 
> non-compound name 'Test1' has no effect in [...]".
> I understand the rationale behind this warning but it simply isn't true: 
> omitting the use statement results in a fatal error: "Class 
> 'Test2::Test1' not found in [...]".
> 
> Since the following code executes without warning or error I think the 
> code above (without use statement) should also execute just fine.
> 
> <?php
> namespace Test1::Test2;
> function fooBar() { echo 'Test1::Test2::fooBar()' . PHP_EOL; }
> 
> namespace Test3;
> Test1::Test2::fooBar();
> 
> But I'm not quite sure about the warning (about the non-compound use 
> statement): I think the warning should either be dropped or its 
> statement should be fulfilled.
> 
> 
> 2. I'm sorry for bringing this up again: The current name resolution 
> order makes using the namespace feature in conjunction with autoloading 
> less usable and somewhat error prone.
> 
>    a. To avoid that internal classes introduced to PHP somewhen in the 
> future break my app I've to add a number of use statements that would 
> not be necessary otherwise.
>        So to be on the safe side one has to
>           i.   "use" all classes from the current namespace which is 
> annoying and  especially in bigger projects one might easily forget to 
> "use" classes when making changes
>           ii.  use exactly one file per namespace (this might work well 
> especially with few classes per namespace that are mostly used together,
>                 but one can easily think of a lot of situations you want 
> to load just the classes that are really needed and in the end this is 
> what autoload is for)
>           iii. avoid the usage of autoload
> 
>    b. Applications might behave differently when packaged
>           i.  one class per file using autoload (without "use"-ing 
> classes from the  current namespace)
>           ii. all classes in one file
> 
>    c. Implementors of autoloaders can keep the performance hit to a 
> minimum using some kind of caching.
> 
> I think the current resolution order is a WTF-factor especially for 
> unexperienced users or users coming from other languages.
> 
> I know that the above arguments might have been already on this list but 
> I couldn't find some definitive decision to keep the current name 
> resolution order. If I've missed that I'm sorry for the noise.
> 
> 
> Regards,
> Julian Reich

---

## #36818 — Greg Beaver — 2008-04-06T12:49:06+00:00

URL: https://externals.io/message/36816#36818 · In reply to: #36816

Julian Reich wrote:
> Hi,
> 
> I recently started porting an application to PHP 5.3.
> 
> 1. While testing the new namespace implementation I noticed the following:
> 
> <?php
> namespace Test1;
> function fooBar() { echo 'Test1::fooBar()' . PHP_EOL; }
> 
> namespace Test2;
> use Test1;
> Test1::fooBar();
> 
> Executing the code above results in a warning: "The use statement with 
> non-compound name 'Test1' has no effect in [...]".
> I understand the rationale behind this warning but it simply isn't true: 
> omitting the use statement results in a fatal error: "Class 
> 'Test2::Test1' not found in [...]".
> 
> Since the following code executes without warning or error I think the 
> code above (without use statement) should also execute just fine.
> 
> <?php
> namespace Test1::Test2;
> function fooBar() { echo 'Test1::Test2::fooBar()' . PHP_EOL; }
> 
> namespace Test3;
> Test1::Test2::fooBar();

This is a clear bug, please report it at bugs.php.net

Greg

---

## #36820 — Julian Reich — 2008-04-06T14:51:50+00:00

URL: https://externals.io/message/36816#36820 · In reply to: #36818

Hi,

> This is a clear bug, please report it at bugs.php.net
Done: http://bugs.php.net/44653

Since "use SomeName" does the same as "use ::SomeName" dropping the  
warning also be an option.

And if we split of "use" into "use namespace" and "use class" we could  
resolve ambiguous calls where
a namespace and a class have the same name in a way easy to  
understand. This would invalidate the
reason for the warning IMO.
Another benefit is that this way we know whether a unqualified call  
should resolve to a static method or a
namespaced function and can save lookups at runtime.
Furthermore if traits were added to PHP we can simply use "use trait  
TraitName". So there is no room
for confusion because of keyword reuse.

I think splitting of "use" was proposed on this list before but was  
never discussed.


Regards,
Julian Reich

---

## #36821 — Julian Reich — 2008-04-06T15:06:54+00:00

URL: https://externals.io/message/36816#36821 · In reply to: #36817

Hi Jessie,

> Regarding the name resolution rules, I posted a patch a few months  
> ago with what I think is a more reasonable lookup order (http://news.php.net/php.internals/34097 
> ), but did not get much feedback. Would you like to try it out? (let  
> me know if it doesn't apply cleanly against the current PHP_5_3)
I tested the patch and it works well for me.
I think if we want a predictable name resolution without speed loss  
this is the way to go.
 From an "aesthetic" point of view we could even add a PHP namespace  
(or even extension specific namespaces) and import all classes from  
the PHP namespace into the global namespace (to avoid BC break). This  
way one could use "use PHP::Exception" instead of "use ::Exception".
But I'm perfectly happy with the patch as is.

The patch didn't apply cleanly against current PHP_5_3. Therefore I  
attached an adapted version.


Regards,
Julian Reich

---

## #36822 — Julian Reich — 2008-04-06T15:18:16+00:00

URL: https://externals.io/message/36816#36822 · In reply to: #36821

> The patch didn't apply cleanly against current PHP_5_3. Therefore I  
> attached an adapted version.
Sorry, attachment missing: http://www.jreich.com/php/name_resolution.patch


Regards,
Julian Reich

---

## #36857 — Stanislav Malyshev — 2008-04-07T20:16:55+00:00

URL: https://externals.io/message/36816#36857 · In reply to: #36816

Hi!

> Executing the code above results in a warning: "The use statement with
> non-compound name 'Test1' has no effect in [...]".

This is correct, use Test1 is a no-op.

> I understand the rationale behind this warning but it simply isn't true: 
> omitting the use statement results in a fatal error: "Class 
> 'Test2::Test1' not found in [...]".

This seems to be a bug.

-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com
