この記事では、PHP の言語の種類について説明します。一定の参考値があるので、困っている友達が参考になれば幸いです。
コンパイル言語
専用のコンパイラ (Windows の Visual Studio と同様) を使用し、特定のプラットフォーム (オペレーティング システム) をターゲットにします。特定の高級言語のソース コードを、プラットフォームのハードウェアによって一度に実行される機械語コード (機械語命令とオペランドを含む) に変換し、それをプラットフォームが認識できる実行可能プログラム (.exe) 形式にパッケージ化します。この変換プロセスはコンパイルと呼ばれます。コンパイルされた実行可能プログラムは、開発環境から分離して、特定のプラットフォーム上で独立して実行できます。一部のプログラムをコンパイルした後、他のコンパイル済みオブジェクト コードをリンクする必要がある場合があります。つまり、2 つ以上のオブジェクト コード モジュールをアセンブルして、最終的な実行可能プログラムを生成します。このようにして、低レベル コードの再利用が実現されます。
コンパイルされた言語コードは、一度コンパイルされ、繰り返し使用されます。つまり、先人は木を植え、子孫はその日陰を楽しんだのです。
コンパイルされたプログラムは、解釈されたプログラムよりもメモリ消費量が少なくなります。
#より多くのメモリと CPU リソースを消費します。これは、インタープリタ型言語で記述されたプログラムを実行するには、まず、関連するインタープリタを実行する必要があるためです。インタプリタは複雑でインテリジェントなリソースを大量に消費するプログラムであり、大量の CPU サイクルとメモリを消費します。
実行効率は、コンパイルされたプログラムよりもはるかに遅くなります。インタプリタは多くのコードの最適化とランタイム セキュリティ チェックを実行しますが、これらの追加の手順により多くのリソースが消費され、アプリケーションの速度がさらに低下します。
OK、上記の学習を通じて、誰もがインタプリタ言語とコンパイル言語について一般的に理解したと思います。PHP 言語はインタプリタ言語であり、PHP 言語を解釈するインタプリタです。ゼンドエンジンです。
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 のデフォルトは call なので、PHP のパフォーマンスをさらに低下させたい場合は、コマンド分散メソッドを goto に変更できます。ただし、goto メソッドを使用すると実行速度は向上しますが、コンパイル速度は実際には最も遅くなります。
------------------------------------------ ------ -------------------------------------------- ------ -------------------------------------------- ------ --
PHP のコンパイルと実行の分離の弱点について話しましょう:
実際、それは弱点とみなされません。 machine) はコンパイルと実行を厳密に分離しますが、ユーザーの観点から見ると、PHP スクリプト リクエストを実行するたびに、コンパイル -> 実行という 2 つの段階を実行する必要があるため、分離がないように見えます。欠けているステージはありません。したがって、これを c のようなコンパイル言語と比較できます。 同じリクエストを 100 回実行します。
①c の場合、初期段階で 1 回コンパイルするだけで済むため、コンパイル後に再度コンパイルされることはありません。 . 、実行するだけでよいため、損失は次のとおりです:
1 コンパイルと実行を 100 回行う
② php の場合、毎回コンパイルと実行が必要なので、損失は次のようになります。 :
100 回のコンパイルと 100 回の実行
明らかに: 定量的な観点から見ると、インタープリタ言語の消費量はコンパイル言語の消費量よりもはるかに多くなります。率直に言うと、PHP のコンパイルと実行の分離は、本当の意味での分離ではありません。そして c は実際の分離です。
php もこの問題を長い間認識していたため、この問題を解決する方法を考え出しました。この解決策が eAccelerator です。主な考え方は次のとおりです:
スクリプトが初めて実行された後、コンパイルされたスクリプトは特定の方法で保存されます (op_array がその中に保存されます)。当社が指定したキャッシュ有効期間内であれば、スクリプトが 2 回目に実行されます。このとき、繰り返しコンパイル作業を行う必要はなく、以前に保存したコンパイル済みファイルを直接呼び出して実行するため、プログラムのパフォーマンスが大幅に向上します。
この方法でPHPの効率はある程度向上しますが、究極の方法ではなく、コンパイル言語に変えるのが究極の方法です(笑~~~
-- ------------------------------------------------ ---- ------------------------------------------------ ---- ------------------------------------------
最後に、PHP のコンパイルと実行を分離することの利点について話しましょう;
この利点は実際にはユーザーではなくプログラマにあります。これら 2 つのステージが分離されているため、ここでやりたいことがいくつか実行できます。
たとえば、ファイルを暗号化および復号化する場合、一部の PHP スクリプトのソース コード ファイルを暗号化して、ユーザーがソース コードを見られないようにする必要があります。同時に、この暗号化されたソース コード ファイルは、PHP 仮想マシンによって解析および処理できます。もちろん、これを実現するには、まず暗号化と復号化のアルゴリズムを検討し、これが可逆的なプロセスであることを確認する必要があります。
php ソース コード ファイルを暗号化したので、この暗号化されたファイルのサフィックスを *.buaa であると仮定して定義する必要があります。問題は、PHP 仮想マシンがこのサフィックスを持つファイルを処理できるようにするにはどうすればよいでしょうか?これには、前述したコンパイルと実行を分離する必要があります。
思い出してください: コンパイル段階の入力は php ソース ファイルであり、出力は op_array です。さて、この段階では大騒ぎしましょう。主なアイデアは次のとおりです: まずコンパイル関数 zend_compile_file() で: 入力ファイルのサフィックスを確認します: それが通常の .php の場合は、通常のロジックに従います; *.buaa の場合は、最初に復号化してから次の手順に従います通常のロジック。 。 。
はぁ~とても簡単です。もちろん、このプロセスは前述したほど単純ではなく、zend_compile_file() 関数を直接変更することはできず、最終的にはこのプロセスを処理するためにモジュールを自分で拡張して実装する必要があります。
結論:
PHP はインタープリタ言語であり、PHP コードはオペコードに解釈され、実行のために Zend エンジンに渡されます。
APC を使用してオペコードをキャッシュし、PHP がオペコードとして解釈する時間を短縮します。
推奨学習: php ビデオ チュートリアル
以上がPHP はインタプリタ言語ですか、それともコンパイル言語ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。