PHP開発者のためのPHPソースコード(1): ソースコードの構造

WBOY
リリース: 2016-06-20 12:26:09
オリジナル
1079 人が閲覧しました

(追記: 英語の原文は 2012 年 3 月に書かれたものです)

開発者として、私は日々の業務の中で、もっともっと PHP ソースコードをもっと見てみましょう。舞台裏で何が起こっているのかを理解して、奇妙な境界問題や、何かが起こるべきときに何かが起こらない理由を解明するのに役立ちます。ドキュメントが不足している、不完全、または間違っている場合にも役立ちます。したがって、PHP 開発者に実際に PHP の C 言語ソース コードを読むのに十分な知識を提供するために、一連の記事を通じて私が学んだことを共有することにしました。 C の基本を知っている必要はありません (いくつかの基本をまとめます) が、知っていると役に立ちます。

これはこのシリーズの最初の記事です。この記事では、PHP プログラミングの基本、つまり、PHP プログラミングの場所、基本的なコード構造、および最も基本的な C 言語の概念について説明します。この一連の記事の目標は、ソース コードを読んで理解する能力を獲得することであることに注意してください。これは、特定のポイントを通過するために、特定の概念が過度に複雑な方法で説明されるのではなく、単純化されることを意味します。読む場合には目立った違いはありませんが、ソース コードに貢献したい場合は、より多くの知識を追加する必要があります。単純化するときは、それを指摘するようにしています。

さらに、この一連の記事はバージョン 5.4 のソース コードに基づいています。異なるバージョンでも、ほとんどの概念は同じですが、ここではこの記事のバージョン定義が必要です (新しいバージョンがリリースされた後は、次の記事がわかりやすくなります)。

それで、始めてもいいですか?

PHP のソース コードはどこにありますか?

PHP ソース コードをダウンロードする最も簡単な方法は、PHP の SVN リポジトリを使用することです。この記事では、5.4 ブランチをチェックアウトしました。これは、PHP の最先端にいる場合、または実際に PHP を開発している場合 (バグの修正、機能の実装など) に最適です。 PHP コミュニティが (この記事の執筆時点で) ソース コードを GIT リポジトリに移行していることは注目に値します。移行が完了して標準レベルに達したら、この投稿を更新します。 (翻訳者注: 翻訳者が翻訳した時点では、PHP は GIT ウェアハウスに移行されていました)。

実際、ソース コードをダウンロードしても、私たちの目的にはあまり役に立ちません。これを編集するのではなく、単に使用して、その実行方法を追跡したいだけです。これをダウンロードして優れた IDE にインポートし、クリックすると関数の定義と宣言にジャンプできますが、これは思ったよりも少し難しいことがわかりました。もっと良い解決策があります。

PHP コミュニティは、私たちにとって非常に優れたツールを維持していることがわかりました。それが lxr.php.net です。これは主に、構文の強調表示とすべての関数へのリンクを備えた、自動的に生成された検索可能なソース コード リストです。これは私が C ソース コードを参照するためにほぼ独占的に使用するツールであり、素晴らしいものです (パッチを作成しているときでも、開発中のコードベースではなく lxr を使用します)。より効率的な検索を行う方法についてはまだ説明しませんが、PHP のコア機能について説明するときに説明します。

ここからは PHP5.4 の話になります。この目的のために、この lxr リンクを他の記事の基礎として使用します。 「5.4 のルート ディレクトリ」とはこのページのことを指します。

ソース コード ディレクトリを表示できるようになったので、その内容について話しましょう。

PHP ソース コードの構造

まあ、5.4 のルート ディレクトリにリストされているファイルとディレクトリを見ると、さらに勉強すべきことがたくさんあります。 extZend の 2 つのディレクトリだけに注目してください。他のファイルとディレクトリは PHP 拡張機能と開発にとって重要ですが、ここでの目的のためには完全に無視できます。では、なぜこれら 2 つのディレクトリがそれほど重要なのでしょうか?

PHP プログラムは、ご想像のとおり、2 つの主要な部分に分かれています。最初の部分は Zend エンジンで、PHP コードの実行時に実行環境を制御します。これは、変数、式、構文解析、コード実行、エラー処理など、PHP が提供するすべての「言語層」機能を処理します。このエンジンがなければ、PHP は存在しません。エンジンのソース コードは Zend ディレクトリに配置されます。

PHP の 2 番目のコア部分は、PHP に含まれる拡張機能です。これらの拡張機能には、PHP で呼び出すことができるすべてのコア関数 (strpos、substr、array_diff、mysql_connect など) が含まれています。コア クラス (MySQLi、SplFixedArray、PDO など) も含まれます。

コア コード内で見たい機能がどこにあるかを判断する最も簡単な方法は、PHP ドキュメントのホームページを参照することです。 PHP のドキュメントも、(私たちの目的では) 言語リファレンスと関数リファレンスという 2 つの主要なセクションに分かれています。要約すると、言語リファレンスで定義を確認したい場合は、Zend フォルダーで見つかる可能性が高くなります。関数リファレンスにある場合は、ext フォルダーにあります。

C 言語の基本的な概念

このパートは、C 言語の入門を目的としたものではなく、「読者のサポート ガイド」を目的としています。次の概念があります:

変数

