PHP V5.3 の新機能、パート 1: オブジェクト インターフェイスの変更
http://www.ibm.com/developerworks/cn/opensource/os-php-5.3new1/
PHP V5 とオブジェクト指向プログラミング
でリリースされた PHP V4 で提供される機能との比較2004 PHP V5 は、オブジェクト指向プログラミング (OOP) と設計において大きな前進をもたらしました。クラスの可視性、適切なコンストラクターとデストラクター、入力ヒント、クラス リフレクション API など、必要ないくつかの改善が提供されます。これにより、PHP での高度なオブジェクト指向プログラミングへの扉が開かれ、よりシンプルな設計パターンと、より適切に設計されたクラスと API が可能になります。
PHP V5.3 では、OOP に多数の進歩的な追加機能が提供されています。これらの改善は、構文の追加とパフォーマンスの向上に重点が置かれています。まず、静的メソッドと静的メンバーの新機能を見ていきます。
----------------------------------------------------- ---
トップに戻る
静的メソッドとメンバーの処理の改善
PHP V5 の便利な追加機能は、メソッドまたはクラス メンバーを静的として指定できることです (PHP V4 はメソッドと静的メンバーをサポートしています)クラス メンバーへのアクセスは可能ですが、静的アクセス専用にメソッドまたはメンバーを指定することはできません)。静的アクセスは、クラスのインスタンスが 1 つだけ存在する単一の設計パターンを実装する場合に特に適しています。
PHP V5.3 は、クラスの静的メンバーとメソッドのサポートを強化するいくつかの機能を提供します。最近追加されたマジック メソッド __callStatic() を見てみましょう。
_callStatic() マジック メソッド
PHP V5 には、クラス内で使用できる、マジック メソッドと呼ばれる特別に定義されたメソッドがいくつか用意されています。これらのメソッドをクラス内で定義すると、特別な機能が提供され、オーバーロード (メソッドが異なる型のパラメーターを受け入れることができるようになります) とポリモーフィズム (異なるデータ型が同じインターフェイスを使用できるようになります) がサポートされます。また、さまざまなタイプの OOP プログラミング手法や PHP のデザイン パターンを簡単に使用できるようになります。
PHP V5.3 では、新しいマジック メソッド __callStatic() が追加されました。これは __call() マジック メソッドと同様に機能します。このメソッドは、クラス内で定義されていないメソッド、またはクラスに表示されないメソッドへの呼び出しを処理するように設計されています。ただし、__callStatic() は静的メソッド呼び出しを処理することを目的としており、これによりメソッドのオーバーロードをより適切に設計できるようになります。この方法の使用例を以下に示します。
リスト 1. __callStatic() と __call() の使用例
class Foo
{
public static function __callStatic(
$name,
$args
)
{
echo "メソッド $name を静的に呼び出した";
}
public function __call(
$name,
$args
) {
Echo "呼び出されたメソッド $ Name";
}
}
Foo :: Dog () // 「呼び出されたメソッド Dog 静的」を出力します
$foo = new Foo;
$foo->dog(); // 「呼び出されたメソッド Dog」を出力します
PHP が実際にサポートを強化していることに注意してください。 __callStatic () メソッドの定義。パブリックである必要があり、静的に宣言する必要があります。同様に、__call() マジック メソッドは、他のすべてのマジック メソッドと同様に、パブリックとして定義する必要があります。
----------------------------------------------------- ---
トップに戻る
動的静的呼び出し
PHP の優れた機能は可変変数です。これは、ある変数の文字列値を使用して別の変数の名前を指定できることを意味します。つまり、次のようなことができます。
リスト 2. 可変変数
x = 'y';
$$x = 'z';
echo $x ;
echo $$x; //
出力 'z'
これは、以下に示すように、関数やクラス メソッドに対しても機能します。
リスト 3. 変数関数とクラス メソッドの名前
class Dog
{
public function bark()
{
echo "Woof! " ;
}
}
$class = 'Dog'
$action = 'bark';
$x = new $class(); '
$x->$action(); // 「Woof!」を出力します
PHP V5.3 の新機能は、静的呼び出しを行うときに、指定されたクラス名は変数です。これにより、以下に示すように、いくつかの新しい機会が提供されます。
リスト 4. 変数クラスの名前付け
class Dog
{
public static function bark()
{
echo "Woof!" ; 🎜> }
}
$class = 'Dog';
$action = 'bark';
$class::$action(); //「Woof!」を出力します。 PHP の変更可能な機能により、PHP に関連するあらゆる状況に適用できます。
静的メソッドとメンバーのアプリケーションに対するより便利な拡張機能の 1 つである遅延静的バインディングを見てみましょう。
----------------------------------------------------- ---
トップに戻る
遅延された静的バインディング
V5.3 より前の PHP における厄介な問題は、静的メソッドとメンバーをどのように扱うかということでした。これまで、それ自体または __CLASS__ を使用する静的参照は、関数が定義されているクラスのスコープ内で解決されていました。問題は、クラスが拡張され、呼び出しが新しいサブクラスから行われる場合、解析が正しく行われないことです。 PHP V5.3 では、この問題を解決するために遅延静的バインディングが追加されました。よりわかりやすく説明するために、以下では静的メソッドを含むクラスを作成します。
リスト 5. 静的メソッド test() を使用したクラス Foo
class Foo
{
protected static $name = 'Foo'; public static function test()
{
return self::$name;
}
}
このクラスを拡張しましょう。サブクラスのメンバー $name を再定義します。
リスト 6. サブクラス Bar は親クラス Foo
class Bar
{
protected static $name = 'Bar'
}
リスト 7 では静的呼び出しを行いました。
リスト 7. 静的メソッド呼び出し test()
echo Bar::test();
この呼び出しの出力は次のとおりです。文字列 Foo。これは、test() メソッドで行われる self::$name への参照が Foo クラスで行われるためです。このバインディングの理由は、関数がクラス Foo で定義されているためです。
PHP V5.3 では、現在のクラスへの参照を許可するキーワード static が追加されました。したがって、リスト 8 でこのキーワードを使用するように上記の Foo クラスを変更すると、出力が Bar になることがわかります。
リスト 8. static キーワードの使用
class Foo
{
protected static $name = 'Foo';
public static function test ()
{
return static::$name;
}
}
class Bar
{
protected static $name = 'Bar'; >}
echo Bar::test(); // 'Bar' を出力します
静的キーワードについて注意すべき点が 1 つあり、これは次の場合と同じように機能します。非静的 コンテキストによって動作が異なります。これは、通常の継承ルールが静的呼び出しには適用されないことを意味します。 static キーワードは、関数が定義されているクラスではなく、現在のクラスでのみ呼び出しを解決しようとします。これは注目に値します。
静的メソッドとメンバーの機能強化について理解したところで、PHP V5 で追加された、非常に便利な部分を形成する新しいクラスである標準 PHP ライブラリを見てみましょう。
----------------------------------------------------- ---
トップに戻る
標準 PHP ライブラリ
標準 PHP ライブラリ (SPL) は、標準的な問題を解決することを目的として、PHP V5 で新たに追加されたインターフェイスとクラスのコレクションです。これらの問題には、反復可能なオブジェクトの実装、オブジェクトを配列のように動作させる、またはリンク リストの実装が含まれます。これらのクラスとメソッドの利点は、ネイティブ PHP であることです。つまり、PHP 自体での実装が高速になることを意味します。多くの場合、これらのクラスとメソッドを使用すると、Iterator インターフェイスで foreach 構造体を使用してオブジェクトを反復処理できるのと同様に、内部 PHP 関数がこれらのオブジェクトを直接操作できるようになります。
PHP V5.3 では、SPL にさらに多くのクラスが追加されています。前に説明したクラスの 1 つは、SPL クラス SplDoublyLinkedList に実装された二重リンク リストです。これは、他の 2 つの新しい SPL クラス、SplStack (スタックを実装) と SplQueue (キューを実装) によって使用されます。
SplStack クラスを使用してスタックを実装する方法を見てみましょう。
リスト 9. SplStack の使用
$stack = new SplStack();
// いくつかの新しい項目をスタックにプッシュします
$stack- >push('a');
$stack->push('b');
// 数を確認アイテムはスタック上にあります
echo count($stack); // 3 を返します
// スタック内のアイテムを反復処理します
foreach ( $stack as $item )
echo " [$item],";
// 上記の出力: [c],[b],[a]
// スタックから項目をポップします
echo $stack-> Pop(); // 'c' を返します
// スタック上にあるアイテムの数を確認します
echo count($stack) // 2
を返します
SqlQueue も同様のアプローチをとりますが、キューのように動作します (スタックのようにではなく、先入れ先出し、最後の項目がプッシュされ、最初の項目がポップされる)。さらに、ヒープ実装 (SplHeap) のほか、場合によっては特定のキューおよびヒープ実装 (SplMinHeap、SplMaxHeap、および SplPriorityQueue) もあります。
もう 1 つの便利な追加機能は SplFixedArray クラスです。これは名前が示すように、固定サイズの配列の実装です。ただし、そのパフォーマンスは非常に高速です。実際、ベンチマーク テストでは、PHP の組み込み配列実装よりも 10% ~ 30% 高速です。この速度上の利点の理由は、デフォルトの PHP 配列が可変サイズであり、数値以外のインデックスを許可しないのに対し、配列は固定サイズであるためです。リスト 10 にその使用方法を示します。
リスト 10. SplFixedArray
$array = new SplFixedArray(3);
$array[0] = 'dog'; 'cat';
$array[2] = 'bird';
$a->setSize(4); // その場でサイズを増加します
$array[3] = 'mouse' ;
foreach ( $array as $value )
echo "[$value],";
出力:
[犬],[猫],[鳥],[マウス]
さらに、FilesystemIterator と GlobIterator という新しい反復子クラスが追加されました。これらは PHP の他のイテレータ クラスと同じように機能しますが、対象とする状況は異なります。
SPL に対するもう 1 つの変更点は、PHP V5.3 で通常 SPL が有効になったことです。以前の PHP V5 バージョンでは、コンパイル時に SPL を無効にすることができましたが、PHP V5.3 では SPL を無効にできません。
SPL?? の新しい追加機能には、二重リンク リスト、スタック、ヒープ、キューなどのデータ構造の実装に加えて、いくつかの便利で使いやすい機能が追加されています。これらのクラスを使用してユーザー空間実装を置き換えることができ、速度が向上し、さまざまな PHP 関数と構造の統合が向上します。
SPL の新しい機能をいくつか見てきました。次に、循環ガベージ コレクションによって PHP V5.3 の OOP がどのようにパフォーマンスとメモリ使用量を大幅に改善するかを見てみましょう。
----------------------------------------------------- ---
トップに戻る
循環ガベージ コレクション
ガベージ コレクションは、PHP 開発者が遭遇するパフォーマンスの問題です。 PHP には、メモリ スコープ内にないオブジェクトを実際にガベージ コレクションする非常に単純なガベージ コレクタがあります。ガベージ コレクションの内部的な動作では参照カウンターを使用するため、カウンターが 0 に達すると (オブジェクトへの参照が利用できないことを意味し)、オブジェクトはガベージ コレクションされてメモリから削除されます。
これはうまく機能しますが、親子関係を使用してあるオブジェクトが別のオブジェクトを参照する場合、問題が発生する可能性があります。この場合、これらのオブジェクトの参照カウンタは収集されないため、これらのオブジェクトによって使用されるメモリは参照されないままとなり、リクエストが完了するまで割り当てることができません。この問題の例を見てみましょう。
リスト 11. PHP V5.2 以前のバージョンでは、親子クラス関係を適切にガベージ コレクションできません
class Parent
{
public function __construct()
{
$this->child = new Child($this);
}
}
class Child
{
public function __construct(
Parent $parent
)
{
parent = $parent;
}
}
この場合、Parent クラスのインスタンスが存在するたびにが作成され、その後そのインスタンスがメモリ不足になると、メモリは解放されないため、スクリプトのメモリ使用量は増加し続けます。この問題を解決するためのユーザー空間ソリューションがいくつかあります。たとえば、親クラスのデストラクターを作成すると、子オブジェクトが直接解放されます。このデストラクターは、親クラスを参照解除する前に呼び出す必要があります。しかし、これを行うとコードが非常に複雑になります。
PHP V5.3 では、ガベージ コレクターがこれらの循環参照を検出し、循環参照が占有しているメモリを解放できるため、スクリプトの実行中に PHP のメモリ使用量がスムーズに維持されます。親クラスへの各参照が削除されると、親クラス内の子クラス参照もガベージ コレクションされます。
----------------------------------------------------- ---
トップに戻る
結論
PHP には、オブジェクト指向プログラミングをサポートしてきた長い歴史があります。 PHP V4 でのサポートは比較的弱かったですが、PHP V5 では大幅に改善されており、後続のバージョンで調整される予定です。現在、PHP V5.3 では、新しい __callStatic() マジック メソッド、動的静的呼び出し、遅延静的バインディング、静的メソッド、メンバー サポートなどの構文の強化を含む、いくつかの興味深い改善が提供されています。二重リンク リスト、スタック、ヒープ、キューの実装などの新しいコンテンツが SPL に追加され、いくつかの一般的なデータ構造にアクセスし、それらを簡単に使用できるようになります。最後に、待望のループ ガベージ コレクターは、これらのループ インスタンスのメモリを適切に解放し、自己参照クラスのメモリとパフォーマンスの問題を解決する、改良されたガベージ コレクターです。これらすべての機能により、PHP V5.3 はさらに強力なオブジェクト指向プログラミング言語になります。