php namespace

I never used php namespace as my project is not complex enough to use it. But a small project cannot prevent some programming guru from using namespace. The result is I’m often confused by the use keyword. The syntax of the use keyword is like:

  • use namespace;
  • use namespace as;
  • use namespace\class;
  • use namespace\class as;
  • use class;

What does the use syntax mean?

use foo\bar is equal with use foo\bar as bar, i.e., the former is shortened for the latter. Similarly, use namespace\class is equal with use namespace\class as class. Using these syntax can save you typing more characters thereafter. If you want to call a function or new a class defined in some namespace rather than the global namespace, you must prefix the namespace before the function name or the class name such as:

$a=new foo\bar\myclass;
$b=foo\bar\myfunction();

If you do not do so as you are calling a function in global namespace or instancing an object of a class defined in global namespace, you will get the error:

Fatal error: Call to undefined function myfunction()

or,

Fatal error: Class ‘myclass’ not found

The full function name/class name that includes a namespace prefix is too long to type. In this case, you can use the use function to shorten the function/class name:

use foo\bar;
//use foo\bar as bar;
$a=new bar\myclass;
$b=bar\myfunction();

You can further shorten the class name by:

use foo\bar\myclass;
//use foo\bar\myclass as myclass;
$a=new myclass;
use foo\bar;
$b=bar\myfunction();

Unfortunately, you cannot use use foo\bar\myfunction to shorten myfunction for foo\bar\myfunction. To call function in another namespace, you must type at least one namespace before the function name.

To define functions/classes in a namespace rather than the global one, you must first define/declare the namespace:

namespace foo\bar;
class myclass{}
function myfunction(){}

Here, we actually define two namespaces: foo and bar, where bar is nested inside foo. The class myclass and the function myfunction are defined within the bar namespace.  We do not need to define something inside the foo namespace before defining the class/function inside the bar namespace. The most confusing thing about the namespace statement is the lacking of the back-slash before the first namespace name. It seems you are declaring a namespace under the current namespace but in fact you are declaring the namespace in the global namespace. (Remember the absolute path/relative path of file system?) If you write a backslash at the beginning of the full namespace name like:

namespace \foo\bar;
class myclass{}
function myfunction(){}

you will get this error:

Fatal error: Undefined constant ‘foo\bar’

You cannot nest a namespace in current namespace like:

namespace foo
{
     .....
     namespace bar
     {
         ....
     }
    .....
}

which will produce the following error:

Fatal error: Namespace declarations cannot be nested in …

Trying to do the following also fails:

namespace foo
{
    .....
     namespace bar;

    .....
}

The error is:

Fatal error: Cannot mix bracketed namespace declarations with unbracketed namespace declarations in …

In summary, although you can define hierarchical namespace using the backslash syntax, you cannot define a new namespace within another. You must define a new namespace after ending the previous namespace, and you must provide the full paths in the namespace statement(there is no concept of relative path for the use statement and the namespace statement).

namespace foo;
..........
namespace foo/bar;

The effect of the namespace statement does not cross scripts. If you create a namespace in A script, which is included in B script at the beginning, the namespace of A does not include the content in script B, and script B is in global namespace.

Although there is no concept of relative path for the use statement and the namespace statement, the hierarchical namespace without the heading backslash is considered a relative path when being referred to in calling the function or using class in different namespace. So, you will get an error in the example below:

namespace foo\bar;
$a=new stdClass;

Fatal error: Class ‘foo\bar\stdClass’ not found

This is because when referring to stdClass that is defined in global namespace, we did not prefix it with a backslash, and php will search the class in current namespace, i.e., foo\bar. The correct code is:

namespace foo\bar;
$a=new \stdClass;

In other words, in your own namespace, you can only use class in same namespace if you do not provide its namespace. To use class from global namespace, you can also use the last form of the syntax of the use keyword:

namespace foo\bar;
use stdClass;
$a=new stdClass;

Now, you can use stdClass as usual without prefixing the global namespace because php finds variable names/function names without beginning backslash as relative one and firstly try to think the first word(separated by backslash) as an alias(in this case the stdClass is an alias of \stdClass as defined by the use keyword) and find the expand name(\stdClass). If no alias was defined for the first word, php would look for the name in current namespace(\foo\bar\stdClass). The use statement, however, does not use the alias mechanism.

The namespace paths in the use statement is like those in the namespace statement, i.e., without a beginning backslash, the paths still start from the global namespace. Unlike the namespace statement, you can add the backslash at the beginning of the namespace paths, which won’t lead to an error.

 

Did you like this?
Tip admin with Cryptocurrency

Donate Bitcoin to admin

Scan to Donate Bitcoin to admin
Scan the QR code or copy the address below into your wallet to send some bitcoin:

Donate Bitcoin Cash to admin

Scan to Donate Bitcoin Cash to admin
Scan the QR code or copy the address below into your wallet to send bitcoin:

Donate Ethereum to admin

Scan to Donate Ethereum to admin
Scan the QR code or copy the address below into your wallet to send some Ether:

Donate Litecoin to admin

Scan to Donate Litecoin to admin
Scan the QR code or copy the address below into your wallet to send some Litecoin:

Donate Monero to admin

Scan to Donate Monero to admin
Scan the QR code or copy the address below into your wallet to send some Monero:

Donate ZCash to admin

Scan to Donate ZCash to admin
Scan the QR code or copy the address below into your wallet to send some ZCash:
Posted in

Leave a Reply