ホームページ  >  記事  >  バックエンド開発  >  PHP が解釈されるかコンパイルされるかを理解するのに 1 分?

PHP が解釈されるかコンパイルされるかを理解するのに 1 分?

慕斯
慕斯転載
2021-06-21 09:58:433134ブラウズ

この記事では、PHP が解釈されるのかコンパイルされるのかについて 1 分で説明します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PHP が解釈されるかコンパイルされるかを理解するのに 1 分?

##コンパイル言語

    使用特定の高級言語のソース コードを、特定のプラットフォーム (オペレーティング システム) 向けにプラットフォーム ハードウェアによって一度に実行されるマシン コード (機械語命令とオペランドを含む) に「変換」する専用のコンパイラ (Windows の Visual Studio に似ています)この変換プロセスをコンパイルと呼びます。コンパイルされた実行可能プログラムは、開発環境から分離して、特定のプラットフォーム上で独立して実行できます。一部のプログラムをコンパイルした後、他のコンパイル済みオブジェクト コードをリンクする必要がある場合があります。つまり、2 つ以上のオブジェクト コード モジュールをアセンブルして、最終的な実行可能プログラムを生成します。このようにして、低レベル コードの再利用が実現されます。
  • コンパイルされた言語コードは、一度コンパイルされ、繰り返し使用されます。つまり、先人は木を植え、子孫はその日陰を楽しんだのです。
  • C、C、Objective-C などはすべてコンパイル言語です

インタープリタ言語

    プログラムの実行前ソースプログラムは中間言語にプリコンパイルされ、インタプリタが中間言語を実行します。
  • インタープリタ型言語のプログラムは実行するたびに一度コンパイルする必要があるため、インタープリタ型言語プログラムの実行効率が低下します。通常は低く、インタプリタから独立して実行することはできません。
  • C#、PHP、Python、Java などはすべてインタープリタ型言語です。
OK、上記の概念を簡単に理解すれば、インタプリタ言語とコンパイル言語について一般的に理解できるでしょう。両者は平等に世界を共有しているので、それぞれの利点を見てみましょう。

コンパイル言語

利点

##コンパイル言語の最大の利点の 1 つは、その実行速度です。 C/C で書かれたプログラムは、Java で書かれた同じプログラムよりも 30% ~ 70% 高速に実行されます。
コンパイルされたプログラムは、解釈されたプログラムよりもメモリ消費量が少なくなります。
  • #欠点

欠点 - コンパイラはインタプリタよりも書くのがはるかに難しい

  • ##コンパイラーは、プログラムのデバッグ時にあまり役に立ちません。C コードで「Null ポインター例外」に何度遭遇し、コードのどこにエラーがあるかを特定するのに何時間もかかったことでしょう。
  • 実行可能なコンパイル済みコードは、同じ解釈されたコードよりもはるかに大きくなります。たとえば、C/C .exe ファイルは、同じ機能を持つ Java .class ファイルよりもはるかに大きくなります。
  • コンパイルされたプログラムはプラットフォーム固有であるため、プラットフォームに依存します。
  • コンパイルされたプログラムは、コード内でのセキュリティの実装をサポートしていません。たとえば、コンパイルされたプログラムは、メモリの任意の領域にアクセスし、PC に対して必要なことを何でも行うことができます (ほとんどのウイルスはコンパイル済み言語を使用して記述されています)
  • セキュリティとプラットフォームへの依存性が緩いため、コンパイル済み言語はインターネットまたは Web ベースのアプリケーションの開発には適していません。
  • インタープリタ言語

利点

