Home  >  Article  >  Backend Development  >  In-depth understanding of PHP's OpCode principle, in-depth understanding of opcode_PHP tutorial

In-depth understanding of PHP's OpCode principle, in-depth understanding of opcode_PHP tutorial

WBOY
WBOYOriginal
2016-07-12 08:50:561078browse

In-depth understanding of the principle of OpCode in PHP, in-depth understanding of opcode

This article describes the principle of OpCode in PHP with examples. Share it with everyone for your reference, the details are as follows:

OpCode is an intermediate language compiled from PHP scripts, just like Java's ByteCode, or .NET's MSL. This article is mainly based on "Understanding OPcode" and the Internet. It is specially recorded based on personal understanding and modification:

PHP code:

<&#63;php
  echo "Hello World";
  $a = 1 + 1;
  echo $a;
&#63;>

PHP will go through the following 4 steps when executing this code:

1. Scanning (Lexing), convert PHP code into language fragments (Tokens)
2. Parsing, converting Tokens into simple and meaningful expressions
3. Compilation, compile expressions into Opocdes
4. Execution, execute Opcodes sequentially, one at a time, thereby realizing the functions of PHP scripts.

Note: Some current caches, such as APC, can enable PHP to cache Opcodes. In this way, every time a request comes, there is no need to repeat the first three steps, which can greatly improve the execution speed of PHP.

First, Zend/zend_language_scanner.c will perform lexical analysis on the input PHP code based on Zend/zend_language_scanner.l (Lex file) to obtain "words" one by one. PHP4.2 began to provide a function called token_get_all, this function can scan a piece of PHP code into Tokens;

<&#63;php
$tokens = token_get_all('<&#63;php
  echo "Hello World";
  $a = 1 + 1;
  echo $a;
&#63;>');
print_r($tokens);
&#63;>

You will get the following results:

Array
(
  [0] => Array
    (
      [0] => 367
      [1] => <&#63;php
      [2] => 1
    )
  [1] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [2] => Array
    (
      [0] => 316
      [1] => echo
      [2] => 2
    )
  [3] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [4] => Array
    (
      [0] => 315
      [1] => "Hello World"
      [2] => 2
    )
  [5] => ;
  [6] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [7] => Array
    (
      [0] => 309
      [1] => $a
      [2] => 3
    )
  [8] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [9] => =
  [10] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [11] => Array
    (
      [0] => 305
      [1] => 1
      [2] => 3
    )
  [12] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [13] => +
  [14] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [15] => Array
    (
      [0] => 305
      [1] => 1
      [2] => 3
    )
  [16] => ;
  [17] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [18] => Array
    (
      [0] => 316
      [1] => echo
      [2] => 4
    )
  [19] => Array
    (
      [0] => 370
      [1] =>
      [2] => 4
    )
  [20] => Array
    (
      [0] => 309
      [1] => $a
      [2] => 4
    )
  [21] => ;
  [22] => Array
    (
      [0] => 370
      [1] =>
      [2] => 4
    )
  [23] => Array
    (
      [0] => 369
      [1] => &#63;>
      [2] => 5
    )
)

The returned result, strings, characters, and spaces in the source code will be returned unchanged. Characters in each source code will appear in the corresponding order. However, other items such as tags, operators, and statements will be converted into an Array containing two parts: Token ID (that is, the corresponding code for changing the Token inside Zend, such as T_ECHO, T_STRING), and the original code in the source code. content.

The next step is the Parsing stage. Parsing will first discard the excess spaces in the Tokens Array, and then convert the remaining Tokens into simple expressions one by one

1. echo a constant string
2. add two numbers together
3. store the result of the prior expression to a variable
4. echo a variable

Then, change the Compilation stage, which will compile Tokens into op_arrays one by one. Each op_arrayd contains the following 5 parts:

1. The identification of the Opcode number indicates the operation type of each op_array, such as add, echo
2. The result stores the Opcode result
3. Operand 1 is given to the operand of Opcode
4. Operand 2
5. The extended value is an integer used to distinguish overloaded operators

For example, PHP code will be parsed as:

[root@localhost html]# /usr/local/php/bin/php -dvld.active=1 hello.php
Branch analysis from position: 0
Return found
filename:    /var/www/html/hello.php
function name: (null)
number of ops: 6
compiled vars: !0 = $a
line   # op              fetch     ext return operands
-------------------------------------------------------------------------------
  2   0 ECHO                           'Hello+world'
  3   1 ADD                       ~0   1, 1
     2 ASSIGN                          !0, ~0
  4   3 ECHO                           !0
  6   4 RETURN                          1
     5* ZEND_HANDLE_EXCEPTION
Hello world2

Each operand is composed of the following two parts:

a) op_type: IS_CONST, IS_TMP_VAR, IS_VAR, IS_UNUSED, or IS_CV

b) u, a union, stores the value (const) or lvalue (var) of this operand in different types according to the op_type

As for var, each var is different. IS_TMP_VAR, as the name suggests, this is a temporary variable that saves some results of op_array for use in the next op_array. The u of this type of operand stores a handle (integer) pointing to the variable table. This type of operand is generally used~ The beginning, such as ~0, represents the unknown temporary variable IS_VAR at number 0 in the variable table. This is our general variable. They begin with $ to represent IS_CV, which represents the type used by compilers after ZE2.1/PHP5.1. Cache mechanism, this variable saves the address of the variable referenced by it. When a variable is referenced for the first time, it will be CVd. Future references to this variable do not need to look up the active symbol table again. CV variables are represented by starting with !.

The $a variable is optimized to !0.

Readers who are interested in more PHP-related content can check out the special topics on this site: "Summary of PHP mathematical operation skills", "Summary of PHP operating office document skills (including word, excel, access, ppt)", "PHP array ( Array) operating skills collection", "php sorting algorithm summary", "php common traversal algorithms and techniques summary", "php data structure and algorithm tutorial", "php programming algorithm summary", "php regular expression usage summary", "Summary of PHP operations and operator usage", "Summary of PHP string usage" and "Summary of common PHP database operation skills"

I hope this article will be helpful to everyone in PHP programming.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1133037.htmlTechArticleIn-depth understanding of the principle of OpCode in PHP, and in-depth understanding of opcode. This article explains the principle of OpCode in PHP with examples. Share it with everyone for your reference, the details are as follows: OpCode is a PHP script compilation...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn