ホームページ バックエンド開発 PHP7 新しい抽象構文ツリー (AST) によって PHP7 に加えられた変更

新しい抽象構文ツリー (AST) によって PHP7 に加えられた変更

May 14, 2020 am 11:12 AM
php php7

新しい抽象構文ツリー (AST) によって PHP7 に加えられた変更

この記事の内容の大部分は、AST の RFC ドキュメントに基づいています: https://wiki.php.net/rfc/abstract_syntax_tree , 理解を容易にするために、ソース文書からの抜粋が紹介されています。

この記事では、抽象構文ツリーが何であるかについては説明しません。これは自分で理解する必要があります。この記事では、AST が PHP にもたらすいくつかの変更についてのみ説明します。

新しい実行プロセス

PHP7 のコアにおける重要な変更は、AST の追加です。 PHP5 では、PHP スクリプトからオペコードまでの実行プロセスは次のとおりです:

1. 字句解析: 字句スキャン分析、ソース ファイルをトークン ストリームに変換します;

2. 解析: 構文分析、Op 配列はこの段階で生成されます。

3. PHP7 では、op 配列は構文分析段階で直接生成されなくなりましたが、AST が最初に生成されるため、プロセスにはもう 1 つのステップがあります:

4. 字句解析:字句スキャン分析、ソース ファイルをトークン ストリームに変換;

5. 解析: 構文分析、トークン ストリームから抽象構文ツリーを生成;

6. コンパイル: 抽象から op 配列を生成構文ツリー。

実行時間とメモリ消費量

上記の手順から、これは前のプロセスよりも 1 つの手順が多いため、常識的には、これによりプログラムの実行時間が増加します。時間とメモリの使用量。しかし実際には、メモリ使用量は確かに増加していますが、実行時間は減少しています。

次の結果は、小規模 (約 100 行のコード)、中規模 (約 700 行)、および大規模 (約 2800 行) の 3 つのスクリプトをテストして得られます。テスト スクリプト: https ://gist.github.com/nikic/289b0c7538b46c2220bc

各ファイルを 100 回コンパイルする実行時間 (記事のテスト結果時間は 14 年であることに注意してください、PHP7 とも呼ばれます) PHP-NG ):

#SMALL0.180s0.160s-12.5%MEDIUM1.492s1.268s-17.7%LARGE6.703s 5.736s-16.9%1 回のコンパイルでのメモリ ピーク:

##php-ng
php-ast diff


#php-ng##SMALL378kB414kB 9.5%643kB1857kB単一コンパイルのテスト結果は、実際の使用状況を表していない可能性があります。以下は、PhpParser を使用した完全なプロジェクト テストの結果です:

php-ast
diff
##MEDIUM 507kB
26.8% 1084kB
71.3%

##php-ngphp-ast 時間25.5ms22.8ms-11.8% 5.1%##

テストによると、AST を使用した後、プログラムの全体的な実行時間は約 10% ~ 15% 改善されましたが、メモリ消費量も増加しました。この増加は、大きなファイルの 1 回のコンパイルでは明らかですが、実行中はそうではありません。プロジェクトの実行プロセス全体が非常に深刻な問題です。

また、上記の結果はすべて Opcache を使用していないことにも注意してください。運用環境で Opcache がオンになっている場合、メモリ消費量の増加は大きな問題ではありません。

セマンティックな変更

これが単なる時間の最適化である場合、AST を使用する十分な理由にはならないようです。実際、AST の実装は時間の最適化を考慮したものではなく、構文の問題を解決するために行われています。セマンティクスにおけるいくつかの変更を見てみましょう。

yield には括弧は必要ありません

PHP5 実装では、式コンテキスト (代入式の右側など) で yield を使用する場合、 yield 宣言の両側で括弧を使用する必要があります:

<?php
$result = yield fn();   // 不合法的
$result = (yield fn()); // 合法的

この動作は、PHP5 の実装制限によるものです。PHP7 では、括弧は必要なくなりました。したがって、次の記述方法も合法です:

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

もちろん、yield のアプリケーション シナリオに従わなければなりません。

括弧は動作に影響しません

PHP5 では、($foo)['bar'] = 'baz' および $foo['bar'] = 'baz ' 2 つのステートメントの意味は異なります。実は、前者の書き方は違法であり、次のようなエラーが発生します。

