For namespaces, the official documents have already explained it in detail [View]. I have made some practice and summary here.
One of the clearest purposes of namespaces is to solve the problem of duplicate names. PHP does not allow two functions or classes to have the same name, otherwise a fatal error will occur. In this case, it can be solved as long as you avoid naming duplication. The most common way is to agree on a prefix.
Example: There are two modules in the project: article and message board. Each of them has a class Comment for processing user messages. Later, I may want to add some information statistics functions for all user messages. For example, I want to get the number of all messages. At this time, it is a good idea to call the methods provided by their Comments, but it is obviously not possible to introduce their respective Comment classes at the same time. The code will make errors, and rewriting any Comment in another place will also reduce maintainability. At this time, I can only reconstruct the class name. I agreed on a naming rule, adding the module name in front of the class name, like this: Article_Comment, MessageBoard_Comment
As you can see, the name has become very long, which means that more code (at least more characters) will be written when using Comment in the future. Moreover, if you want to add more integration functions to each module in the future, or call each other, you will need to reconstruct the names when duplicate names occur. Of course, this problem can be avoided by noticing this problem at the beginning of the project and specifying naming rules. Another solution could be to use namespaces.
Note:
Constants mentioned in this article: Starting from PHP5.3, the const keyword can be used outside the class. Both const and define are used to declare constants (their differences are not detailed), but in a namespace, define acts globally, while const acts on the current space. The constants I mentioned in the article refer to constants declared using const.
Basics
Namespace divides the code into different spaces (areas), and the constants, functions, and classes of each space (to be lazy, I will call them elements below) ) names do not affect each other. This is somewhat similar to the concept of 'encapsulation' that we often mention.
To create a namespace, you need to use the namespace keyword, like this:
//Create a namespace named 'Article'
namespace Article;
?>
$path = "/";
class Comment { }
namespace Article;
?>
//Example 2
//Some characters are output in front of the script
namespace Article;
?>
Below I created two namespaces and added a Comment class element to each of these two spaces:
//Create a namespace named 'Article'
namespace Article;
//This Comment belongs to the element of Article space
class Comment { }
//Create a namespace named 'MessageBoard'
namespace MessageBoard;
//This Comment belongs to the element of the MessageBoard space
class Comment { }
?>
namespace Article;
class Comment { }
namespace MessageBoard;
class Comment { }
//Call the Comment class of the current space (MessageBoard)
$comment = new Comment();
//Call the Comment class of Article space
$article_comment = new ArticleComment();
?>
Except for classes, the usage of functions and constants is the same. Below I create new elements for the two spaces and output their values in the MessageBoard space.
namespace Article;
const PATH = '/article';
function getCommentTotal() {
return 100;
}
class Comment { }
namespace MessageBoard;
const PATH = '/message_board';
function getCommentTotal() {
return 300;
}
class Comment { }
//Call constants, functions and classes in the current space
echo PATH; ///message_board
echo getCommentTotal(); //300
$comment = new Comment();
//Call constants, functions and classes of Article space
echo ArticlePATH; ///article
echo ArticlegetCommentTotal(); //100
$article_comment = new ArticleComment();
?>
Subspace
The calling syntax of namespace is like a file path, which makes sense. It allows us to customize subspaces to describe the relationship between each space.
Sorry, I forgot to mention that the two modules article and message board are actually in the same blog project. If you use namespace to express their relationship, it is like this:
//I use this namespace to represent the article module under blog
namespace BlogArticle;
class Comment { }
//I use this namespace to represent the message board module under the blog
namespace BlogMessageBoard;
class Comment { }
//Call the class of the current space
$comment = new Comment();
//Call the class of BlogArticle space
$article_comment = new BlogArticleComment();
?>
Public space
I have a common_inc.php script file with some useful functions and classes:
function getIP() { }
class FilterXSS { }
?>
namespace BlogArticle;
//Introduce script file
include './common_inc.php';
$filter_XSS = new FilterXSS(); //Fatal error: BlogArticleFilterXSS class not found
$filter_XSS = new FilterXSS(); //Correct
?>
I would like to mention that in fact, public space functions and constants can be called normally without adding (I don’t understand why PHP does this). However, in order to correctly distinguish elements, it is recommended to add
when calling functions.
Name terminology
Before talking about aliases and imports, you need to know the terminology of the three names of spaces and how PHP parses them. The official documentation is very good, so I just used it.
1. Unqualified name, or class name without prefix, such as $comment = new Comment();. If the current namespace is BlogArticle, Comment will be parsed as BlogArticleComment. If the code using Comment does not contain code in any namespace (in the global space), the Comment will be parsed as a Comment.
2. Qualified name, or name containing prefix, such as $comment = new ArticleComment();. If the current namespace is Blog, Comment will be parsed as BlogArticleComment. If the code using Comment does not contain code in any namespace (in the global space), the Comment will be parsed as a Comment.
3. Fully qualified name, or a name that includes a global prefix operator, such as $comment = new ArticleComment();. In this case, Comment is always parsed as the literal name ArticleComment in the code.
In fact, these three names can be compared to file names (such as comment.php), relative path names (such as ./article/comment.php), and absolute path names (such as /blog/article/comment.php). This might make it easier to understand.
I used several examples to represent them:
//Create space Blog
namespace Blog;
class Comment { }
//Unqualified name, indicating the current Blog space
//This call will be parsed into BlogComment();
$blog_comment = new Comment();
//Qualified name, indicating relative to the Blog space
//This call will be parsed into BlogArticleComment();
$article_comment = new ArticleComment(); //There is no backslash in front of the class
//Fully qualified name, indicating absolute to Blog space
//This call will be parsed into BlogComment();
$article_comment = new BlogComment(); //There is a backslash in front of the class
//Fully qualified name, indicating absolute to Blog space
//This call will be parsed into BlogArticleComment();
$article_comment = new BlogArticleComment(); //There is a backslash in front of the class
//Create a blog subspace Article
namespace BlogArticle;
class Comment { }
?>
Aliases and Imports
Aliases and imports can be thought of as a shortcut for calling namespace elements. PHP does not support importing functions or constants.
They are all implemented by using the use operator:
namespace BlogArticle;
class Comment { }
//Create a BBS space (I plan to open a forum)
namespace BBS;
//Import a namespace
use BlogArticle;
//After importing the namespace, you can use the qualified name to call the element
$article_comment = new ArticleComment();
//Use alias for namespace
use BlogArticle as Arte;
//Use alias instead of space name
$article_comment = new ArteComment();
//Import a class
use BlogArticleComment;
//After importing the class, you can use the unqualified name to call the element
$article_comment = new Comment();
//Use aliases for classes
use BlogArticleComment as Comt;
//Use aliases instead of space names
$article_comment = new Comt();
?>
Example:
namespace BlogArticle;
class Comment { }
namespace BBS;
class Comment { }
Class Comt { }
//Import a class
use BlogArticleComment;
$article_comment = new Comment(); //Conflicts with Comment in the current space, and the program generates a fatal error
//Use an alias for the class
use BlogArticleComment as Comt;
$article_comment = new Comt(); //Conflicts with the Comt of the current space and the program generates a fatal error
?>
namespace BlogArticle;
const PATH = '/Blog/article';
class Comment { }
//The namespace keyword represents the current space
echo namespacePATH; ///Blog/article
$comment = new namespaceComment();
//The value of the magic constant __NAMESPACE__ is the current space name
echo __NAMESPACE__; //BlogArticle
//Can be combined into a string and called
$comment_class_name = __NAMESPACE__ . 'Comment';
$comment = new $comment_class_name();
?>
1. Special characters may be escaped when using double quotes
namespace BlogArticle;
class name { }
//I want to call BlogArticlename
$class_name = __NAMESPACE__ . "name"; //But n will be escaped as a newline character
$name = new $class_name(); //Fatal error occurred
?>
PHP determines the space where the element is located and the import status when compiling the script. When parsing the script, string form calls can only be considered unqualified names and fully qualified names, and can never be qualified names.
namespace Blog;
//Import Common class
use BlogArticleCommon;
//I want to call BlogArticleCommon using an unqualified name
$common_class_name = 'Common';
//It will actually be treated as an unqualified name , which means the Common class of the current space, but my current class has not created a Common class
$common = new $common_class_name(); //Fatal error occurred: Common class does not exist
//I want to use a qualified name to call BlogArticleCommon
$common_class_name = 'ArticleCommon';
//It will actually be regarded as a fully qualified name, which means the Common class in the Article space, but I only BlogArticle space is defined instead of Article space
$common = new $common_class_name(); //Fatal error occurred: ArticleCommon class does not exist
namespace BlogArticle;
class Common { }
?>