優れたデバッグ サポート。 PHP プログラマが「Null Pointer Exception」を見つけて修正するのに数分しかかかりません。これは、PHP 実行環境が例外の性質を示すだけでなく、例外が発生した特定の行番号と関数呼び出しシーケンスも示すためです (有名なスタックトレース情報)。このような利便性はコンパイル言語では提供されません。

  • インタプリタはコンパイラよりも実装が簡単です
  • 優れたプラットフォーム独立性
  • 高いレベルセキュリティ - これはインターネット アプリケーションに緊急に必要です
  • 中間言語コードのサイズは、コンパイルされた実行可能コードよりもはるかに小さいです
  • 欠点

  • より多くのメモリと CPU リソースを消費します。これは、インタープリタ型言語で記述されたプログラムを実行するには、まず、関連するインタープリタを実行する必要があるためです。インタプリタは複雑でインテリジェントなリソースを大量に消費するプログラムであり、大量の CPU サイクルとメモリを消費します。
  • 実行効率は、コンパイルされたプログラムよりもはるかに遅くなります。インタプリタは多くのコードの最適化とランタイム セキュリティ チェックを実行しますが、これらの追加の手順により多くのリソースが消費され、アプリケーションの速度がさらに低下します。

OK、上記の学習を通じて、誰もがインタプリタ言語とコンパイル言語について一般的に理解したと思います。PHP 言語はインタプリタ言語であり、PHP 言語を解釈するインタプリタは Zend です。エンジン。

さらに、この 2 つの長所と短所を比較すると、コンパイル言語は低レベルの操作に適しており、インタープリタ言語は Web 開発でよく使用されていることがわかります。 。

PHP の実行プロセスを詳しく見てみましょう:

PHP のコンパイルと実行は分離されています。つまり、コンパイルが最初に完了してから実行されます。多くの人は、「確かに、c についても同じことが当てはまります」と言うでしょう。ただし、この PHP の分離により、多くの利便性が得られますが、もちろん、多くの欠点もあります。

まずプロセス全体について話しましょう:

①php はコンパイル関数 zend_compile_file() を呼び出してコンパイルします。この関数の具体的な実装には、実際には字句解析 (Lex 実装) と構文解析 (Yacc 実装) という 2 つの主要なプロセスが含まれます。この関数を実行すると、php スクリプトのコンパイルが完了します。この関数の入力は: php スクリプト ファイル、出力は op_array です。簡単に言うと、コンパイル プロセスは、スクリプトを php 仮想マシンが処理できる命令に解析することであり、op_array はこれらの命令で構成される単なる配列です。 (これは、いくつかのコンパイル言語のコンパイルによって生成されるアセンブリ コードに非常に似ており、これも 1 つずつコマンドです)。

②: 次に、php 仮想マシンは zend_execute() 関数を呼び出して実行します。この関数の入力は、上記のコンパイル段階で生成された op_array であり、各コマンドを解析して処理します。 op コマンドは合計で約 150 個あるため、この 150 個のコマンドを処理する必要があります。ここで非常に興味深い疑問が生じます。これらの 150 個のコマンドはどのように処理されるのでしょうか?まず、各コマンドには、処理に対応するプロセッサがあります。したがって、仮想マシンは、op_array 内の各コマンドのタイプに基づいて、対応するプロセッサに分散されて処理されます。

ここで 2 つの小さな質問があります: 1: ここのプロセッサは何ですか? 2: どのように配布されますか?

これら 2 つの質問に答えるには、分散メカニズムから説明する必要があります: PHP 仮想マシンがコマンドを分散するには、CALL、SWITCH、GOTO の 3 つのメカニズムがあります。PHP はデフォルトで CALL メソッドを使用します。つまり、すべてのオペコード プロセッサは関数として定義され、仮想マシンによって呼び出されます。この方法は従来の方法であり、一般に最も安定した方法と考えられています。SWITCH メソッドと GOTO メソッドは、switch と goto を通じてオペコードを配布します。実行に対応する処理ロジック (セグメント)

次に、上記の 2 つの質問に答えましょう:

1: プロセッサは、実際に op コマンドのロジックを処理します。コマンドの配布方法に応じて、関数または論理セグメントの形式で存在できます。

