namespaces: import name conflicts with defined class

php.internals

Benjamin Schulz

18 years ago
Hi all, import Foo::Bar AS DomDocument; import Foo::Exception; import MyStuff::Dom::XsltProcessor; Result in a "Fatal error: Import name '...' conflicts with defined class" Of course i want to refer to my own exception in my application or framework as "Exception", and of course i want to use it without prefixes (import myStuff::Exception AS MyStuffException), i wouldn't use namespace otherwise (there is no other benefit, right?). It's not that one accidentally puts an "import Foo::Exception" in his file .. Is there a good reason for this bevhaviour that i don't see? There is still ::Exception to access the class in the global namespace. regards, Benjamin

Greg Beaver

18 years ago
Benjamin Schulz wrote:
> Hi all, > > import Foo::Bar AS DomDocument; > import Foo::Exception; > import MyStuff::Dom::XsltProcessor; > > Result in a "Fatal error: Import name '...' conflicts with defined class" > Of course i want to refer to my own exception in my application or > framework as "Exception", and of course i want to use it without > prefixes (import myStuff::Exception AS MyStuffException), i wouldn't use > namespace otherwise (there is no other benefit, right?). > It's not that one accidentally puts an "import Foo::Exception" in his > file .. > > Is there a good reason for this bevhaviour that i don't see? There is > still ::Exception to access the class in the global namespace. > > regards, > Benjamin
Hi Benjamin, If you are aliasing a class to the same name as an existing class, you should also import that class with another name: <?php import ::Exception as Notused; import Foo::Exception; ?> This is somewhat unintuitive, but is pretty simple to solve. Greg

Stanislav Malyshev

18 years ago
> <?php > import ::Exception as Notused; > import Foo::Exception; > ?>
I wouldn't actually recommend using such code. If you have Foo::Exception just use Foo::Exception - it's short enough :)
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Benjamin Schulz

18 years ago
On 02.10.2007, at 22:04, Stanislav Malyshev wrote:
>> <?php >> import ::Exception as Notused; >> import Foo::Exception; >> ?> >> > > I wouldn't actually recommend using such code. If you have > Foo::Exception just use Foo::Exception - it's short enough :) >
And what if not? "throw App::package::subpackage::Exception" in a file that has the namespace "App::package::subpackage" is just wrong, importing the Exception as a different name as well. Importing the global Exception as something else - i don't even know what to answer to that ... this problem makes the whole concept just seem broken, is there even a concept? ;) regards, Benjamin

Greg Beaver

18 years ago
Benjamin Schulz wrote:
> On 02.10.2007, at 22:04, Stanislav Malyshev wrote: > > >>> <?php >>> import ::Exception as Notused; >>> import Foo::Exception; >>> ?> >>> >> >> I wouldn't actually recommend using such code. If you have >> Foo::Exception just use Foo::Exception - it's short enough :) >> > > And what if not? "throw App::package::subpackage::Exception" in a file > that has the namespace "App::package::subpackage" is just wrong, > importing the Exception as a different name as well. Importing the > global Exception as something else - i don't even know what to answer to > that ... this problem makes the whole concept just seem broken, is there > even a concept? ;) > > regards, > Benjamin
<?php namespace test; class Exception {} $a = new Exception('hi'); ?> The above code works just fine. Yes there is a concept. import is best used within a namespace. So, namespace your code and there is no need to import global classes. Greg

Benjamin Schulz