<?php
($foo)[&#39;bar&#39;] = &#39;baz&#39;;
# PHP Parse error: Syntax error, unexpected &#39;[&#39; on line 1

しかし、PHP7 では、2 つの書き方は同じ意味になります。

同様に、関数のパラメータが括弧で囲まれている場合、型チェックに問題があります。この問題は PHP7 でも解決されています:

<?php
function func() {
    return [];
}

function byRef(array &$a) {
}

byRef((func()));

上記のコードは、次の場合には警告しません。 PHP5 では byRef が使用されていない限り (func())、PHP7 では func() の両側に括弧があるかどうかに関係なく、次のエラーが発生します。

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

Changes in list()

list キーワードの動作が大幅に変更されました。リストが変数に値を割り当てる順序 (等号の左右の順序) は、以前は右から左でしたが、現在は左から右です:

<?php
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);

// PHP5: $array = [3, 2, 1]
// PHP7: $array = [1, 2, 3]

# 注意这里的左右的顺序指的是等号左右同时的顺序,
# list($a, $b) = [1, 2] 这种使用中 $a == 1, $b == 2 是没有疑问的。

上記の変更の理由は、正確には、PHP5 の代入プロセスでは、最初に 3 が配列に入力され、最後に 1 が入力されるためですが、順序が変更されたためです。

同じ変更は次のとおりです:

<?php
$a = [1, 2];
list($a, $b) = $a;

// PHP5: $a = 1, $b = 2
// PHP7: $a = 1, $b = null + "Undefined index 1"

これは、前の代入プロセスで $b が最初に 2 を取得し、その後 $a の値が 1 になったためです。しかし、今回は $a が最初に変更されます。は 1 になり、配列ではなくなるため、$b は null になります。

list はオフセットごとに 1 回のみアクセスされるようになりました:

<?php
list(list($a, $b)) = $array;

// PHP5:
$b = $array[0][1];
$a = $array[0][0];

// PHP7:
// 会产生一个中间变量,得到 $array[0] 的值
$_tmp = $array[0];
$a = $_tmp[0];
$b = $_tmp[1];

以前は特定の状況下でのみ空のリスト メンバーがすべて禁止されました:

<?php
list() = $a;           // 不合法
list($b, list()) = $a; // 不合法
foreach ($a as list()) // 不合法 (PHP5 中也不合法)

参照の順序assign

参照割り当ての順序は、PHP5 では右から左でしたが、現在は左から右です。

<?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"] => &int(1)
}

#clone メソッドは直接呼び出し可能です

これで、$obj->__clone() を直接使用して __clone メソッドを呼び出すことができます。 __clone は、以前は直接呼び出すことが禁止されていた唯一のマジック メソッドでした。以前は、次のようなエラーが発生していました:

Fatal error: Cannot call __clone() method on objects - use &#39;clone $obj&#39; instead in ...

変数構文の一貫性

AST もいくつかの問題を解決しました構文の一貫性の問題。これらの問題は別の RFC で提起されました: https://wiki.php.net/rfc/uniform_variable_syntax.

新しい実装では、以前の文法表現の意味は現在とは多少異なります。詳細については、次の表を参照してください:

diff
##メモリ 2360kB 2482kB
##$foo->{$bar['baz']} ##$foo->$ bar['baz' ]()推奨チュートリアル:「PHP7
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']() 全体的に、以前の順序は右から左でしたが、現在は左から右です。また、括弧は動作に影響を与えないという原則に従います。このような複雑な変数の書き方は、実際の開発では注意が必要です。

以上が新しい抽象構文ツリー (AST) によって PHP7 に加えられた変更の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPセットアップの簡単なガイド PHPセットアップの簡単なガイド Jul 18, 2025 am 04:25 AM

PHPを設定するための鍵は、インストールメソッドを明確にし、PHP.iniを構成し、Webサーバーに接続し、必要な拡張機能を有効にすることです。 1. PHPのインストール:LinuxにAPTを使用し、Mac用のHomeBrew、およびWindowsに推奨されるXAMPPを使用します。 2。PHP.iniの構成:エラーレポート、制限のアップロードなどを調整し、サーバーを再起動します。 3。Webサーバーの使用:Apacheはmod_phpを使用し、nginxはphp-fpmを使用します。 4.完全な機能をサポートするために、Mysqli、JSON、MbStringなど、一般的に使用される拡張機能:MySqli、JSON、Mbstringなどをインストールします。

