PHP Kernel Exploration: namespaces
Namespaces are a special type of scope
Thank you for reference or the original www.php-internal.com server June spent a total of 81.974 MS 3 database queries, and strive to provide you with this page. Try reading mode? I'd like to hear your suggestions.
In Wikipedia, the definition of a namespace is: the namespace (English: Namespace) represents the context of the identifier (identifier). An identifier can be defined in more than one namespace, and its meaning in different namespaces is mutually irrelevant. In a programming language, a namespace is a special scope that contains an identifier that is in that scope, and itself is represented by an identifier, which organizes a series of logically related identifiers together with an identifier. The scopes of functions and classes can be seen as implicit namespaces, which are inextricably linked to visibility, accessibility, and object life cycles.
Namespaces can be thought of as a way to encapsulate things, but also as a form of organization code structure that can be seen in many languages. In PHP, namespaces are used to solve two types of problems encountered when writing a class library or application to create reusable code such as classes or functions:
- User-written code conflicts with the name of a class/function/constant or third-party class/function/constant inside PHP.
- Creates an alias (or short) name for a very long identifier name (usually defined to alleviate the first type of problem), improving the readability of the source code.
PHP supports namespace features starting with version 5.3.0. Look at an example that defines and uses a namespace:
04 |
public static $var = ‘think in php internal‘ ; |
07 |
const E_ALL = "E_ALL IN Tipi" ; |
14 |
echo strlen (Exception:: $var ); |
As shown above, a namespace tipi is defined, within which a exception class is defined, a E_all constant and a function strlen. These classes, constants, and functions PHP are implemented by default. Without this namespace, declaring these classes, constants, or functions would be an error that the function repeats or the class repeats, and the definition of the constant will not succeed.
In the PHP language, namespaces are defined by the namespace keyword, which can include any valid PHP code within a namespace, but its scope is limited to classes, constants, and functions. Syntactically, PHP supports defining multiple namespaces in a single file, but it is not recommended for this type of code organization. When you need to combine the code in the global non-namespace with the code in the namespace, the global code must be enclosed in curly braces with a namespace statement without a name.
At this point, consider how the namespace definition is implemented in the PHP kernel. When there are multiple identical functions or classes in multiple namespaces, how do you differentiate between them? How does a function within a namespace be called?
Definition of namespaces
The implementation of namespaces in PHP is simple, whether it is a function, a class, or a constant, in the process of declaring the namespace with the defined function name to \ Merge together, as the function name or class name stored in its corresponding container. As the Exception class in the example above, the last stored class name is tipi\exception. The cost of this implementation and the adjustment to the entire code structure are minimal for the entire PHP implementation architecture.
Let's take the exception class as an example to illustrate the implementation of the entire namespace. The keyword for the namespace implementation is namespace, and from this keyword we can find the function that handles this keyword at compile time as zend_do_begin_namespace. In this function, the key is in the assignment of CG (Current_namespace), which is useful when declaring a later class declaration or function.
As we said earlier, the implementation of the class declaration invokes the Zend_do_begin_class_declaration function in the zend/zend_complie.c file at compile time, and the processing code for the namespace in this function is as follows:
01 |
if (CG(current_namespace)) { |
02 |
/* Prefix class name with name of current namespace */ |
05 |
tmp.u.constant = *CG(current_namespace); |
06 |
zval_copy_ctor(&tmp.u.constant); |
07 |
zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC); |
10 |
lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant)); |
The purpose of this code is to prefix the class name with the namespace if the namespace is currently present, as mentioned in the example Tipi\exception class above, where the addition of tipi\ is performed. In the Zend_do_build_namespace_name function, the Zend_do_build_full_name function is eventually called to implement the merge of the class name. The same name merge operation exists in the declaration of functions and constants. This is also why namespaces are valid only for classes, constants, and functions.
Using namespaces
As an example of a function call, the Zend_do_begin_function_call function is called when a function needs to be called. In this function, when a namespace is used, the function name is checked, and the function called is zend_resolve_non_class_name. In the Zend_resolve_non_class_name function, it is judged by type and returns the relevant result:
- Fully qualified name function: The program first makes this judgment, and its judgment is based on whether the first character is "\", in which case it is returned directly at parse time. A global call, such as \strlen, that begins with \ or a \tipi\exception call similar to the previously defined.
- All unqualified and qualified names (non-fully qualified names): Determines whether an alias is based on the current import rule program, and takes the corresponding namespace name from the Hashtable that stores the alias during compilation, merging it with the existing function name. The storage and generation of aliases is explained in the following sections,
- Inside the namespace: all qualified names that are not translated according to the import rule are preceded by the current namespace name. Finally, if the current namespace is determined, the final program returns a function name that incorporates the namespace.
Alias/import
Allowing the external fully qualified name to be referenced or imported through an alias is an important feature of the namespace. This is somewhat similar to the ability to create symbolic connections to other files or directories in a UNIX-like file system. The PHP namespace supports two ways to use aliases or imports: Use aliases for class names, or use aliases for namespace names.
PHP does not support importing functions or constants.
In PHP, aliases are implemented using the operator use. So we can find from the source code that the function called at compile time is zend_do_use. Aliases are stored in CG (Current_import) in the process of compiling to intermediate code, which is a hashtable. Zend_do_use the implementation of the entire function is basically a process of finding, judging whether it is wrong, and finally writing to the Hashtable. There is an import process for namespaces and class names, but not for constants and functions, which is the root cause of PHP's unsupported import of functions or constants.
Extended Reading
The list of topics for this article is as follows:
- PHP Kernel Explorer: Starting with the SAPI interface
- PHP kernel exploration: Start and end of a single request
- PHP kernel exploration: One-time request life cycle
- PHP Kernel Exploration: single-process SAPI life cycle
- PHP kernel Exploration: SAPI lifecycle of multiple processes/threads
- PHP Kernel Explorer: Zend Engine
- PHP Kernel Explorer: Explore SAPI again
- PHP kernel Discovery: Apache module Introduction
- PHP Kernel Explorer: PHP support via MOD_PHP5
- PHP kernel exploration: Apache Run with hook function
- PHP Kernel Explorer: embedded PHP
- PHP Kernel Explorer: PHP fastcgi
- PHP kernel exploration: How to execute PHP scripts
- PHP Kernel Explorer: PHP script execution details
- PHP kernel exploration: opcode opcode
- PHP kernel Explorer: PHP opcode
- PHP kernel exploration: Interpreter execution process
- PHP Kernel Exploration: Variables overview
- PHP kernel exploration: variable storage and type
- PHP Kernel Explorer: Hash table in PHP
- PHP Kernel Exploration: Understanding the hash table in Zend
- PHP kernel exploration: PHP hash Algorithm design
- PHP kernel Exploration: translating an article hashtables
- PHP Kernel exploration: What is a hash collision attack?
- PHP Kernel exploration: implementation of constants
- PHP kernel exploration: Storage of variables
- PHP kernel exploration: Types of variables
- PHP Kernel Explorer: Variable value operation
- PHP Kernel exploration: Creation of variables
- PHP kernel exploration: pre-defined variables
- PHP Kernel Explorer: variable retrieval
- PHP kernel Exploration: Variable type conversion
- PHP Kernel exploration: implementation of weakly typed variables
- PHP Kernel exploration: implementation of static variables
- PHP Kernel Explorer: Variable type hints
- PHP kernel exploration: The life cycle of a variable
- PHP Kernel Exploration: variable assignment and destruction
- PHP Kernel exploration: variable scope
- PHP kernel Explorer: Weird variable names
- PHP Kernel Explorer: variable value and type storage
- PHP Kernel Explorer: global variables
- PHP kernel Exploration: Conversion of variable types
- PHP kernel Exploration: The memory management begins
- PHP Kernel Explorer: Zend Memory manager
- PHP Kernel Explorer: PHP's memory management
- PHP Kernel Exploration: Application and destruction of memory
- PHP Kernel Exploration: reference count vs. write-time replication
- PHP kernel exploration: PHP5.3 garbage collection mechanism
- PHP Kernel Explorer: Cache in memory management
- PHP Kernel Exploration: write-time copy cow mechanism
- PHP kernel Exploration: arrays and Linked lists
- PHP kernel exploration: Using the Hash Table API
- PHP kernel exploration: array manipulation
- PHP kernel Exploration: Array source code Analysis
- PHP Kernel Exploration: Classification of functions
- PHP kernel Exploration: internal structure of functions
- PHP Kernel exploration: function structure transformation
- PHP Kernel Exploration: The process of defining a function
- PHP kernel Exploration: Parameters for functions
- PHP kernel exploration: zend_parse_parameters function
- PHP Kernel exploration: function return value
- PHP kernel exploration: formal parameter return value
- PHP Kernel exploration: function invocation and execution
- PHP kernel exploration: Referencing and function execution
- PHP kernel exploration: anonymous functions and closures
- PHP Kernel Exploration: object-oriented opening
- PHP kernel Exploration: The structure and implementation of classes
- PHP kernel exploration: member Variables for classes
- PHP Kernel Exploration: Member Methods for classes
- PHP Kernel Exploration: class prototype Zend_class_entry
- PHP kernel exploration: Definition of class
- PHP Kernel Explorer: Access control
- PHP kernel exploration: inheritance, polymorphism and abstract classes
- PHP Kernel Exploration: magic function and delay binding
- PHP kernel Exploration: Preserving classes and special classes
- PHP Kernel Explorer: objects
- PHP kernel Exploration: Creating object instances
- PHP Kernel Explorer: Object properties Read and write
- PHP Kernel Exploration: namespaces
- PHP kernel exploration: Defining interfaces
- PHP kernel Exploration: Inheritance and Implementation interface
- PHP Kernel Exploration: resource resource type
- PHP Kernel Explorer: Zend virtual machine
- PHP Kernel Exploration: Lexical parsing of virtual machines
- PHP Kernel Explorer: virtual machine Syntax analysis
- PHP kernel exploration: Execution of intermediate code opcode
- PHP Kernel Exploration: Code encryption and decryption
- PHP kernel exploration: zend_execute specific execution process
- PHP kernel exploration: Reference and counting rules for variables
- PHP kernel exploration: New garbage collection Mechanism description
____php Kernel Exploration: namespaces