Introduction to the use of php namespace

Posted by xwishmasterx on Thu, 18 Jul 2019 01:00:19 +0200

brief introduction

For namespaces, the official documentation has been very detailed. http://www.php.net/manual/zh/language.namespaces.rationale.php I have done some practice and summary here.

One of the clearest purposes of namespaces is to solve the problem of renaming. Two functions or classes are not allowed to have the same name in PHP, otherwise a fatal error will occur. In this case, it can be solved by avoiding naming duplication. One of the most common practices is to agree on a prefix.

Example: There are two modules in the project: article and message board, each of which has a class Comment that handles user messages. Then I may want to add some information statistics functions to all users'messages, such as the number of messages I want to get. It's a good practice to call the methods provided by their Comments, but it's obviously not good to introduce their own Comment classes at the same time. The code will make mistakes, and rewriting any Comment in another place will reduce maintainability. At this point, only the class name can be reconstructed. I agreed on a naming rule that preceded the class name with the module name, such as Article_Comment, MessageBoard_Comment

As you can see, the name becomes very long, which means that more code (at least more characters) will be written when Comment is used in the future. In addition, if you want to add more integration functions to each module, or call each other, you need to reconstruct the name when the rename occurs. Of course, noticing this problem at the beginning of the project and specifying naming rules can avoid this problem very well. Another solution is to consider using namespaces.

Note:

Constants mentioned in this article: PHP 5.3 starts with const keywords that can be used outside classes. Const and define are both used to declare constants (their differences are not detailed), but in namespaces, define is global, while const acts on the current space. The constants I mentioned in this article refer to consts that are declared using const.

Use of namespace

Basics Namespaces divide code into different spaces (regions). The names of constants, functions, and classes in each space (for laziness, I'll call them elements below) do not affect each other. This is somewhat similar to the concept of encapsulation that we often refer to.

To create a namespace, you need to use the namespace keyword.


<?php

//Create a namespace named'Article'
namespace Article;

?>

It should be noted that there is no code in front of the first namespace of the current script file, and the following is incorrect:


//Example 1
//Write some logic code in front of the script

<?php

$path = "/";

class Comment { }

namespace Article;

?>

//Example 2
//Output some characters in front of the script

<html></html>
<?php

namespace Article;

?>

Why the first namespace? Because multiple namespaces can be created in the same script file.

Next, I created two namespaces, and by the way, I added a Comment class element to each of them:


<?php

//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 MessageBoard space
class Comment { }
?>

No other elements can be directly invoked between different spaces. Namespace grammar is required:


<?php

namespace Article;

class Comment { }

namespace MessageBoard;

class Comment { }

//Call the Computing class of the current space (MessageBoard)
$comment = new Comment();

//Calling Comment Class of Article Space
$article_comment = new \Article\Comment();

?>

As you can see, when calling Comment class in article space in MesageBoard space, a syntax like file path is used: space name element name

In addition to classes, the use of functions and constants is the same. Here I create new elements for both spaces and output their values in Message Board spaces.


<?php

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();

//Calling Constants, Functions and Classes in Article Spaces
echo \Article\PATH; ///article
echo \Article\getCommentTotal(); //100
$article_comment = new \Article\Comment();

?>

Then I did get the element data in the Article space.

Subspace Namespace invocation syntax is as reasonable as file paths, allowing us to customize subspaces to describe the relationships between spaces.

I'm sorry I forgot to say that both the article and message board modules are actually in the same blog project. If they are expressed in namespaces, this is the case:


<?php

//I use this namespace to represent the article module under the blog
namespace Blog\Article;

class Comment { }

//I use this namespace to represent the message board module under the blog
namespace Blog\MessageBoard;

class Comment { }

//Classes calling the current space
$comment = new Comment();

//Classes calling BlogArticle spaces
$article_comment = new \Blog\Article\Comment();

?>

Furthermore, subspaces can also define many levels, such as Blog Article Archives Date.

public space I have a common_inc.php script file with some useful functions and classes:


<?php

function getIP() { }

class FilterXSS { }

?>

Introducing this script into a namespace, the elements in the script do not belong to the namespace. If no other namespace is defined in this script, its elements are always in public space:


<?php

namespace Blog\Article;

//Introducing script files
include './common_inc.php';

$filter_XSS = new FilterXSS(); //A fatal error occurred: The BlogArticleFilterXSS class could not be found

$filter_XSS = new \FilterXSS(); //Correct

?>

The way to call public space is to add directly before the element name, otherwise the PHP parser will think that I want to call elements in the current space. Apart from the customized elements, PHP also includes its own elements, which belong to the public space.

To mention, in fact, functions and constants in public spaces can be called normally without adding\ but it is recommended to add them when calling functions in order to distinguish elements correctly.\

Terminology of names Before you talk about aliases and imports, you need to know the terms for the three names of space and how PHP resolves them. The official documents were very good, so I took them directly.

1. Unqualified names, or class names that do not contain prefixes, such as $comment = new Comment();. If the current namespace is Blog Article, Comment will be resolved to Blog Article Comment. If the code using Comment is not included in any namespace (in global space), Comment will be resolved to Comment.

2. A qualified name, or a name containing a prefix, such as $comment = new Article Comment ();. If the current namespace is Blog, Comment will be resolved to Blog Article Comment. If the code using Comment is not included in any namespace (in global space), Comment will be resolved to Comment.

3. Fully qualified names, or names containing global prefix operators, such as $comment = new\ArticleComment();. In this case, Comment is always parsed as literal name Article Comment in the code.

In fact, you can compare these three names 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), which may be easier to understand.

I use several examples to show them:


<?php

//Creating Spatial Blog
namespace Blog;

class Comment { }

//Unqualified name for the current Blog space
//This call will be parsed into Blog Comment ();
$blog_comment = new Comment();

//Qualified name, relative to Blog space
//This call will be parsed into Blog Article Comment ();
$article_comment = new Article\Comment(); //No backslash bar in front of class\

//Fully qualified name, meaning absolute in Blog space
//This call will be parsed into Blog Comment ();
$article_comment = new \Blog\Comment(); //There is a backslash bar in front of class\

//Fully qualified name, meaning absolute in Blog space
//This call will be parsed into Blog Article Comment ();
$article_comment = new \Blog\Article\Comment(); //There is a backslash bar in front of class\

//Creating Subspace Article of Blog
namespace Blog\Article;

class Comment { }

?>

In fact, I've been using unqualified and fully qualified names before, and now they can finally name them.

Aliases and imports Aliases and imports can be seen as a shortcut for calling namespace elements. PHP does not support importing functions or constants.

They are implemented by using the use operator:


<?php

namespace Blog\Article;

class Comment { }

//Create a BBS space (I have plans to open a forum)
namespace BBS;

//Import a namespace
use Blog\Article;
//Elements can be invoked with qualified names after importing namespaces
$article_comment = new Article\Comment();

//Use aliases for namespaces
use Blog\Article as Arte;
//Use aliases instead of space names
$article_comment = new Arte\Comment();

//Import a class
use Blog\Article\Comment;
//Elements can be called with unqualified names after importing classes
$article_comment = new Comment();

//Use aliases for classes
use Blog\Article\Comment as Comt;
//Use aliases instead of space names
$article_comment = new Comt();

?>

I've noticed that when you import elements, what happens if the current space has the same name element? Obviously, fatal mistakes will occur.

Example:


<?php

namespace Blog\Article;

class Comment { }

namespace BBS;

class Comment { }

Class Comt { }

//Import a class
use Blog\Article\Comment;
$article_comment = new Comment(); //Conflicts with Comment in the current space, resulting in fatal errors in the program

//Use aliases for classes
use Blog\Article\Comment as Comt;
$article_comment = new Comt(); //Conflicts with Comt in the current space, resulting in fatal errors in the program

?>

Dynamic call PHP provides namespace keywords and NAMESPACE magic constant dynamic access elements. NAMESPACE can be dynamically accessed by combining strings:


<?php

namespace Blog\Article;

const PATH = '/Blog/article';

class Comment { }

//The namespace keyword represents the current space
echo namespace\PATH; ///Blog/article
$comment = new namespace\Comment();

//The value of the magic constant _NAMESPACE_ is the current space name.
echo __NAMESPACE__; //Blog\Article
//Can be combined into strings and called
$comment_class_name = __NAMESPACE__ . '\Comment';
$comment = new $comment_class_name();

?>

String Formal Call Problem

In the example of dynamic invocation above, we have seen the string form of dynamic invocation. If we want to use this way, we should pay attention to two problems.

  1. Special characters may be escaped when using double quotation marks

<?php

namespace Blog\Article;

class name { }

//I want to call Blog Article name
$class_name = __NAMESPACE__ . "\name"; //But\n will be converted to a newline character

$name = new $class_name(); //A fatal error occurred

?>
  1. Not considered a qualified name

When compiling scripts, PHP determines the space where the elements are located and how they are imported. When parsing scripts, string-style calls can only be considered as unqualified names and fully qualified names, but never qualified names.


<?php

namespace Blog;

//Import Common class
use Blog\Article\Common;
//I want to call BlogArticleCommon with an unqualified name
$common_class_name = 'Common';
//Actually, it will be treated as an unqualified name, which means the Common class in the current space, but my current class does not create a Common class.
$common = new $common_class_name(); //Fatal error: Common class does not exist

//I want to call BlogArticleCommon with a qualified name
$common_class_name = 'Article\Common';
//Actually, it will be treated as a fully qualified name, representing the Common class in the Article space, but I only define the Blog Article space, not the Article space.
$common = new $common_class_name(); //Fatal error: Article Common class does not exist

namespace Blog\Article;

class Common { }

?>

Topics: PHP