PHPでコードをコメントします PHPでコードをコメントします Jul 18, 2025 am 04:57 AM

PHPコメントコードには3つの一般的な方法があります。1。//#を使用して1行のコードをブロックすると、//を使用することをお勧めします。 2。使用/.../複数の行でコードブロックをラップするには、ネストすることはできませんが交差することができます。 3. / if(){}を使用するなどの組み合わせスキルコメントロジックブロックを制御するか、エディターショートカットキーで効率を改善するには、シンボルを閉じることに注意を払い、使用時にネストを避ける必要があります。

PHPコメントを書くためのヒント PHPコメントを書くためのヒント Jul 18, 2025 am 04:51 AM

PHPコメントを書くための鍵は、目的と仕様を明確にすることです。コメントは、「何が行われたのか」ではなく「なぜ」を説明する必要があり、冗長性や単純さを避けてください。 1.読みやすさとツールの互換性を向上させるために、クラスおよびメソッドの説明にdocblock(/*/)などの統合形式を使用します。 2。JSジャンプを手動で出力する必要がある理由など、ロジックの背後にある理由を強調します。 3.複雑なコードの前に概要説明を追加し、手順でプロセスを説明し、全体的なアイデアを理解するのに役立ちます。 4. TodoとFixmeを合理的に使用して、To Doアイテムと問題をマークして、その後の追跡とコラボレーションを促進します。優れた注釈は、通信コストを削減し、コードメンテナンスの効率を向上させることができます。

コメントで読みやすさを向上させます コメントで読みやすさを向上させます Jul 18, 2025 am 04:46 AM

良いコメントを書くための鍵は、コードの読みやすさを改善するために「何が行われたか」ではなく「なぜ」を説明することです。 1。コメントは、価値の選択や処理の背後にある考慮事項など、論理的な理由を説明する必要があります。 2。複雑なロジックに段落注釈を使用して、関数またはアルゴリズムの全体的な考え方を要約します。 3.コードとの一貫性を確保し、誤解を招くことを避け、必要に応じて時代遅れのコンテンツを削除するために、コメントを定期的に維持します。 4.コードをレビューする際にコメントを同期して確認し、コードコメントの負担を軽減するためにドキュメントを介してパブリックロジックを記録します。

PHPの学習:初心者向けガイド PHPの学習:初心者向けガイド Jul 18, 2025 am 04:54 AM

tolearnphpefctivially、startbysettingupalocalserverenvironmentusingtoolslikexamppandacodeeditorlikevscode.1)instalxamppforapa Che、mysql、andphp.2)useocodeeditorforsyntaxsupport.3)testyoursetup withasimplephpfile.next、Learnpbasicsincludingvariables、ech

効果的なPHPコメントを書く 効果的なPHPコメントを書く Jul 18, 2025 am 04:44 AM

コメントは、古いインターフェイスとの互換性やサードパーティの制限など、機能ではなくコードの存在の理由を説明したいため、不注意にすることはできません。コメントしなければならない領域には、複雑な条件付き判断、特別なエラー処理ロジック、一時的なバイパス制限が含まれます。コメントを書くためのより実用的な方法は、シーンに基づいてシングルラインのコメントを選択したり、コメントをブロックすることです。ドキュメントブロックコメントを使用して、関数、クラス、ファイルの開始時にパラメーターと返品値を説明し、コメントを更新します。複雑なロジックについては、前のロジックにラインを追加して、全体的な意図を要約できます。同時に、コードを封印するためにコメントを使用しないでください。バージョン制御ツールを使用します。

クイックPHPインストールチュートリアル クイックPHPインストールチュートリアル Jul 18, 2025 am 04:52 AM

to installphpquickly、usexampponwindowsorhomebrewonmacos.1.onwindows、downloadandinstallxampp、selectcomponents、startapache、andplacefilesinhtdocs.2

PHPブロックコメントのマスター PHPブロックコメントのマスター Jul 18, 2025 am 04:35 AM

phpblockcommentsEursefurwritingmulti-lineexplanations、一時的にdisabledingcode、およびgeneratingdocumentation.theyshouldnotedorleftunclosed.blockcommentshelpindocumentingのfunctionswithphpdoc、whitooklikephpstormuseuto-compling-compling-compling comprivedoc

See all articles