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.
A namespace is a hierarchically labeled code block holding a regular PHP code. A namespace can contain valid PHP code. Namespace affects following types of code: classes (including abstracts and traits), interfaces, functions, and constants. Namespaces are declared using the namespace keyword.
In the PHP world, namespaces are designed to solve two problems that authors of libraries and applications encounter when creating re-usable code elements such as classes or functions: Name collisions between code you create, and internal PHP classes/functions/constants or third-party classes/functions/constants.
Namespaces are qualifiers that solve two different problems: They allow for better organization by grouping classes that work together to perform a task. They allow the same name to be used for more than one class.
Multiple namespaces may also be declared in the same file. There are two allowed syntaxes. This syntax is not recommended for combining namespaces into a single file. Instead it is recommended to use the alternate bracketed syntax.
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.
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).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With