Deep application of PHP namespace rules

Source: Internet
Author: User
Tags autoload

In the first part, we introduced the usage of the PHP namespace and the namespace keyword. In this article, we will introduce the use of the use command and how PHP resolves the namespace name.

To facilitate the comparison, I have defined two almost identical code blocks, only with different namespaces.

Lib1.php

<? PHP
// Application library 1
Namespace APP/lib1;

Const myconst = 'app/lib1/myconst ';

Function myfunction (){
Return _ FUNCTION __;
}

Class myclass {
Static function whoami (){
Eturn _ method __;
}
}
?>

Lib2.php

<? PHP
// Application library 2
Namespace APP/lib2;

Const myconst = 'app/lib2/myconst ';

Function myfunction (){
Return _ FUNCTION __;
}

Class myclass {
Static function whoami (){
Eturn _ method __;
}
}
?>

Before you start, you must understand several terms related to PhP namespaces.

◆ Fully qualified name (fully-qualified name)

Any PHP code can reference a fully qualified name. It is an identifier starting with a namespace backslash, such as/APP/lib1/myconst,/APP/lib2/myfunction.

The fully qualified name is unambiguous. The backslash at the beginning is similar to the file path. It indicates the global space of "root, if we implement a different myfunction () in the global space, we can use/myfunction () to call it from lib1.php or lib2.php.

Fully qualified names are very useful for one-time function calls or object initialization, but they do not have practical value when you generate a large number of calls. As we will see in the following discussion, PHP provides other options to ease typing in namespaces.

◆ Qualified name)

There must be at least one namespace separator identifier, such as lib1/myfunction ().

◆ Unqualified name)

There is no namespace separator identifier, such as myfunction ().

Work in the same namespace

Think carefully about the following code:

Myapp1.php

<? PHP
Namespace APP/lib1;

Require_once ('lib1. php ');
Require_once ('lib2. php ');

Header ('content-type: text/plain ');
Echo myconst. "/N ";
Echo myfunction (). "/N ";
Echo myclass: whoami (). "/N ";
?>

Even if we include both lib1.php and lib2.php, myconst, myfunction, and myclass identifiers, we can only reference them in lib1.php because the code of myapp1.php is in the same app/lib1 namespace.

Execution result:

APP/lib1/myconst APP/lib1/myfunction APP/lib1/myclass: whoami

Namespace Import

You can use the use operator to import namespaces, for example:

Myapp2.php

<? PHP
Use APP/lib2;

Require_once ('lib1. php ');
Require_once ('lib2. php ');

Header ('content-type: text/plain ');
Echo lib2/myconst. "/N ";
Echo lib2/myfunction (). "/N ";
Echo lib2/myclass: whoami (). "/N ";
?>

You can define any number of use statements or use commas to separate them into independent namespaces. In this example, we imported the APP/lib2 namespace, but we still cannot directly reference myconst, myfunction and myclass, because our code is still in the global space, but if we add the "lib2/" prefix, they will become qualified names, PHP searches for the imported namespace until a match is found.

Execution result:

APP/lib2/myconst APP/lib2/myfunction APP/lib2/myclass: whoami

Namespace alias

A namespace alias may be the most useful concept. It allows us to reference a long namespace with a short name.

Myapp3.php

<? PHP
Use APP/lib1 as L;
Use APP/lib2/myclass as OBJ;

Header ('content-type: text/plain ');
Require_once ('lib1. php ');
Require_once ('lib2. php ');

Echo L/myconst. "/N ";
Echo L/myfunction (). "/N ";
Echo L/myclass: whoami (). "/N ";
Echo OBJ: whoami (). "/N ";
?>

The first use statement defines APP/lib1 as "L". Any qualified name using "L" will be translated into "app/lib1" during compilation ", therefore, we can reference L/myconst and L/myfunction instead of fully qualified names.

The second use statement defines "OBJ" as the alias of the myclass class in the app/lib2/namespace. This method is only applicable to classes and cannot be used for constants and functions, now we can use new OBJ () or run the static method as above.

Execution result:

APP/lib1/myconst APP/lib1/myfunction APP/lib1/myclass: whoami APP/lib2/myclass: whoami

PHP naming rules

The PHP identifier name is parsed using the following namespace rules. For more information, see the PHP user manual:

1. Call fully qualified functions, classes, or constants during compilation;

2. for example, if a/B/c is imported as C, call C/D/E () it will be translated into A/B/C/D/E ();

3. in the PHP namespace, all qualified names have not been converted according to the import rules. For example, if C/D/E () is called in namespace a/B (), it will be translated into A/B/C/D/E ();

4. the unqualified class name is converted according to the current import rule, and the short name of the import is replaced by the full name. For example, if Class C is imported as X in namespace a/B, then new x () will be translated into new A/B/C ();

5. non-limited function calls in a namespace are parsed at runtime. For example, if myfunction () is called in namespace a/B, PHP first searches for the function/a/B/myfunction (). If no function is found, it searches for/myfunction () in the global space ();

6. the call of an unqualified or qualified class name is parsed at runtime. For example, if we call New C () in namespace a/B (), PHP will search for Class A/B/C. If it cannot be found, PHP will try to automatically load A/B/C.

PHP namespace advanced features

Next, let's take a look at some advanced features of the PHP namespace.

_ Namespace _ constant

_ Namespace _ is a PHP string that always returns the name of the current namespace. It is an empty string in the global space.

<? PHP namespace APP/lib1; echo _ namespace __; // outputs: APP/lib1?>

This value is very useful during debugging. It can also dynamically generate a fully qualified class name, for example:

<? PHP
Namespace APP/lib1;

Class myclass {
Public Function whoami (){
Return _ method __;
}
}

$ C = _ namespace _. '// myclass ';
$ M = new $ C;
Echo $ M-> whoami (); // outputs: APP/lib1/myclass: whoami
?>

Namespace keyword

The namespace keyword can be used to explicitly reference a project in the current namespace or sub-namespace. It is equivalent to the self namespace in the class:

<? PHP
Namespace APP/lib1;

Class myclass {
Public Function whoami (){
Return _ method __;
}
}

$ M = new namespace/myclass;
Echo $ M-> whoami (); // outputs: APP/lib1/myclass: whoami
?>

Automatically load the namespace class

The most time-saving feature in PHP 5 is automatic loading. In the global (non-namespace) PHP code, you can write a standard automatic loading function:

<? PHP
$ OBJ = new myclass1 (); // classes/myclass1.php is auto-loaded
$ OBJ = new myclass2 (); // classes/myclass2.php is auto-loaded

// Autoload Function
Function _ autoload ($ class_name ){
Require_once ("classes/$ class_name.php ");
}
?>

In PHP 5.3, you can create a namespace class instance. In this case, the namespace and class name are completely limited and passed to the _ autoload function. For example, the value of $ class_name may be APP/lib1/myclass. You can place all PHP class files in the same folder and extract the namespace from the string, but this will cause File Name Conflict.

In addition, your class File hierarchy will be reorganized according to the namespace structure. For example, the myclass. php file can be created in the/classes/APP/lib1 Folder:

<? PHP
Namespace APP/lib1;

Class myclass {
Public Function whoami (){
Return _ method __;
}
}
?>

The following code is used for files in the root folder:

MyApp. php

<? PHP
Use APP/lib1/myclass as MC;

$ OBJ = new MC ();
Echo $ obj-> whoami ();

// Autoload Function
Function _ autoload ($ class ){
// Convert namespace to full file path
$ Class = 'classes/'. str_replace (' // ','/', $ class).'. php ';
Require_once ($ class );
}
?>

Explanation:

1. the alias of the class APP/lib1/myclass is MC;
2. New MC () is translated into new app/lib1/myclass () during compilation ();
3. the string APP/lib1/myclass is passed to the _ autoload function. Use the file path forward slash to replace the backslash in all namespaces, and then modify the string, classes/APP/lib1/myclass. PHP files are automatically loaded;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.