Jump to content

Problem with "use" namespace keyword.


trq

Recommended Posts

I have here what I would refer to as doozy. I'm not sure anyone is going to be able to help as there is allot involved.

 

The issue could be in a number of locations, I am using PHPUnit as a test suite (and this is how I have found the issue) and PHP5.4rc5. The problem could be in either, or it could be in my code.

 

I am also using a cascading filesystem (explained here) and while I'm confident this isn't the issue. It has the potential to be involved I guess. If you need to see how this is implemented it is see here: https://github.com/proem/proem/blob/develop/lib/Proem/Api/Autoloader.php#L108

 

I have narrowed the problem down to two classes:

 

https://github.com/proem/proem/blob/develop/lib/Proem/Api/Chain.php & https://github.com/proem/proem/blob/develop/lib/Proem/Api/Proem.php

 

The tests that test these classes are:

 

https://github.com/proem/proem/blob/develop/tests/lib/Proem/Tests/ChainTest.php & https://github.com/proem/proem/blob/develop/tests/lib/Proem/Tests/ProemTest.php

 

As the code stands right now, everything is fine and all tests pass. However, I am about to start some more work on the Proem\Api\Proem class and it needs access to the Proem\Api\Chain class.

 

To do this, I add the line "use Proem\Chain;", the code becomes:

 

<?php

/**
* @namespace Proem\Api
*/
namespace Proem\Api;

use Proem\Chain;

/**
* Proem\Api\Proem
*
* The Proem boostrap wrapper (eventually)
*/
class Proem
{
    const VERSION = '0.1.0';
}

 

As soon as I do this the tests fail with:

 

Fatal error: Cannot use Proem\Chain as Chain because the name is already in use in /home/thorpe/src/proem/lib/Proem/Api/Proem.php on line 32

 

If I alias the namespace ( "use Proem\Chain as C;" ) the tests pass again. The issue is I shouldn't have to use an alias here.

 

from the manual:

Note:

 

Importing rules are per file basis, meaning included files will NOT inherit the parent file's importing rules.

 

Writing this post I have come to realise that the issue is likely that both the Chain class and the Proem class are in the same namespace yet I am trying to force the Chain class to be loaded from Proem\Chain instead of Proem\Api\Chain (this is part of the cascading filesystem setup).

 

Anyway, if anyone has some ideas I would be grateful if you could take a look. Otherwise, it looks like I might need to do some re-shuffling.

 

Iv'e created a ticket for this bug if anyone wan't to chip in. See here

Link to comment
Share on other sites

Hi Andy-H, I did try pulling it from the global \Proem but it shouldn't need to and that doesn't work either.

 

One thing (and probably the most important thing) I forgot to mention is that if I remove the ChainTest from the test suite all tests pass. So the issue isn't in Proem.php alone, it is only introduced when the ChainTest is also run.

Link to comment
Share on other sites

Surely if you're already in the namespace \Proem\Api, and you want to call \Proem\Api\Chain, you should just need

 

 

use Chain;

 

 

Or does use only call from absolute paths?

 

Generally you wouldn't even need to call "use Chain" because Chain is in the same namespace so you can just go ahead and use it.

 

As the link to the "cascading filesystem" stuff points out however, it's not so simple in this case.

 

All classes within Proem are actually created in the Proem\Api\ namespace. However, when you go to use one you must always use it from Proem\

 

Lets use Foo as an example:

 

use Proem\Foo;{/php]

This searches the Proem namespace for Foo, when not found, it will then search Proem\Api. Once located it will alias the class to Proem\Foo and give you access to it. 

Interanally all classes are declared in Proem\Api\ yet used from Proem\

This means that a user can override the functionality of Foo throughout the entire framework without needing to hack the framework itself. You would simply create a file within the Proem namespace and extend Proem\Api\Foo

[code=php:0]

namespace Proem;

class Foo extends \Proem\Api\Foo {}

 

Now, anywhere (including within the framework itself) that access Proem\Foo will get your new class instead of the original one declared within Proem\Api\Foo which it would normally get.

 

I understand that there is a bit going on here, but this functionality allows great flexability and for the most part it is working.

 

I'm at work at the moment but will be investigating this issue tonight when I get home as it is blocking progress. I'll let you guys know if I find a solotion.

 

I already had an idea of moving all components into there own namespace anyway (not because of this issue), so this might be the raod I end up travelling down.

 

Thanks for taking a look.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.