using of global namespaces and multiple namespaces in one PHP file increase the complexity and decrease readability of the code.
Let's try not use this scheme even it's very necessary (although there is not)
(PHP 5 >= 5.3.0, PHP 7)
Multiple namespaces may also be declared in the same file. There are two allowed syntaxes.
Example #1 Declaring multiple namespaces, simple combination syntax
<?php
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>
This syntax is not recommended for combining namespaces into a single file. Instead it is recommended to use the alternate bracketed syntax.
Example #2 Declaring multiple namespaces, bracketed syntax
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
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.
To combine global non-namespaced code with namespaced code, only bracketed syntax is supported. Global code should be encased in a namespace statement with no namespace name as in:
Example #3 Declaring multiple namespaces and unnamespaced code
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
No PHP code may exist outside of the namespace brackets except for an opening declare statement.
Example #4 Declaring multiple namespaces and unnamespaced code
<?php
declare(encoding='UTF-8');
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
using of global namespaces and multiple namespaces in one PHP file increase the complexity and decrease readability of the code.
Let's try not use this scheme even it's very necessary (although there is not)
<?php
// You cannot mix bracketed namespace declarations with unbracketed namespace declarations - will result in a Fatal error
namespace a;
echo "I belong to namespace a";
namespace b {
echo "I'm from namespace b";
}
<?php
//Namespace can be used in this way also
namespace MyProject {
function connect() { echo "ONE"; }
Sub\Level\connect();
}
namespace MyProject\Sub {
function connect() { echo "TWO"; }
Level\connect();
}
namespace MyProject\Sub\Level {
function connect() { echo "THREE"; }
\MyProject\Sub\Level\connect(); // OR we can use this as below
connect();
}
If you have the habit to always use the closing PHP tag "?>" in your test files, remember that with the bracketed syntax code outside the brackets, including new lines outside the PHP tags, is not allowed. In particular, even though PHP sees a new line after the closing tag as a part of the line and eats it, some editors, such as Gedit, Gvim, Vim and Nano in Ubuntu, will add yet another new line after this new line and this will create an error.
//call same named function using namespace
//food.php
<?php
namespace Food;
require ('Apple.php');
require('Orange.php');
use Apples;
use Oranges;
Apples\eat();
Oranges\eat();
?>
//Apple.php
<?php
namespace Apples;
function eat()
{
echo "eat apple";
}
?>
//Orange.php
<?php
namespace Oranges;
function eat()
{
echo "eat Orange";
}
?>
Notice it's not allowed to mix bracketed namespace with unbracketed namespace declarations.
<?php
namespace MyTest;
const TEST = 777;
//in this way
echo \MyTest\TEST . '<br />';
//Or this way
echo TEST . '<br />';
namespace AnotherTest {
const TEST = 555;
echo \AnotherTest\TEST . '<br />';
echo \MyTest\TEST;
}
?>
This code will issue a fatal error, like this: Fatal error: Cannot mix bracketed namespace declarations with unbracketed namespace declarations in C:\xampp\htdocs\teste2.php on line 11.
There are rational examples of where the ability to blend multiple namespaces into a single file is not only desirable but also absolutely necessary. An example of where this ability is useful is over in the very popular phpseclib library where they are PSR-4 compliant but, in order to be compliant, they have to read a directory of files to know what classes are available so that the autoloader can load the correct files. If they, instead, just bundled the defaults into one file using this mechanism already supported by PHP core, there would be no need to do extraneous scanning of the file system.
That's just one legitimate use-case where strict compliance with PSRs gets in the way of good software development.
Be careful with include combined to namespaces:
file b.php
<?php
const WHERE_I_AM = 'I am in B';
function i_am_in() {
\A\cr_echo(WHERE_I_AM);
}
?>
file c.php
<?php
namespace C {
const WHERE_I_AM = 'I am in C';
function i_am_in() {
\A\cr_echo(WHERE_I_AM);
}
}
?>
main file
<?php
namespace A {
const CR = "\r\n";
const WHERE_I_AM = 'I am in A';
function cr_echo($msg) {
echo $msg . CR;
}
function i_am_in() {
cr_echo(WHERE_I_AM);
}
}
namespace B {
require 'b.php';
}
namespace {
require 'c.php';
\A\i_am_in(); //ok
\B\i_am_in(); // fatal-error
\C\i_am_in(); //ok
}
?>
With the bracketed syntax, a simple white space after the closing "?>" of the file, even a new line that is some times considered as the end of a line and thus a part of the line, will (at the least in some php installations) be considered as code outside the brackets and will result in an error. It's general good practice to avoid white space after the closing "?>". Just pointing out that it is another case where it matters.
In addition to kothnok at gmail dot com
When using namespaces with brackets, you should define the USE statements within the brackets. His example sets the global use for the file.
<?php
namespace Space1;
use SomeNamespace\FunctionCollection as FC;
{
FC\hello_world();
}
namespace Space2;
{
// This can be used here
FC\hello_world();
}
?>
While the preferred method with brackets is this:
<?php
namespace Space1
{
use SomeNamespace\FunctionCollection as FC;
FC\hello_world();
}
namespace Space2;
{
// This will not work now
FC\hello_world();
}
?>