7

PHP 5.6

This code:

<?php

namespace Database
{
    abstract class Model
    {

    }
}

namespace Models
{
    use Database\Model as DbModel;

    class Model extends DbModel
    {

    }
}

namespace Models
{
    use Database\Model;

    class Brand extends Model
    {

    }
}

namespace
{
    $m = new \Models\Model();
}

causes an error:

"Fatal error: Cannot use Database\Model as Model because the name is already in use in D:\OpenServer\domains\localhost\index.php on line 23".

This code:

<?php

namespace Models
{
    use Database\Model as DbModel;

    class Model extends DbModel
    {

    }
}

namespace Models
{
    use Database\Model;

    class Brand extends Model
    {

    }
}

namespace Database
{
    abstract class Model
    {

    }
}


namespace
{
    $m = new \Models\Model();
}

has no errors.

Why is this happening? Because the code has not been changed.

3
  • 1
    The error message should be pretty clear. You already have a Model class in the Models namespace so you cannot use another Model class. You should alias it using use Database\Model as DatabaseModel like in your second example. Commented Feb 26, 2015 at 11:17
  • Why in the second code, no error? Indeed, should be in the first and in the second. Commented Feb 26, 2015 at 11:19
  • 1
    Because in you second code you are aliasing the class use Database\Model as DbModel; Commented Feb 26, 2015 at 11:19

2 Answers 2

6

The ordering of your namespace clauses makes the difference here; in the first example, the Database namespace clause is declared before the clause that defines the class Models\Model.

A similar example of that difference can be found in the documentation:

(...) However, the next example causes a fatal error on name conflict because MyClass is defined in the same file as the use statement.

Separate files or same file here is simulated by moving the Database namespace below or above, respectively.

That said, the documentation also states:

It is strongly discouraged as a coding practice to combine multiple namespaces into the same file. The primary use case is to combine multiple PHP scripts into the same file.

Update

Interestingly, this problem is what Drupal 8 developers recently found out as well, but according to this bug report it has been reported more than two years ago.

A pull request has been submitted to address this issue for the next major version (it may be back ported to 5.x as well).

Sign up to request clarification or add additional context in comments.

2 Comments

Additional question: what Model class is extended by class Brand in the example that works? And why?
1

After few tests: PHP file with few namespaces behave difficult to understand, try to do not use more then one namespace in one file.

(It's because of linking to not existing classes while parsing [of one file!] that change order of PHP parsing, C++ things [pointers] - I can't explain that.)

As PHP doc says: "It is strongly discouraged as a coding practice to combine multiple namespaces into the same file."

More about tests I did and documentation we studied to find it out:

https://chat.stackoverflow.com/rooms/71776/discussion-between-axiac-and-jack

1 Comment

The PHP FAQ page about namespaces warns about the conflict exposed in the question. It doesn't explain why it happens, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.