C では、変数は静的であり、厳密に型指定されます。これは、変数を使用する前に、その変数を型で定義する必要があることを意味します。一度定義すると、その型を変更することはできません (後で別の型に変換できますが、そのためには別の変数を使用する必要があります)。なぜなら、C言語では実際には変数が存在しないからです。これらは、私たちが使用するメモリアドレスの便利なラベルにすぎません。このため、C には PHP の参照がありません。代わりに、ポインタがあります。ここでは、ポインターを他の変数を指す変数と考えてください。 PHP の変数の変数と考えてください。

それでは、上記の説明を踏まえて、変数の構文について話しましょう。 C 言語では、変数を識別するために接頭辞を使用しません。したがって、(私たちの目的において) それらがどのように異なるかを知る唯一の方法は、それらの定義を確認することです。関数の先頭 (または関数の宣言内) の型とスペースの後に文字がある場合、それは変数です。注意すべき重要な点は、変数名の前に 1 つ以上の記号を付けることができるということです。アスタリスク (*) は、変数が特定の型 (参照) へのポインターであることを示します。 2 つのアスタリスクは、変数がポインターへのポインターであることを示します。 3 つのアスタリスクは、変数が別のポインターへのポインターであることを示します。

PHP は内部で多くの 2 レベル ポインターを使用するため、この間接アドレス指定は非常に重要です。これは、エンジンがデータのチャンク (PHP 変数) や、PHP 参照、コピーオンライト、オブジェクト参照などの興味深いタイプをすべて渡すことができる必要があるためです。したがって、**ptr は 2 レベルの参照 (変数への参照ではなく、データ参照への参照) を使用していることを意味することに注意してください。これも少しややこしいですが、引用がまったく初めての場合は、これを読むことをお勧めします (ただし、C を読む必要があるわけではありません)。それは助けになります。

ポインタについて理解する必要があるもう 1 つのことは、ポインタが C の配列 (PHP の配列ではなく、C の配列) をどのように扱うかということです。ポインタはメモリ アドレスであるため、メモリのブロックを割り当てることで配列を定義し、ポインタをインクリメントすることで配列を反復処理できます。通常の状況では、文字 (8 ビット) を表す C データ型 char を使用して、文字を文字列に格納できます。ただし、配列のように使用して、文字列の後のバイトにアクセスすることもできます。したがって、変数に文字列を格納する代わりに、最初のバイトにポインタを格納するだけで済みます。次に、ポインタをインクリメントして (メモリ アドレスを増やして)、文字列全体を反復処理します。

char *foo = "test";// foo 是指向"t"在内存的片段保存"test"的指针// 要访问"e",我们可以通过下面的方式:char e = foo[1];char e = *(foo + 1);char e = *(++foo);
ログイン後にコピー

C の変数とポインターの詳細については、この素晴らしい無料書籍を参照してください。

前処理命令

C はコンパイル前に「前処理」と呼ばれるステップを使用します。このステップには、コンパイラに渡すオプションに基づいてコードの一部を最適化し、動的に使用することが含まれます。条件文とマクロという 2 つの主要なプリプロセッサ仕様について説明します。

条件ステートメントを使用すると、出力をコンパイルするとき、または定義に基づいていないときにコードを導入できます。これは以下の例によく似ています。これにより、異なるオペレーティング システムに応じて異なるコードを使用できるようになります (そのため、異なる API を使用している場合でも、Windows と Linux で適切に使用できます)。さらに、定義された命令に基づいてコードの一部を導入したり、導入しなかったりすることもできます。実際、これは構成ステップ中に PHP がコンパイルされる方法です。

#define FOO 1#if FOOFoo is defined and not 0#elseFoo is not defined or is 0#endif#ifdef FOOFoo is defined#elseFoo is not defined#endif
ログイン後にコピー

別の説明 私はこれをマクロと呼んでいます。これは、コードを簡素化するための最も単純なミニ関数です。これらは実際の関数ではありませんが、コンパイル前処理中に単純なテキスト置換を実行します。したがって、マクロは実際には関数を呼び出しません。関数定義のマクロを作成できます (実際、これは PHP が行うことですが、これについては後の記事で説明します)。私が言いたいのは、マクロを使用すると、コンパイルの前処理時により単純なコードが可能になるということです。

#define FOO(a) ((a) + 1)int b = FOO(1); // Converted to int b = 1 + 1
ログイン後にコピー

ソース ファイル

最後の部分では、C ソース コードで使用される 2 種類のファイルを理解する必要があります。ファイルには主に .c.h の 2 つのタイプがあります。 .c ファイルは、コンパイルの準備ができているソース コードを含むファイルです。一般に、.c ファイルには、他のファイルと共有できないプライベート関数の実装が含まれています。 .h (またはヘッダー ファイル) は、前処理マクロなど、他のファイルから参照できる .c ファイル内の関数を定義します。ヘッダー ファイルでパブリック API を定義する方法は、関数本体を使用せずに関数のシグネチャを再宣言することです (PHP のインターフェイスや抽象メソッドと同様)。このようにして、ヘッダー ファイルを介してソース コードをリンクできます。

次のパート

この一連の記事の次のパートでは、C で内部関数がどのように定義されるかについて説明します。したがって、任意の内部関数 (strlen など) にジャンプして、その定義とその動作を確認できます。このリズムを保ってください。

翻訳者がより良い記事を翻訳できるようサポートするためのヒント、ありがとうございます!

翻訳者にチップ

より良い記事を翻訳できるように翻訳者をサポートするチップ、ありがとう!

支払い方法を選択してください

著者について: hoohack

働いている人ハードルーキー個人ホームページ · 私の記事 · 15 ·

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート