


In-depth understanding of the underlying mechanism of PHP_PHP tutorial
As a dynamic language, how is PHP implemented, what is its underlying mechanism, and what characteristics does it have? This article introduces relevant underlying knowledge including PHP design concepts, overall structure, core data structures, and variables in a simple and easy-to-understand way. It will be more useful to us. Good development of PHP programs, optimization of performance, etc. have certain guiding significance.
Table of Contents
1. Overview...
what is php?.
Understand the purpose of its underlying implementation?.
2. The design concept and characteristics of php...
3. Php’s four-layer system...
4. Sapi
5. Php execution process&opcode.
6. HashTable — core data structure...
7. Php variables...
Overview…
Zval
Integer, floating point type variables...
String variable…
Array variable…
Resource type variable…
The scope of Php variables...
1. Overview
what is php?
A dynamic language for web development. To be more specific: it is a software framework that uses C language to implement a large number of components. In a more narrow sense, it can be considered as a powerful UI framework.
Understand the purpose of its underlying implementation?
- To use dynamic language well, you must first understand it
- Memory management and framework models are worth learning from
- Achieve more powerful functions through extended development and optimize the performance of our programs
2. The design concept and characteristics of php
- Multi-process model
Since PHP is a multi-process model, different requests do not interfere with each other. This ensures that the failure of one request will not affect the entire service. Of course, with the development of the times, PHP has already supported the multi-thread model.
- Weakly typed language
Unlike c/c++, java, c# and other languages, Php is a weakly typed language: the type of a variable is not determined at the beginning. It is determined during operation and implicit or explicit type conversion may occur. The flexibility of this mechanism is very convenient and efficient in web development, which will be detailed in PHP variables later.
- The engine (Zend) + component (ext) model reduces internal coupling
- The middle layer (sapi) isolates the web server and php
- The syntax is simple and flexible, without too many specifications. (Resulting in mixed styles)
- No matter how bad a programmer is, he will not write a program that is so outrageous that it endangers the overall situation.
3. Php’s four-layer system
The core architecture of Php is as shown below
As can be seen from the picture, PHP is a 4-layer system from bottom to top
- Zend Engine
Zend is implemented entirely in pure C and is the core part of PHP. It translates PHP code (a series of compilation processes such as lexical and syntax analysis) into executable opcode processing and implements corresponding processing methods and implements basic data structures (such as hashtable, oo), memory allocation and management, and provides corresponding api methods for external calls. It is the core of everything. All peripheral functions are implemented around zend.
- Extensions
Around the zend engine, extensions provide various basic services in a component-based manner. Our common various built-in functions (such as array series), standard libraries, etc. are all implemented through extensions. Users can also implement their own extensions as needed. Achieve functions expansion, performance optimization and other purposes (for example, the PHP middle layer and rich text parsing currently used by Tieba are typical applications of extension).
- Sapi
The full name of Sapi is Server Application Programming Interface, which is the server application programming interface. Sapi enables PHP to interact with peripheral data through a series of hook functions. This is a very elegant and successful design of PHP. Through sapi, PHP itself and The upper-layer application is decoupled and isolated. PHP can no longer consider how to be compatible with different applications, and the application itself can also implement different processing methods according to its own characteristics. It will be introduced later in the sapi chapter
- Upper layer application
This is the PHP program we usually write. We can obtain various application modes through different sapi methods, such as implementing web applications through webserver, running them in script mode on the command line, etc.
If php was a car, then
- The framework of the car is PHP itself
- Zend is the engine of the car
- The various components under Ext are the wheels of the car
- Sapi can be regarded as a road, and cars can run on different types of roads
The execution of a PHP program is a car running on the road.
Therefore, we need: Excellent engine + suitable wheels + correct runway
4. Sapi
As mentioned before, sapi allows external applications to exchange data with php through a series of interfaces and implement specific processing methods according to different application characteristics. Some of our common sapis are:
- apache2handler
This is the processing method when using apache as the webserver and running in mod_php mode. It is also the most widely used one now.
- cgi
This is another direct interaction method between webserver and php, which is the famous fastcgi protocol. In recent years, fastcgi+php has been used more and more, and it is also the only method supported by asynchronous webserver. Regarding fastcgi and mod_php, you can refer to another article "php performance survey-mod_php vs fastcgi"
- cli
Application mode called by command line
The definition and main interface functions of Sapi are as shown below
Here are some of the main functions
- startup: Initialization operation when php is called
For example, in cgi mode, all extensions will be loaded and module initialization will be performed during startup.
- shutdown: finishing work when php is shut down
- activate: Request initialization
- dectivate: Finishing work at the end of the request
- ub_write: Specify data output method
For example, in the apache2handler method, since php exists as a so of apache, its output is to call apache's ap_write function, and in cgi mode, the system calls write.
- sapi_error: error handling function
- read_post: Read post data
- register_server_variables: Register environment variables in $_SERVER
This variable is generally registered according to different protocol standards.
5. Php execution process&opcode
Let's first take a look at the process of executing the php code.
As you can see from the picture, PHP implements a typical dynamic language execution process: after getting a piece of code, after lexical analysis, syntax analysis and other stages, the source program will be translated into instructions (opcodes), and then ZEND virtual The machine executes these instructions in sequence to complete the operation. Php itself is implemented in C, so the functions ultimately called are all C functions. In fact, we can regard PHP as a software developed in C.
It is not difficult to see from the above description that the core of PHP execution is the translated instructions one by one, that is, opcode
u opcode
Opcode is the most basic unit of PHP program execution. An opcode consists of two parameters (op1, op2), return value and processing function. The Php program is finally translated into the sequential execution of a set of opcode processing functions
Several common processing functions
ZEND_ASSIGN_SPEC_CV_CV_HANDLER: Variable allocation ($a=$b)
ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:Function call
ZEND_CONCAT_SPEC_CV_CV_HANDLER: String concatenation $a.$b
ZEND_ADD_SPEC_CV_CONST_HANDLER: addition operation $a+2
ZEND_IS_EQUAL_SPEC_CV_CONST: Judgment of equality $a==1
ZEND_IS_IDENTICAL_SPEC_CV_CONST: Judgment of equality $a===1
6. HashTable — core data structure
HashTable is the core data structure of zend. It is used to implement almost all common functions in php. The php array we know is its typical application. In addition, within zend, such as function symbol tables, global variables, etc. are also based on hash table to achieve.
PHP’s hash table has the following characteristics:
- Supports typical key->value query
- Can be used as an array
- Adding and deleting nodes is O(1) complexity
- The key supports mixed types: there are associative number combination index arrays at the same time
- Value supports mixed types: array ("string",2332)
- Support linear traversal: such as foreach
Zend hash table implements the typical hash table hash structure, and at the same time provides the function of forward and reverse traversal of the array by appending a doubly linked list. Its structure is as shown below
-
Hash structure
In addition, when performing key->value fast search, zend itself has also made some optimizations to speed up the process by exchanging space for time. For example, a variable nKeyLength is used in each element to identify the length of the key for quick determination.
-
Doubly linked list
Zend hash table is a composite structure. When used as an array, it supports common associative arrays and can also be used as sequential index numbers, and even allows a mixture of the two.
-
Php associative array
- getKeyHashValue h;
- index = n & nTableMask;
- Bucket *p = arBucket[index];
- while (p) {
- if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
- RETURN p->data;
- }
- p=p->next;
- }
- RETURN FALTURE;
As can be seen from the code, this is a common hash query process and some fast judgments are added to speed up the search.
- Php index array
The index array is our common array, accessed through subscripts. For example $arr[0]
Zend HashTable is internally normalized, and the hash value and nKeyLength (0) are also assigned to the index type key. The internal member variable nNextFreeElement is the currently assigned maximum id, which is automatically increased by one after each push.
It is this normalization process that allows PHP to achieve a mixture of associative and non-associative
Due to the particularity of the push operation, the order of the index keys in the PHP array is not determined by the size of the subscript, but by the order of the push.
For example $arr[1] = 2; $arr[2] = 3;
For double type keys, Zend HashTable will treat them as index keys
7. Php variables
Overview
- Php is a weakly typed language and does not strictly distinguish the types of variables.
- Php does not need to specify the type when declaring variables.
- Php may perform implicit conversions of variable types during program running.
- Like other strongly typed languages, explicit type conversion can also be performed in the program.
- Php variables can be divided into simple types (int, string, bool), collection types (array resource object) and constants (const)
- All the above variables have the same structure at the bottom: zval
Zval
Zval is another very important data structure in zend, used to identify and implement php variables. Its data structure is as follows
Zval mainly consists of three parts:
1. type: specifies the type of variable (integer, string, array, etc.)
2. refcount&is_ref: used to implement reference counting (detailed introduction later)
3. Value: The core part, which stores the actual data of the variable
u zvalue
Zvalue is used to save the actual data of a variable. Because multiple types need to be stored, zvalue is a union, thus implementing weak typing.
The corresponding relationship between Php variable types and their actual storage is as follows
IS_LONG -> lvalue
IS_DOUBLE -> dvalue
IS_ARRAY -> ht
IS_STRING -> str
IS_RESOURCE -> lvalue
u Reference count
Reference counting is widely used in memory recycling, string operations, etc. Variables in Php are a typical application of reference counting
Zval's reference counting is implemented through the member variables is_ref and ref_count. Through reference counting, multiple variables can share the same data. Avoid heavy consumption caused by frequent copies
During the assignment operation, zend points the variable to the same zval and ref_count++, and during the unset operation, the corresponding ref_count-1. The destruction operation will only be performed when ref_count is reduced to 0
If it is a reference assignment, zend will modify is_ref to 1
u Copy while writing
Php variables realize variable sharing data through reference counting. What if you change the value of one of the variables?
When trying to write a variable, if Zend finds that the zval pointed to by the variable is shared by multiple variables, it will copy a zval with a ref_count of 1 and decrement the refcount of the original zval. This process is called "zval separation". It can be seen that zend only performs copy operations when a write operation occurs, so it is also called copy-on-write (copy on write)
For reference variables, the requirements are opposite to those of non-reference types. Variables assigned by reference must be bundled. Modifying one variable modifies all bundled variables.
Integer and floating point type variables
Integers and floating point numbers are one of the basic types in PHP and are also simple variables.
For integers and floating point numbers, the corresponding values are stored directly in zvalue. Their types are long and double respectively.
It can be seen from the zvalue structure that for integer types, unlike strongly typed languages such as C, PHP does not distinguish between int, unsigned int, long, long long and other types. For it, there is only one type of integer, which is long. . From this, it can be seen that in PHP, the value range of integers is determined by the number of compiler bits and is not fixed .
For floating point numbers, similar to integers, it does not distinguish between float and double, but only double is unified.
- In php, what should I do if the integer range is out of bounds?
In this case, it will be automatically converted to double type. You must be careful about this, as many tricks are caused by this.
String variable
Like integers, character variables are also basic types and simple variables in PHP
It can be seen from the zvalue structure that in PHP, a string is composed of a pointer to the actual data and a length structure, which is similar to the string in C++.
Since the length is represented by an actual variable, unlike c, its string can be binary data (including
When adding, modifying, or appending string operations, PHP will reallocate memory to generate new strings.Finally, for security reasons, php will still add at the end when generating a string
Common string splicing methods and speed comparison
- Suppose there are the following 4 variables:
$strA=‘123’; $strB = ‘456’; $intA=123; intB=456;
Now let’s compare and explain the following string splicing methods
1. $res = $strA.$strB and $res = “$strA$strB”
In this case, zend will malloc a piece of memory again and process it accordingly, and its speed is generally
2. $strA = $strA.$strB
This is the fastest, zend will directly relloc based on the current strA to avoid repeated copying
3. $res = $intA.$intB
This speed is slower because implicit format conversion is required. In actual programming, you should also pay attention to avoid
as much as possible.4. $strA = sprintf (“%s%s”,$strA.$strB);
This will be the slowest method, because sprintf is not a language structure in PHP. It takes a lot of time to identify and process the format. In addition, the mechanism itself is malloc. However, the sprintf method is the most readable, and in practice it can be chosen flexibly according to specific circumstances.
Array variable
As mentioned before, Php arrays are naturally implemented through Zend HashTable
How to implement foreach operation?
- Foreach of an array is completed by traversing the doubly linked list in the hashtable. For index arrays, traversal through foreach is much more efficient than for, eliminating the need for key->value search
The Count operation directly calls HashTable->NumOfElements, O(1) operation
For a string like '123', zend will convert it to its integer form. $arr[‘123’] and $arr[123] are equivalent
Resource type variable
This is the most complex variable in PHP and is also a composite structure.
Php's zval can represent a wide range of data types, but it is difficult to fully describe custom data types. Since there is no efficient way to represent these composite structures, there is no way to use traditional operators on them. To solve this problem, just refer to the pointer through an essentially arbitrary identifier (label), which is called a
resource. In zval, for resource, lval is used as a pointer, directly pointing to the address of the resource.
Resource can be any composite structure. The familiar mysqli, fsock, memcached, etc. are all resources.
Use resources
- • Register
- For a custom data type, you want to use it as a resource. First you need to register, zend will assign it a globally unique identifier
• Get a resource variable
- For resources, zend maintains an id->hash_tale of actual data. For a resource, only its id is recorded in zval. When fetching, find the specific value in hash_table through id and return
- • Resource destruction
The data types of resources are diverse. Zend itself has no way to destroy it. Therefore, users need to provide a destruction function when registering resources. When unset resources, zend calls the corresponding function to complete the destruction. Also delete it from the global resource table.
- Persistent resources
A resource can persist long-term, not just after all variables that reference it go out of scope, but even after a request ends and a new request is made. These resources are called persistent resources because they persist throughout the entire life cycle of the SAPI unless specifically destroyed.
In many cases, persistent resources can improve performance to a certain extent. For example, in our common mysql_pconnect, persistent resources allocate memory through pemalloc so that they will not be released when the request ends.
For zend, there is no distinction between the two per se.
Scope of Php variables
- How are local variables and global variables implemented in Php?
For a request, PHP can see two symbol tables (symbol_table and active_symbol_table) at any time, of which the former is used to maintain global variables. The latter is a pointer pointing to the currently active variable symbol table. When the program enters a function, zend will allocate a symbol table x to it and point active_symbol_table to a. In this way, the distinction between global and local variables is achieved
- Get variable value
PHP’s symbol table is implemented through hash_table. Each variable is assigned a unique identifier. When obtaining, the corresponding zval is found from the table according to the identifier and returns
- Use global variables in functions
In a function, we can use global variables by explicitly declaring global. Create a reference to the variable with the same name in symbol_table in active_symbol_table. If there is no variable with the same name in symbol_table, it will be created first
Excerpted from YoungerChen’s column

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

To work with date and time in cakephp4, we are going to make use of the available FrozenTime class.

CakePHP is an open-source framework for PHP. It is intended to make developing, deploying and maintaining applications much easier. CakePHP is based on a MVC-like architecture that is both powerful and easy to grasp. Models, Views, and Controllers gu

To work on file upload we are going to use the form helper. Here, is an example for file upload.

Validator can be created by adding the following two lines in the controller.

Logging in CakePHP is a very easy task. You just have to use one function. You can log errors, exceptions, user activities, action taken by users, for any background process like cronjob. Logging data in CakePHP is easy. The log() function is provide

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

CakePHP is an open source MVC framework. It makes developing, deploying and maintaining applications much easier. CakePHP has a number of libraries to reduce the overload of most common tasks.
