php5 のオブジェクトとクラスの基本概念
最も基本的な概念から継承まで、主にオブジェクト指向の経験豊富なプログラマと、オブジェクトに触れたことのない読者を対象としています。
PHP プログラマーであれば、変数と関数についてよく知っているはずです。ただし、クラスとオブジェクトは別の話になる可能性があります。単一のクラスを定義しなくても、完全なシステムを作成することは可能です。ただし、コード内でオブジェクト指向プログラミングを使用しないことに決めた場合でも、オブジェクト指向プログラミングについて学びたいと思うかもしれません。たとえば、PHP Extension and Application Repository (PEAR) を通じて利用できるサードパーティ ライブラリを使用する場合、オブジェクトをインスタンス化しメソッドを呼び出すことになります。
クラスとオブジェクトとは何ですか?
簡単に言えば、クラスは変数とメソッドの独立したブロックまたはバンドルです。これらのコンポーネントは、多くの場合、単一の責任または一連の責任を実装するために組み合わせられます。この記事では、項目と値で構成されるディクショナリをクエリおよび設定するためのメソッドを集めたクラスを作成します。
クラスは、関数や変数のセットと同様に、データや機能を整理する簡単な方法として直接使用できます。ただし、クラスを使用すると、その存在を無視できます。クラスを使用して、メモリ内に複数のインスタンスを生成できます。このようなインスタンスはオブジェクトと呼ばれます。各オブジェクトは、同じ関数セット (オブジェクト指向のコンテキストではメソッドと呼ばれます) と変数 (属性またはインスタンス変数と呼ばれます) にアクセスできますが、各変数の実際の値はオブジェクトごとに異なります。
ロールプレイング ゲームのユニット (戦車など) を考えてみましょう。クラスは、戦車の一連の変数 (防御能力と攻撃能力、射程距離、体力など) を設定できます。このクラスは、move() や Attack() などの一連の関数を定義することもできます。システムに戦車クラスが含まれている場合、そのクラスを使用して数十または数百の戦車オブジェクトを生成でき、それぞれが独自の健全性または範囲特性を持つ可能性があります。したがって、クラスはオブジェクトを生成するための設計図またはテンプレートです。
おそらく、クラスとオブジェクトを理解する最も簡単な方法は、クラスとオブジェクトを作成することです。
最初のクラス
クラスは、class キーワードを使用して作成できます。最も単純なケースでは、クラスはキーワード class、名前、およびコードのブロックで構成されます:
クラス辞書 {
}
?
クラス名には文字、数字、アンダースコア文字を任意に組み合わせて含めることができますが、数字で始めることはできません。
上記の例の Dictionary クラスは、用途は限られていますが、完全に合法です。では、このクラスを使用してオブジェクトを作成するにはどうすればよいでしょうか?
$obj1 = 新しい辞書();
$obj2 = 新しい辞書();
$obj3 = 新しい辞書();
?
少なくとも非公式には、オブジェクトのインスタンス化は関数の呼び出しに似ています。関数呼び出しの場合は、括弧を指定する必要があります。関数と同様、一部のクラスではパラメータを渡す必要があります。 new キーワードも使用する必要があります。これにより、新しいオブジェクトをインスタンス化したいことが PHP エンジンに伝えられます。返されたオブジェクトは、将来使用するために変数に保存できます。
属性
クラスの本体では、属性と呼ばれる特別な変数を宣言できます。 PHP V4 では、プロパティはキーワード var を使用して呼び出す必要があります。これは依然として正当な構文ですが、主に下位互換性を目的としています。 PHP V5 では、プロパティはパブリック、プライベート、または保護されていると宣言する必要があります。キーワードで見つけることができます: ここで少しプライバシーを確保できますか?これらの修飾子については、 を参照してください。ただし、この例ではすべてのプロパティを public として宣言します。リスト 1 は、2 つのプロパティを宣言するクラスを示しています。
リスト 1. 2 つの属性を宣言するクラス
クラス辞書 {
???? public $translations = array();
???? public $type ="En";
}
?
ご覧のとおり、プロパティの宣言と値の割り当てを同時に行うことができます。 print_r() 関数を使用すると、オブジェクトの状態を簡単に確認できます。リスト 2 は、Dictionary オブジェクトにさらに多くのメンバーが含まれていることを示しています。
リスト 2. Dictionary オブジェクトのリスト
$en = new Dictionary();
print_r( $en );
スクリプトを実行すると、次のオブジェクトの出力が表示されます:
辞書オブジェクト
(
???? [翻訳] => 配列
??????? (
??????? )
???? [タイプ] => En
)
?
パブリック オブジェクトのプロパティには、オブジェクト演算子 -> を使用してアクセスできます。したがって、$en->type は、$en によって参照される Dictionary オブジェクトの $type プロパティを表します。プロパティにアクセスできる場合は、その値を設定および取得できることを意味します。リスト 3 のコードは、Dictionary クラスのインスタンスを 2 つ作成します。つまり、2 つの Dictionary オブジェクトをインスタンス化します。 1 つのオブジェクトの $type プロパティを変更し、2 つのオブジェクトの翻訳を追加します:
リスト 3. Dictionary クラスの 2 つのインスタンスを作成する
$en = new Dictionary();
$en->translations['TREE'] = "ツリー";
$fr = new Dictionary();
$fr->type = "Fr";
$fr->translations['TREE'] = "arbre";
foreach ( array( $en, $fr ) as $dict ) {
???? print "type: {$dict->type} ";
???? print "TREE: {$dict->translations['TREE']}n";
}
?
スクリプトの出力は次のとおりです
タイプ: En TREE: ツリー
タイプ: Fr TREE: arbre
?
つまり、Dictionary クラスがさらに便利になりました。単一のオブジェクトにさまざまなキーと値の組み合わせを格納でき、そのような辞書に関する詳細をクライアントに伝えるフラグがあります。
Dictionary クラスは現在、連想配列のラッパーに過ぎませんが、オブジェクトの機能に関するいくつかのヒントがここにあります。リスト 4 に示すように、サンプル データを適切に表現できるようになりました。
リスト 4. サンプル データ
$en = array(
???? 'translations'=>array( 'TREE' => 'tree' ),
???? 'type'=>'En'
);
$fr = array(
???? 'translations'=>array( 'TREE' => 'arbre' ),
???? 'type'=>'Fr'
);
?
このデータ構造は Dictionary クラスと同じ目的を達成しますが、構造の保証は提供されません。 Dictionary オブジェクトを渡すと、それに $translations プロパティがあることがわかります。しかし、リンクされたデータの場合、そのような保証はありません。このため、クエリを実行するコードが配列の起源を決定しない限り、 $fr['translations']['TREE']; のようなクエリは多少なりとも当たり外れが生じます。これがオブジェクトの本質です。オブジェクトの型はその特性を保証するものです。
オブジェクトを使用してデータを保存することには利点がありますが、それをまったく感じないかもしれません。オブジェクトは物である可能性がありますが、重要なのは、オブジェクトが何かを行うこともできるということです。
メソッド
簡単に言えば、メソッドはクラス内で宣言された関数です。これらは通常 (常にではありませんが)、オブジェクト演算子を使用してオブジェクト インスタンスから呼び出されます。リスト 5 では、Dictionary クラスにメソッドを追加し、そのメソッドを呼び出します。
リスト 5. Dictionary クラスへのメソッドの追加
クラス辞書 {
???? public $translations = array();
???? public $type ="En";
???? 関数 summary() {
????? $ret?? = "辞書の種類: {$this->type}n";
???? ??? $ret .= "用語: ".count( $this->translations ).";
?????? return $ret;
???? >}
$en->translations['TREE'] = "tree";
print $en->summarize();
次の出力が提供されます:
辞書の種類: En
用語: 1
ご覧のとおり、summary() メソッドの宣言は、クラス内で宣言されることを除けば、関数の宣言と同じです。 summary() メソッドは、オブジェクト演算子を使用して Dictionary インスタンスから呼び出されます。 summary() 関数はプロパティにアクセスして、オブジェクトの状態の概要を提供します。
この記事では新しい機能が使用されていることに注意してください。 $this 疑似変数は、オブジェクトが独自のプロパティとメソッドを参照するためのメカニズムを提供します。オブジェクトの外部では、ハンドルを使用してその要素 (この場合は $en) にアクセスできます。オブジェクト内にはそのようなハンドルがないため、$this を使用する必要があります。 $this がわかりにくいと思われる場合は、コード内で $this が見つかった場合は常に、心の中で $this を現在のインスタンスに置き換えてみてください。
クラスは通常、ユニバーサル モデリング言語 (UML) を使用して図で表されます。 UML の詳細についてはこの記事の範囲を超えていますが、この図はクラスの関係を視覚化するのに適した方法です。図 1 は、UML で表現された Dictionary クラスを示しています。クラス名が上部、プロパティが中央、メソッドが下部にあります。
コンストラクター
PHP エンジンは多くの「マジック」メソッドを認識します。メソッドが定義されている場合、対応する状況が発生したときに PHP エンジンが自動的にメソッドを呼び出します。最も一般的に実装されるメソッドはコンストラクター メソッドです。 PHP エンジンは、オブジェクトをインスタンス化するときにコンストラクターを呼び出します。オブジェクトの基本的なセットアップ コードはすべてコンストラクターに配置されます。 PHP V4 では、クラスと同じ名前のメソッドを宣言することでコンストラクターが作成されます。 V5 では、__construct() というメソッドを宣言する必要があります。リスト 6 は、DictionaryIO オブジェクトを必要とするコンストラクターを示しています。
クラス辞書 {
???? public $translations = array();
???? public $dictio;
???? function __construct( $type, DictionaryIO $dictio ) {
??????? ->dictio=$dictio;
???? }
???//...
?
Dictionary オブジェクトをインスタンス化するには、型文字列と DictionaryIO オブジェクトをそのコンストラクターに渡します。コンストラクターはこれらのパラメーターを使用して独自のプロパティを設定します。次のコードは、Dictionary オブジェクトをインスタンス化する方法を示しています。
$en = new Dictionary( "En", new DictionaryIO() );
?
もちろん、誰かが後で $type 属性を変更したり、$dictio を空に設定したりすることを妨げるものは何もありません。良いニュースとしては、PHP V5 がこの機能の実現に役立つということです。
キーワード: ここで少しプライバシーを保ってもいいですか? www.9qc.com
プロパティ宣言に関連する公開キーワードについては前に見てきました。このキーワードは属性の可視性を表します。実際、プロパティの可視性はパブリック、プライベート、保護に設定できます。 public として宣言されたプロパティは、クラスの外部から読み書きできます。private として宣言されたプロパティは、オブジェクトまたはクラスのコンテキストでのみ表示されます。 protected として宣言されたプロパティは、現在のクラスとそのサブクラスのコンテキスト内でのみ表示されます。 (これは「継承」セクションで実際に動作しているのがわかります。) プライベート プロパティを使用してクラスを実際にロックダウンすることができます。プロパティをプライベートとして宣言し、クラス スコープの外からアクセスしようとすると (リスト 7 を参照)、PHP エンジンは致命的なエラーをスローします。
リスト 7. クラス スコープ外からプロパティへのアクセスを試みる
クラス辞書 {
???? private $translations = array();
???? private $dictio;
????
?????? $this->type = $type;
????????? $this->dictio = $dictio;
???? }
}
$en->dictio = null;
出力は次のとおりです:
致命的なエラー: プライベート プロパティ
Dictionary::$dictio in...
にアクセスできません
一般に、ほとんどのプロパティをプライベートとして宣言し、必要に応じてそれらを取得および設定するメソッドを提供する必要があります。これにより、クラスのインターフェイスを制御したり、一部のデータを読み取り専用にしたり、パラメーターをプロパティに割り当てる前にパラメーターをサニタイズまたはフィルターしたり、オブジェクトと対話するための明確なルール セットを提供したりすることができます。
メソッドの可視性を変更する方法は、プロパティの可視性を変更する方法と同じです。つまり、メソッド宣言に public、private、または protected を追加します。クラスが外部に知られる必要のないハウスキーピング メソッドを使用する必要がある場合、そのクラスをプライベートとして宣言できます。リスト 8 の get() メソッドは、Dictionary クラスのユーザーに翻訳を取得するためのインターフェースを提供します。このクラスはすべてのクエリを追跡する必要があるため、プライベート メソッド logQuery() が提供されています。
リスト 8. get() メソッドは、Dictionary クラスのユーザーにインターフェースを提供します
function get( $term ) {
???? $value = $this->translations[$term];
???? $this->logQuery( $term, $value , "get" );
???? return $value;
}
???? // ログ情報を書き込みます
}
logQuery() をプライベートとして宣言すると、パブリック インターフェイスが簡素化され、クラスが logQuery() を不適切に呼び出すことがなくなります。プロパティと同様に、含まれているクラスの外部からプライベート メソッドを呼び出そうとすると、致命的なエラーが発生します。
クラス コンテキストでの操作
これまで見てきたメソッドとプロパティはすべてオブジェクト コンテキストで操作されます。つまり、$this 疑似変数または標準変数に格納されているオブジェクト参照を通じてメソッドやプロパティにアクセスするには、オブジェクト インスタンスを使用する必要があります。場合によっては、オブジェクト インスタンスではなくクラスを通じてプロパティやメソッドにアクセスする方が便利な場合があります。このようなクラス メンバーは静的メンバーと呼ばれます。
次の例は、単一の静的プロパティ $iodir を示しています。これは、辞書データの保存と読み取りに使用されるデフォルトのディレクトリへのパスを保持します。このデータはすべてのオブジェクトで同じであるため、すべてのインスタンスで使用できるようにするのが合理的です。
リスト 9. 単一の静的 $iodir プロパティ
クラス辞書 {
???? public static $iodir=".";
???? // ...
}
静的プロパティには、二重コロン (::) で構成されるスコープ解決演算子を使用してアクセスできます。スコープ解決演算子は、クラス名とアクセスする静的プロパティの間に配置する必要があります。
print Dictionary::$iodir . "n";
Dictionary::$iodir = "/tmp";
ご覧のとおり、このプロパティにアクセスするには Dictionary オブジェクトをインスタンス化する必要はありません。
静的メソッドを宣言してアクセスするための構文はこれに似ています。繰り返しますが、static キーワードは可視性修飾子の後に配置する必要があります。リスト 10 は、プライベートとして宣言された $iodir プロパティにアクセスする 2 つの静的メソッドを示しています。
リスト 10. $iodir プロパティにアクセスする 2 つの静的メソッド
class Dictionary {
???? private static $iodir=".";
???? // ...
???? public static function setSaveDirectory( $dir ) {
????????? if ( ! is_dir( $dir ) ||
???????????? ! is_writable( $dir ) ) {
?? ?????????? false を返します;
????????? self::$iodir = $dir;
??? ?}
???? public static function getSaveDirectory( ) {
???? // . .
}
?
どちらのメソッドもキーワード self とアクセス解決演算子を使用して $iodir プロパティを参照することに注意してください。 $this は現在のオブジェクト インスタンスへの参照であるため、静的メソッドで $this を使用することはできませんが、静的メソッドはオブジェクトではなくクラスを通じて呼び出されます。 PHP エンジンが静的メソッドで $this を認識すると、致命的なエラーとメッセージがスローされます。
クラスの外部から静的メソッドを呼び出すには、クラス名に加えてスコープ リゾルバーとメソッド名を使用します。
Dictionary::setSaveDirectory("/tmp");
print Dictionary::getSaveDirectory();
?
静的メソッドを使用する重要な理由が 2 つあります。まず、ユーティリティ操作では、そのジョブを実行するためにオブジェクト インスタンスが必要ない場合があります。静的として宣言すると、クライアント コードでオブジェクトを作成する手間が省けます。 2 番目に、静的メソッドはグローバルに利用可能です。これは、すべてのオブジェクト インスタンスがアクセスできる値を設定できることを意味し、静的メソッドはシステム上の重要なデータを共有するための優れた方法になります。
静的プロパティは通常、他のものによる干渉を防ぐためにプライベートとして宣言されますが、定数を宣言することで、読み取り専用の静的スコープのプロパティを作成する方法があります。グローバル プロパティと同様、クラス定数は一度定義すると変更できません。これはステータス フラグや、pi やアフリカのすべての国など、プロセスの存続期間中に変更されないものに使用されます。
const キーワードを使用してクラス定数を宣言します。たとえば、Dictionary オブジェクトの実際の実装にはほぼ確実にその背後にデータベースがあるため、用語と翻訳には最大長があると想定することもできます。リスト 11 では、これをクラス定数として設定します。 http://www.k686.com
リスト 11. MAXLENGTH をクラス定数として設定する
クラス辞書 {
???? const MAXLENGTH = 250;
???? // ...
}
print Dictionary::MAXLENGTH;
?
クラス定数は常にパブリックであるため、visibility キーワードは使用できません。その値を変更しようとすると解析エラーが発生するため、これは問題ではありません。また、通常のプロパティとは異なり、クラス定数はドル記号で始まらないことにも注意してください。
継承
オブジェクト指向プログラミングに詳しい人なら、私が常に最良のものを最後に取っておくことがわかるでしょう。クラスとクラスが生成する動的オブジェクト間の関係により、システムはより柔軟になります。たとえば、各 Dictionary オブジェクトは翻訳データの異なるコレクションをカプセル化しますが、これらの異なるエンティティのモデルは単一の Dictionary クラスで定義されます。
しかし、場合によってはクラスレベルの違いに注意する必要があります。 DictionaryIO クラスを覚えていますか?要約すると、Dictionary オブジェクトからデータを取得し、ファイル システムに書き込み、ファイルからデータを取得して、Dictionary オブジェクトにマージし直します。リスト 12 は、シリアル化を使用して辞書データを保存およびロードする簡単な実装を示しています。
リスト 12. シリアル化を使用した迅速な実装
クラス辞書 {
???? // ...
???? 関数 asArray() {
????? return $this->translations;
???? }
?? 関数 getType() {
????? return $this->type;
????
????? $this->dictio->export( $this );
???? }
????? $this->dictio->import( $this );
???? }
}
???? 関数 path( Dictionary $dictionary, $ext ) {
????? $path?? = Dictionary::getSaveDirectory();
???? ? $path .= DIRECTORY_SEPARATOR;
????????? $path .= $dictionary->getType().".$ext";
???????パス;
???? }
????? $translations = $dictionary->asArray();
??????? this->path(
???????????????????????????$dictionary, 'serial'),
??シリアル化( $translations );?
}
????? $path = $this->path( $dictionary, 'serial' );
??? ?????? if ( ! is_file( $path ) )
????????? $translations = unserialize(
????????? ? ?????????? file_get_contents( $path ) );
????? foreach ( $translations as $term => $trans ) {
????? ?? ????? $dictionary->set( $term, $trans );
??????? }
}
$dict = new Dictionary( "En", new DictionaryIO() );
$dict->export();
?
この例では、2 つの単純な Dictionary メソッドを紹介します。具体的には、asArray() は $translations 配列のコピーを返します。 DictionaryIO の実装には、単純さという利点があります。サンプル コードではエラー チェックが省略されることが多いため、それでも、これはデータをファイルに保存するための迅速かつ簡単な方法です。
このようなライブラリがデプロイされたら、その保存形式をすぐにサポートする必要があります。この形式を廃止すると、この方法でバックアップを保存するユーザーの希望に反することになります。しかし、要件は変化しており、出力形式がユーザーにとって編集しにくいという苦情を受けることもあります。これらのユーザーは、エクスポート ファイルを XML 形式でサードパーティに送信したいと考えています。
現在、問題に直面しています。 DictionaryIO インターフェイスで両方の形式をサポートするにはどうすればよいですか?
1 つの解決策は、リスト 13 に示すように、export() メソッドと import() メソッドで条件文を使用して型フラグをテストすることです。
リスト 13.export() メソッドと import() メソッドでの条件文の使用
function export( Dictionary $dictionary ) {
???? if ( $this->type == DictionaryIO::SERIAL ) {
????? // シリアル化されたデータを書き込みます
???? } else if ( $this->type == DictionaryIO::XML ) {
?????? // XML データを書き込みます
???? }
???? if ( $this->type == DictionaryIO::SERIAL ) {
??????? // シリアル化されたデータを読み取る
???? } else if ( $this->type == DictionaryIO::XML ) {
?????? // XML データを読み取ります
???? }
?
この構造は、コピーへの依存による悪い「コード臭」の一例です。 1 か所で変更を加えると (たとえば、新しい型テストを追加する)、他の場所でも対応する一連の変更が必要になります (他の型テストをラインに組み込む) ため、コードはすぐにエラーが発生しやすくなり、読みにくくなります。
継承は、より洗練されたソリューションを提供します。 DictionaryIO によって設定されたインターフェイスを継承しながら、その機能の一部をオーバーライドする新しいクラス XmlDictionaryIO を作成することができます。
サブクラスを作成するには、extends キーワードを使用します。以下は、XmlDictionaryIO クラスの最小限の実装です:
XmlDictionaryIO extends DictionaryIO {}
?
XmlDictionaryIO は DictionaryIO とまったく同じように機能するようになりました。 DictionaryIO からすべてのパブリック (および保護された) プロパティを継承するため、DictionaryIO オブジェクトに適用されるのと同じ操作を XmlDictionaryIO オブジェクトに適用できます。この関係はオブジェクトの種類にも及びます。 XmlDictionaryIO オブジェクトは明らかに XmlDictionaryIO クラスのインスタンスですが、DictionaryIO のインスタンスでもあります。同様に、一般化された順序で、人は同時に人間、哺乳類、動物でもあります。これをテストするには、instanceof 演算子を使用します。この演算子は、オブジェクトが指定されたクラスのメンバーである場合に true を返します (リスト 14 を参照)。
リスト 14.instanceof 演算子を使用した継承のテスト
$dictio = new XmlDictionaryIO();
if ( $dictioinstanceof XmlDictionaryIO ) {???? print "オブジェクトは XmlDictionaryIOn のインスタンスです";
}
if ( $dictioinstanceof DictionaryIO ) {
}
?
出力は次のとおりです:
オブジェクトは XmlDictionaryIO のインスタンスですオブジェクトは DictionaryIO のインスタンスです
?
instanceof が DictionaryIO オブジェクトである $dictio を受け入れるのと同じように、メソッドもこれらのオブジェクトをパラメータとして受け入れます。これは、DictionaryIO がコンストラクターのシグネチャで指定された型であっても、XmlDictionaryIO オブジェクトを Dictionary クラスのコンストラクターに渡すことができることを意味します。
リスト 15 は、DOM を使用して XML 機能を完成させる、手早く汚い XmlDictionaryIO 実装です。
リスト 15. XmlDictionaryIO 実装
クラス XmlDictionaryIO extends DictionaryIO {
???? 関数 export( Dictionary $dictionary ) {
?????? $translations = $dictionary->asArray();??????$ doc = new DOMDocument("1.0");
??????$dic_el = $doc->createElement( "dictionary" );
??????$doc- >appendChild( $dic_el ) ;
????????? foreach ( $translations as $key => $val ) {
????????? $term_el = $doc->createElement( " term" );
???????????? $dic_el->appendChild( $term_el );
????????? ???? $key_el = $ doc->createElement("key", $key );
????????? $val_el = $doc->createElement(
?????????? ????????????? "値", $val );
????????? $term_el->appendChild( $key_el );
???????$term_el->appendChild( $val_el );
????????? }
??? file_put_contents( $this ->path(
?????????????????????$dictionary, 'xml') ,
??????? ????????????????$doc->saveXML() );
??? }
???関数 import( Dictionary $dictionary ) {
??? ?????? if ( ! is_file( $path ) ) return false;
????????? $doc = DOMDocument::loadXML(
????????? ? ??? file_get_contents( $path ) );
??????$termlist = $doc
??????????????? - > getElementsByTagName( "term" );
????????? foreach ( $termlist as $term ) {
????????? $key = $term- >getElementsByTagName( "key" )
??????????????? ->item( 0 )->nodeValue;
?????? ?? $val = $term
??????????????? ->getElementsByTagName( "value" )
?????? ???????? ->item( 0 )->nodeValue;
???????????? $dictionary->set( $key, $ val ); 🎜>????????? }
???? }
}
?
import() と export() は両方とも、XmlDictionaryIO クラスには存在しないユーティリティ メソッド path() を呼び出すことに注意してください。ただし、Path() は DictionaryIO に実装されているため、問題はありません。 XmlDictionaryIO がメソッドを実装する場合、メソッドが呼び出されたときに、その実装が XmlDictionaryIO オブジェクトに対して呼び出されます。実装が存在しない場合、呼び出しは失敗し、親クラスに返されます。
まとめ
紙面の都合上、全てを紹介することはできません。さらなる研究には、幅広さと深さという 2 つの方向性があります。幅とは、抽象クラス、インターフェイス、イテレータ インターフェイス、リフレクション、例外、オブジェクト レプリケーションなど、この記事の範囲を超えている機能を指します。深さは設計上の問題を指します。 PHP でのオブジェクト指向プログラミングに利用できるツールの範囲を理解することは重要ですが、これらの機能を最適に使用する方法を検討することも同様に重要です。幸いなことに、オブジェクト指向のコンテキストにおけるデザイン パターンを特にカバーするリソースが多数あります。
この記事は Goldtimes.net からのものです 元のリンク: goldtimes.net/member/view.asp?ID=1423
k686 Green Software の貢献に感謝します。