php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51225 cannot define a class with the same name as an interface
Submitted: 2010-03-06 18:50 UTC Modified: 2016-01-16 12:37 UTC
Votes:5
Avg. Score:3.4 ± 0.8
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: xiaodujinjin at gmail dot com Assigned: johannes (profile)
Status: Closed Package: Class/Object related
PHP Version: master OS: Windows XP MT15i
Private report: No CVE-ID: None
 [2010-03-06 18:50 UTC] xiaodujinjin at gmail dot com
Description:
------------
When I try to define a particular class it fails with "cannot redeclare class ...". When I check with class_exists('...') it returns false, but I still cannot create it. I eventually found some previous code which uses the same name to define an interface.

Test script:
---------------
Interface Singleton{public static function instance();}
if (class_exists('Singleton')) {
    $reason = 'class already exists';
} else {
    class Singleton{
        static function getInstance(){
            return true;
        }
    }
}

Expected result:
----------------
If it is not possible to define a class and an interface with the same name, then the class_exists() function should also include interface names.

If it IS possible to have a class and an interface with the same name, then the compiler should NOT reject the second reference.


Patches

1314609a (last revision 2012-05-20 02:45 UTC by xiaodujinjin at gmail dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-08 00:02 UTC] kalle@php.net
-Status: Open +Status: Bogus
 [2010-03-08 00:02 UTC] kalle@php.net
Thats how the OO is designed, internally is interfaces just a class with an additional flag.

So no bug here
 [2010-03-08 00:23 UTC] tony at marston-home dot demon dot co dot uk
If an interface is a class, then it should show up in class_exists() and get_declared_classes().
 [2010-03-08 00:28 UTC] derick@php.net
-Status: Bogus +Status: Re-Opened
 [2010-03-08 00:28 UTC] derick@php.net
Yes, I agree.
 [2010-03-08 00:55 UTC] johannes@php.net
I think the error message ("Cannot redeclare class") should be clearer about classes and interfaces sharing the same namespace, which is needed as type hints would be conflicting otherwise, but class_exists (by default) should only check classes in my opinion. Any change should consider that there's also interface_exists() and they should be consistent.
 [2010-03-08 10:35 UTC] tony at marston-home dot demon dot co dot uk
I disagree. class_exists() SHOULD check if that name has already been declared as an interface otherwise you get the following situation:

if (!class_exists('foobar') {  // returns false
    class foobar{}             // fails because interface exists
}

On the one hand it is saying "a class with the name 'foobar' does not exist" which is immediately followed by "you cannot create a class with the name 'foobar' as it already exists". That is not logical to me.
 [2010-06-08 15:05 UTC] tony2001@php.net
-Status: Re-Opened +Status: Assigned -Assigned To: +Assigned To: johannes
 [2010-08-05 23:38 UTC] bobalicious dot bob at gmail dot com
In my opinion, in order to be valid the code snippet should read:

if (!class_exists('foobar') && !interface_exists('foobar') ) {
    class foobar{}
}

The error message on attempting to declare a class with the same name as an 
interface should respond:
Cannot declare class as an interface exists with that name
The reverse message should also be possible.

It does not make sense to allow an interface and a class to have the same name 
(type hinting is a great example why not), and 'class_exists' should only refer 
to classes (the clue's in the name).

The confusion is merely down to an inaccurate error message.

Note: There's a reason it's not uncommon for people to prefix interfaces with an 
'i'
 [2010-09-23 08:03 UTC] i at walkinraven dot name
I think you the fact of class and interface sharing a same namespace should be clearly written into the manual!

And the better way, the two should not share a same namespace at all.

It waste me some much time to check my project.
 [2012-03-20 21:05 UTC] LaKing at D250 dot hu
The language-developers have two options. Either a clearer error message as a quick-fix, or allowing interfaces and classes with the same name, with the necessary underlying updates properly implemented in the language. That would be the elegant, and logical way.
 [2012-05-20 02:39 UTC] xiaodujinjin at gmail dot com
xiaodujinjin@gmail.com
 [2012-05-20 02:39 UTC] xiaodujinjin at gmail dot com
-: tony@marston-home.demon.co.uk +: xiaodujinjin at gmail dot com -Operating System: Windows XP +Operating System: Windows XP MT15i
 [2012-05-20 02:40 UTC] xiaodujinjin at gmail dot com
xiaodujinjin@gmail.com
 [2013-08-06 10:04 UTC] yohgaki@php.net
-PHP Version: 5.2.13 +PHP Version: master
 [2016-01-16 12:37 UTC] danack@php.net
-Status: Assigned +Status: Closed
 [2016-01-16 12:37 UTC] danack@php.net
This was improved in PHP 7. For the code:

interface foo {}
class foo implements foo {}
new foo();

The error message is now:

Fatal error: Cannot declare class foo, because the name is already in use in /in/Nnh4T on line 6


Which I believe meets the criteria of "a clearer error message as a quick-fix,"
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Sep 21 17:01:27 2019 UTC