18 years ago
>> > <?php > namespace test; > class Exception {} > $a = new Exception('hi'); > ?> > > The above code works just fine. > > Yes there is a concept. import is best used within a namespace. So, > namespace your code and there is no need to import global classes.
Yep, it works if your whole application uses one namespace, but what if you have a core package that defines some exceptions and another package, with a different namespace, that wants to use the core exceptions? Like namespace App; class Exception extends Exception { ... } and in another File: namespace App::Db; import App::Exception; .... This doesn't work. And worse: imagine PEAR would bring a PEAR::Exception along, PEAR would be my basic framework and i wouldn't care about ::Exception, i don't even know it's there - i am using PEAR. In every Script i would like to use PEAR::Exception in a convenient way i have to write: <?php import ::Exception AS WTF; import PEAR::Exception; ?> (Nevermind if this example doesn't fit the PEAR-idea, just s/PEAR/ randomFramework/g then) You think this makes sense? Or what about this: pear/Mail_IMAP/IMAP.php (dunno if this file exists): <?php namespace PEAR::Mail::IMAP; import ::Exception AS WTF; import PEAR::Exception; class Imap { ... } All this seems just wrong to me, sorry. And i fully agree with Markus:
> But how to know in advance, e.g. think about other libraries, which > public classes possibly exist? Isn't this problematic then?
Let's say i PEAR would have namespaces and there is a class PEAR::DB::Mysql, i use this class as: <?php import PEAR::DB::Mysql; class MyDb extends Mysql { ... } And surprisingly someday mysqlnd declares a class named "Mysql", that would break my code even though i explicitly declared that i want "PEAR::DB::Mysql" not some different Mysql class that comes from some fancy extension the admin added today. So, why this behaviour? regards, Benjamin

Stanislav Malyshev

18 years ago
> import ::Exception AS WTF;
import isn't the means to shuffle standard class names around. Import is the means to make names shorter. You already have one Exception in global space, you'd have to use other name for other class.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Marcus Börger

18 years ago
Hello Benjamin, if your exception is so general that it is called exception you can obviously simply use exception. If your exception is actually doing something than name that something. Meaning the name of the exception class is carrying information already. Thus every exception should be specialized. Now namespaces are a tool to help you structure your code and avoid naming issues. They are not a tool to shorten your names or aid you in typing less. And especially namespaces are not there to overcome any naming limitations or tricking the naming rules. marcus Wednesday, October 3, 2007, 11:19:00 AM, you wrote:
> On 02.10.2007, at 22:04, Stanislav Malyshev wrote:
>>> <?php >>> import ::Exception as Notused; >>> import Foo::Exception; >>> ?> >>> >> >> I wouldn't actually recommend using such code. If you have >> Foo::Exception just use Foo::Exception - it's short enough :) >>
> And what if not? "throw App::package::subpackage::Exception" in a > file that has the namespace "App::package::subpackage" is just wrong, > importing the Exception as a different name as well. Importing the > global Exception as something else - i don't even know what to answer > to that ... this problem makes the whole concept just seem broken, is > there even a concept? ;)
> regards, > Benjamin
Best regards, Marcus

Benjamin Schulz

18 years ago
> > if your exception is so general that it is called exception you can > obviously simply use exception.
Maybe _my_ exception is a generic exception in _my_ framework and implements some helper functions i need? But the discussion is not about exceptions, it's about classnames that PHP declares i don't want to care about, because i put my classes in "namespaces". Maybe i don't use DOM and i don't know (i don't want to know) that there is a "XsltProcessor" class, i implemented a xsltprocessor myself, a generic one ;). So i need to name it GenericXsltProcessor because luckily currently there is no other class with that name (yet)? Come on ... Who knows what classes SPL or some pecl extension will declare some day, to me this is like a guarantee that future PHP releases, or extensions, will break applications that use namespaces. Sounds quite ironic to me. regards, Benjamin

Marcus Börger

18 years ago
Hello Benjamin, Wednesday, October 3, 2007, 5:33:21 PM, you wrote:
>> >> if your exception is so general that it is called exception you can >> obviously simply use exception.
> Maybe _my_ exception is a generic exception in _my_ framework and > implements some helper functions i need?
The exception example is well an exception. Here you must inherit exception. That is simply how PHP works, it is an intended limitation. That said in this case you should not use Exception for your own stuff. Name it after your library or product, like MyProductException.
> But the discussion is not > about exceptions, it's about classnames that PHP declares i don't > want to care about, because i put my classes in "namespaces". Maybe i > don't use DOM and i don't know (i don't want to know) that there is a > "XsltProcessor" class, i implemented a xsltprocessor myself, a > generic one ;). So i need to name it GenericXsltProcessor because > luckily currently there is no other class with that name (yet)? Come > on ...
Right, you might want to have a class DOM because DOM means something different for your company.
> Who knows what classes SPL or some pecl extension will declare some > day, to me this is like a guarantee that future PHP releases, or > extensions, will break applications that use namespaces. Sounds quite > ironic to me.
SPL like any other extension will get it's own namespace or has to use prefixed classnames. Generally you should do all your stuff in a namespace and do not import anything into the global namespace. That should avoid the problem. If not we need to fix that.
> regards, > Benjamin
Best regards, Marcus

Benjamin Schulz

18 years ago
> > The exception example is well an exception. Here you must inherit > exception. > That is simply how PHP works, it is an intended limitation. That > said in > this case you should not use Exception for your own stuff. Name it > after > your library or product, like MyProductException. >
Hey, i have an idea, why not use namespaces and call it MyProduct::Exception and name everything MyProduct::* - this way i won't get in conflict with global classes, oh wait ...
> Right, you might want to have a class DOM because DOM means something > different for your company. >
Yep, that's why i call it Company::DomDocument, and hey, everyone with a different namespace can import it in his file as "DomDocument", right? That sounds very comfortable to me. *sigh*
> Generally you should do all your stuff in a namespace and do not > import > anything into the global namespace. >
You know that import works per File, right? There is no risk that one accidently tries to catch a MyProduct::Exception if he consciously used "import MyProduct::Exception;" in his file. regards, Benjamin

Moritz Bechler

18 years ago
Hi internals, I think you are conentrating on the Exception (and even internal class) examples a bit too much. Take the following example: -------- a.php: <?php // 1. Some library which does not use namespaces and defines a class Foo include("b.php"); // 2. Some part of a library using namespaces include("c.php"); // 3. Some other part of the namespace-using library include("d.php"); ?> -------- b.php: <?php class Foo { } ?> -------- c.php: <?php namespace Bar; class Foo { } ?> -------- d.php: <?php namespace Bar::Other; import Bar::Foo; ?> -------- Running this example produces a "Fatal error: Import name 'Foo' conflicts with defined class in [...]/d.php on line 4". This problem does not only exist with internal classes (which is bad enough - still remember DateTime?) but also when some non-namespaced code might be used in conjunction. As using namespaces is about preventing naming collisions having to assume that some class "Foo" does not exist while developing the library using namespaces is just inacceptable and makes the namespace implementation pretty useless. And if you start arguing that you should not use import in cases where you don't control the global scope you could pretty much argue not to use it at all and remove it (which makes namespaces some eye-candy for very long class names). best regards Moritz Bechler

Markus Fischer

18 years ago
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Greg Beaver wrote:
> Benjamin Schulz wrote: >> Of course i want to refer to my own exception in my application or >> framework as "Exception", and of course i want to use it without >> prefixes (import myStuff::Exception AS MyStuffException), i wouldn't use >> namespace otherwise (there is no other benefit, right?). > > If you are aliasing a class to the same name as an existing class, you > should also import that class with another name: > > <?php > import ::Exception as Notused; > import Foo::Exception; > ?> > > This is somewhat unintuitive, but is pretty simple to solve.
But how to know in advance, e.g. think about other libraries, which public classes possibly exist? Isn't this problematic then? - - Markus -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHAqaZ1nS0RcInK9ARAorCAJ9BzOIgcJLqAjK6Oycuy2BLA5YHVQCgn/T/ 06+XdBwY4HSJ6aXJzZU1Sh8= =MRLP -----END PGP SIGNATURE-----

Stanislav Malyshev

18 years ago
> But how to know in advance, e.g. think about other libraries, which > public classes possibly exist? Isn't this problematic then?
That should be simple - if you write library using namespaces, no public classes would exist except for the internal ones :)
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Stanislav Malyshev

18 years ago
>> But how to know in advance, e.g. think about other libraries, which >> public classes possibly exist? Isn't this problematic then? > > That should be simple - if you write library using namespaces, no public > classes would exist except for the internal ones :)
By "public" I of course mean "belonging to the global space", even though it's not correct use of the term :)
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Marcus Börger

18 years ago
Hello Stanislav, perfectly right :-) Tuesday, October 2, 2007, 10:21:20 PM, you wrote:
>> But how to know in advance, e.g. think about other libraries, which >> public classes possibly exist? Isn't this problematic then?
> That should be simple - if you write library using namespaces, no public > classes would exist except for the internal ones :)
> -- > Stanislav Malyshev, Zend Software Architect > stas@zend.com http://www.zend.com/ > (408)253-8829 MSN: stas@zend.com
Best regards, Marcus

Marcus Börger

18 years ago
Hello Benjamin, naive question: how do you define your exception which needs to onherit Exception? Are you doing this: class Exception extends ::exception { } ??? marcus p.s.: I think that is really ugly and actually sounds like replacing a core functionality... Tuesday, October 2, 2007, 1:56:04 PM, you wrote:
> Hi all,
> import Foo::Bar AS DomDocument; > import Foo::Exception; > import MyStuff::Dom::XsltProcessor;
> Result in a "Fatal error: Import name '...' conflicts with defined > class" > Of course i want to refer to my own exception in my application or > framework as "Exception", and of course i want to use it without > prefixes (import myStuff::Exception AS MyStuffException), i wouldn't > use namespace otherwise (there is no other benefit, right?). > It's not that one accidentally puts an "import Foo::Exception" in his > file ..
> Is there a good reason for this bevhaviour that i don't see? There is > still ::Exception to access the class in the global namespace.
> regards, > Benjamin
Best regards, Marcus

Stanislav Malyshev

18 years ago
> naive question: how do you define your exception which needs to onherit > Exception? > > Are you doing this: > > class Exception extends ::exception { }
Inside namespace - yes, that's the best way. In fact, I think Exception extends Exception may work too, but that would be seriously confusing :)
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com