2: 配信方法には、call、switch、goto の 3 つがあります。どちらがより効率的ですか?実際、上記の説明からすでに予備的な理解を得ることができます。 switch と goto の両方には、zend_execute() 関数内に対応する論理セグメントがあり、直接実行できます。この呼び出しにより、zend_execute() 関数の関数呼び出しが実行されます。当然のことですが、関数の呼び出し効率は最も低く、一度呼び出した後はスタックにプッシュする必要があります。したがって、効率の観点から言えば、コールが最も低くなっています。 switch と goto の場合: たとえば、3 番目のコマンドの処理を実行したい場合: switch は最初に最初の 2 つであるかどうかを判断する必要がありますが、goto はまったく判断する必要がなく、コマンドの論理コードセグメントに直接ジャンプします。 3 番目のコマンドを実行する これは、Switch よりも優れており、上から下への逐次的な判断の損失が軽減されるため、スイッチよりも goto の効率が高くなります。一般に、次の 3 つの配布方法: goto > switch > call

PHP のコンパイルと実行の分離の弱点について話しましょう:

実際には、 zend エンジン (php の仮想マシン) はコンパイルと実行を厳密に分離していますが、ユーザーにとっては、あたかも分離がないかのようです。実行するには: これら 2 つの段階をコンパイル -> 実行します。欠けているステージはありません。したがって、これを c のようなコンパイル言語と比較できます。 同じリクエストを 100 回実行する

① c の場合、初期段階で 1 回コンパイルするだけで済むため、コンパイル後は再度コンパイルされません。

1 コンパイルと実行を 100 回行う

② php の場合、毎回コンパイルと実行が必要なので、損失は次のようになります。は:

100 回コンパイルし、100 回実行します

明らかに: 定量的な観点から見ると、インタプリタ言語はコンパイル言語よりもはるかに多くの電力を消費します。率直に言うと、PHP のコンパイルと実行の分離は、本当の意味での分離ではありません。そして c は実際の分離です。

PHP はこの問題を長い間認識していたため、この問題を解決する方法を考え出しました。この解決策が eAccelerator です。主な考え方は次のとおりです:

スクリプトが初めて実行された後、コンパイルされたスクリプトは特定の方法で保存されます (op_array がその中に保存されます)。当社が指定したキャッシュ有効期間内であれば、スクリプトが 2 回目に実行されます。このとき、繰り返しコンパイル作業を行う必要はなく、以前に保存したコンパイル済みファイルを直接呼び出して実行するため、プログラムのパフォーマンスが大幅に向上します。

最後に、PHP のコンパイルと実行を分離することの利点について話しましょう;

この利点は実際にはユーザーにとってではなく、プログラマーにとってのものです。これら 2 つのステージが分離されているため、ここでやりたいことがいくつか実行できます。

たとえば、ファイルを暗号化および復号化する場合、一部の PHP スクリプトのソース コード ファイルを暗号化して、ユーザーがソース コードを見られないようにする必要があります。同時に、この暗号化されたソース コード ファイルは、PHP 仮想マシンによって解析および処理できます。もちろん、これを実現するには、まず暗号化と復号化のアルゴリズムを検討し、これが可逆的なプロセスであることを確認する必要があります。

PHP ソース コード ファイルを暗号化したので、この暗号化されたファイルのサフィックスを *.buaa と仮定して定義する必要があります。問題は、PHP 仮想マシンがこのサフィックスを持つファイルを処理できるようにするにはどうすればよいでしょうか?これには、前述したコンパイルと実行を分離する必要があります。

思い出してください: コンパイル段階の入力は php ソース ファイルであり、出力は op_array です。さて、この段階では大騒ぎしましょう。主なアイデアは次のとおりです: まずコンパイル関数 zend_compile_file() で: 入力ファイルのサフィックスを確認します: それが通常の .php の場合は、通常のロジックに従います; *.buaa の場合は、最初に復号化してから次の手順に従います通常のロジック。 。 。

結論:

  • PHP はインタープリタ言語であり、PHP コードはオペコードに解釈され、実行のために Zend エンジンに渡されます。

  • APC を使用してオペコードをキャッシュし、PHP がオペコードとして解釈する時間を短縮します。

推奨学習: php ビデオ チュートリアル

以上がPHP が解釈されるかコンパイルされるかを理解するのに 1 分?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。