Some introduction to abstract syntax tree (AST) in PHP7 new features

Source: Internet
Author: User
Tags diff parse error rfc
This article to you to share is about PHP7 new features of the abstract Syntax tree (AST) Some introduction, the content is very good, the need for friends can refer to, hope can help everyone.

This paper analyzes the changes brought about by the abstract syntax tree (AST) of PHP7 new features. Share to everyone for your reference, as follows:

Most of the content here is referenced by the AST RFC: Https://wiki.php.net/rfc/abstractsyntaxtree, which is described in the excerpt from the source document for ease of understanding.

This article does not tell you what an abstract syntax tree is, it needs to be understood by yourself, and this is just a description of some of the changes that the AST brings to PHP.

The new execution process

An important change in PHP7 's kernel is the addition of an AST. In PHP5, the process of executing from PHP script to opcodes is:

    1. Lexing: Lexical scan analysis to convert source files into token streams;

    2. Parsing: Parsing, generating op arrays at this stage.

In PHP7, the OP arrays is no longer directly generated in the parsing phase, but Mr. Cheng is an AST, so the process is one step further:

    1. Lexing: Lexical scan analysis to convert source files into token streams;

    2. Parsing: parsing, generating abstract syntax trees from token streams;

    3. Compilation: Generates OP arrays from an abstract syntax tree.

Execution time and memory consumption

From the above steps, this is more than the previous process, so it is common sense that this will increase the execution time of the program and the use of memory. But in fact the use of memory has increased, but the execution time has decreased.

The following results are tested using small (approximately 100 lines of code), medium (approximately 700 rows), large (approximately 2800 rows), and three scripts, respectively, to test the script: HTTPS://GIST.GITHUB.COM/NIKIC/289B0C7538B46C2220BC.

Each file compiles 100 execution times (note that the test results of the article are in 14, PHP7 also called Php-ng time):


Php-ng Php-ast Diff
SMALL 0.180s 0.160s -12.5%
MEDIUM 1.492s 1.268s -17.7%
LARGE 6.703s 5.736s -16.9%

Peak Memory in a single compilation:


Php-ng Php-ast Diff
SMALL 378kB 414kB +9.5%
MEDIUM 507kB 643kB +26.8%
LARGE 1084kB 1857kB +71.3%

The test results for a single compilation may not represent the actual usage, and the following is the result of a complete project test using Phpparser:


Php-ng Php-ast Diff
Time 25.5ms 22.8ms -11.8%
MEMORY 2360kB 2482kB +5.1%

The test shows that the execution time of the program after using AST is generally about 10% to 15%, but memory consumption also increases, which is obvious in a single compilation of large files, but it is not a serious problem during the whole project execution.

Also note that the above results are in the absence of Opcache, the production environment in the case of open opcache, memory consumption increase is not a big problem.

A change in semantics

It does not seem to be a good reason to use the AST if it is just time-optimized. In fact, the implementation of AST is not based on time optimization considerations, but to solve grammatical problems. Here's a look at some semantic changes.

Yield does not require parentheses

In the implementation of PHP5, if used in an expression context (for example, to the right of an assignment expression) yield , you must yield use parentheses on both sides of the declaration:

<?php$result = yield fn (); Illegal $result = (yield fn ()); Legal.

This behavior is only due to the limitations of PHP5 implementation, and in PHP7, parentheses are no longer necessary. So the following are also legal:

<?php$result = yield, $result = yield $v; $result = yield $k = = $v;

Of course, you have to follow yield the application scenario.

Parentheses do not affect behavior

In PHP5, the ($foo)['bar'] = 'baz' $foo['bar'] = 'baz' meaning of two statements is different. In fact, the former is not legal, you will get the following error:

<?php ($foo) [' bar '] = ' baz '; # php Parse error:syntax error, unexpected ' [' on line 1

But in PHP7, the two ways of writing mean the same thing.

Similarly, if the parameters of the function are wrapped in parentheses and the type check is problematic, the problem is resolved in PHP7:

<?phpfunction func () {return [];} function ByRef (array & $a) {}byref (func ()));

The above code does not alert in PHP5, except in byRef(func()) the way it is called, but in PHP7, the func() following error occurs regardless of whether there are any parentheses on either side:

PHP Strict standards:only variables should be passed by reference ...

Changes to List ()

The behavior of the list keyword has changed a lot. The order in which the list assigns a variable (equal to the same order as the equals sign) was previously from right to left and now from left to right:

<?phplist ($array [], $array [], $array []) = [1, 2, 3];var_dump ($array);//PHP5: $array = [3, 2, 1]//PHP7: $array = [1, 2 , 3]# Note that the order of the left and right here refers to the same order around the equals sign, # list ($a, $b) = [1, 2] this use $a = = 1, $b = = 2 is no doubt.

The reason for this change is precisely because in the PHP5 assignment process, 3 is first filled into the array, 1 the last, but now the order has changed.

The same changes are:

<?php$a = [1, 2];list ($a, $b) = $a;//PHP5: $a = 1, $b = 2//PHP7: $a = 1, $b = null + "Undefined index 1"

This is because the previous assignment $b get 2 First, then the value of $a becomes 1, but now $a becomes 1, no longer an array, so $b becomes null.

List now accesses only one time per offset:

<?phplist (list ($a, $b)) = $array;//PHP5: $b = $array [0][1]; $a = $array [0][0];//php7://produces an intermediate variable that gets the value of $array [0] $_tmp = $array [0]; $a = $_tmp[0]; $b = $_tmp[1];

Empty list members are now all forbidden, previously just in some cases:

<?phplist () = $a;   Illegal list ($b, list ()) = $a; Illegal foreach ($a as List ())//Non-law (not valid in PHP5)

Order of reference assignments

The order in which the references are assigned is right-to-left in PHP5, now from left to right:

<?php$obj = new StdClass; $obj->a = & $obj->b; $obj->b = 1;var_dump ($obj);//Php5:object (StdClass) #1 (2) {[ "B"] = &int (1) ["a"] = &int (1)}//php7:object (StdClass) #1 (2) {["a"] + &int (1) ["b"] = &i NT (1)}

The __clone method can be called directly

It is now possible $obj->__clone() to invoke the method directly using the notation __clone . __cloneis the only magic method that was previously forbidden to call directly, before you get an error like this:

Fatal Error:cannot Call __clone () method on Objects-use ' clone $obj ' instead in ...

Variable syntax consistency

The AST also solves some grammatical consistency issues, which are presented in another RFC: Https://wiki.php.net/rfc/uniform_variable_syntax.

In the new implementation, some of the previous grammatical expressions have different meanings and are now specific to the following table:

Expression PHP5 PHP7
$ $foo [' bar '] [' Baz '] ${$foo [' Bar '] [' Baz ']} ($ $foo) [' Bar '] [' Baz ']
$foo $bar [' Baz '] $foo->{$bar [' Baz ']} ($foo, $bar) [' Baz ']
$foo $bar [' Baz '] () $foo->{$bar [' Baz ']} () ($foo, $bar) [' Baz '] ()
Foo:: $bar [' Baz '] () foo::{$bar [' Baz ']} () (Foo:: $bar) [' Baz '] ()

The overall or previous order is right-to-left, now from left to right, and also follows the parentheses without affecting the behavior of the principle. These complex variables are written in the actual development of the need to pay attention to.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.