PHP SPL の忘れ去られた宝石
Rafael Dohms の上記の記事 に驚かされ、いくつか追加しながら翻訳せずにはいられませんでした。コンテンツ。
SPL、PHP 標準ライブラリ (標準 PHP ライブラリ) 、この組み込みコンポーネントとインターフェイスは PHP 5.0 から始まり、 PHP5.3は徐々に成熟してきました。 SPL は実際にはすべての PHP5 開発環境に組み込まれており、セットアップは必要ありません。
多くの PHP 開発者は基本的にこれを使用していないか、聞いたことさえないようです。その理由は、「存在」を無視してしまう雪のような文書にあります。 SPL この宝石は、海底に沈んだタイタニック号の「海の心臓」のようなものです。今、それは私たちによって手に取られ、しかるべき場所で着用されるべきであり、これがこの記事で表現された観点です。
では、SPL は何を提供するのでしょうか?
SPL は、配列の形式でオブジェクトを操作するために使用される ArrayAccess、Countable、SeekableIterator などのインターフェイスなどの PHP エンジンの拡張機能を提供します。同時に、RecursiveIterator や ArrayObjects などの他のイテレータを使用してデータを反復することもできます。
Exceptions、SplObserver、Spltorage、splautoloadregister などのいくつかの組み込みオブジェクトもあります。 splclasses、iteratorapply などのヘルパー関数は、対応する関数をオーバーロードするために使用されます。
これらのツールを組み合わせると、多機能のスイス アーミー ナイフのようなものになります。これらをうまく活用すると、PHP コードの効率が定性的に向上します。では、どうすればその力を発揮できるのでしょうか?
あなたが「教科書的なプログラマ」であれば、__autoload の使用方法を必ず知っているでしょう。対応するクラスを遅延ロードするための include/required 操作を置き換えます。
しかし、時間が経つと、まず、クラス ファイルが指定されたファイル パスに存在する必要があることがわかります。たとえば、Zend フレームワークでは、次のようにします。クラス名、メソッド名を分割するには「_」を使用する必要があります (この問題をどのように解決しますか?)。
もう 1 つの問題は、プロジェクトがますます複雑になるにつれて、__autoload 内のロジックもそれに応じて複雑になることです。最終的には、例外判定も追加し、クラスをロードするロジックをすべて書き込むことになります。
SPL を使用して __autoload の読み込みロジックを分離できることは誰もが知っています。独自の自動ロード関数を作成し、SPL が提供する関数を使用してそれをオーバーロードするだけです。
たとえば、上記の Zend フレームワークの問題では、対応するクラスが見つからない場合は、Zend ローダーの対応するメソッドをオーバーロードできます。以前に定義した関数。
<?phpclass MyLoader { public static function doAutoload($class) { // 本模块对应的 autoload 操作 }}spl_autoload_register( array('MyLoader', 'doAutoload') );?>
ご覧のとおり、spl autoload レジスタは配列の形式で複数のロード ロジックを追加することもできます。同時に、spl autoload unregister を使用して、不要になったロード ロジックを削除することもできます。この機能は常に使用されます。
反復は一般的な設計パターンの 1 つであり、データ セット内の統合走査操作によく使用されます。 SPL は、対応するデータ型に必要なイテレータをすべて提供すると言っても過言ではありません。
非常に良い例は、ディレクトリの走査です。従来のアプローチでは、scandir を使用し、「.」と「..」、および条件を満たさないその他のファイルをスキップします。たとえば、画像ファイルを抽出するためにディレクトリを移動する必要がある場合、画像ファイルが jpg で終わるか gif で終わるかを判断する必要があります。
次のコードは、SPL イテレータを使用して、指定されたディレクトリ内の画像ファイルに対する上記の再帰的検索を実行する例です。
<?phpclass RecursiveFileFilterIterator extends FilterIterator { // 满足条件的扩展名 protected $ext = array('jpg','gif'); /** * 提供 $path 并生成对应的目录迭代器 */ public function __construct($path) { parent::__construct(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path))); } /** * 检查文件扩展名是否满足条件 */ public function accept() { $item = $this->getInnerIterator(); if ($item->isFile() && in_array(pathinfo($item->getFilename(), PATHINFO_EXTENSION), $this->ext)) { return TRUE; } }}// 实例化foreach (new RecursiveFileFilterIterator('/path/to/something') as $item) { echo $item . PHP_EOL;}?>
これはそうではないと言うかもしれません。同じことを複数のコードで実行するのは時間の無駄ですか?さて、上記のコードを見ると、再利用可能でテストしやすいコードだと思いませんか? :)
SPL が提供する他のイテレータは次のとおりです。
PHP5.3 以降、さらに多くの組み込みイテレーターが追加されるので、従来のコードを書く習慣が変わるかもしれません。
SPL には、一連の組み込み配列操作ツールもあります。たとえば、SplFixedArray を使用して固定長配列をインスタンス化できます。では、なぜそれを使用するのでしょうか?高速なため、給与にも影響します :)
PHP の通常の配列には、数値や文字列などのさまざまな種類のキーが含まれており、長さは可変であることがわかっています。 PHP がハッシュを使用してキーを通じて対応する値を取得するのは、これらの「高度な機能」のためです。実際、これにより、特定の状況でパフォーマンスの問題が発生する可能性があります。
SplFixedArray は固定数値キーを使用するため、ハッシュ ストレージを使用しません。正確にはそうではありませんが、C 配列と考えることもできます。これが、SplFixedArray が通常の配列より高速である理由です (PHP5.3 のみ)。
それはどれくらい速いでしょうか? 次の一連のデータからそれを垣間見ることができます。
多くの配列操作が必要な場合は、試してみてください。信頼できると思います。
同時に、SPL はいくつかの基本的なタイプのデータ構造の実装も提供します。配列を使用してスタック (Strack) を記述するなど、従来の変数型を使用してデータ構造を記述することもできますが、その後、対応するポップとプッシュのメソッド (arraypop()、arraypush()) を使用します。ただし、常に注意する必要があります。結局のところ、それらはデータ構造を記述するために特別に設計されたものではないため、1 つの間違った操作によってスタックが破壊される可能性があります。
SPL の SplStack オブジェクトは、厳密にデータをスタック形式で記述し、対応するメソッドを提供します。同時に、そのようなコードは、配列ではなくスタック上で動作していることも理解できる必要があり、ピアが対応するコードをよりよく理解できるようになり、処理が高速化されます。
最後に、おそらく上記の淡い例は、SPL を使用する「誘惑」には十分ではありません。実践することで真の知識が得られ、SPL のさらに強力な機能を自分で探索する必要があります。宝石のようにゆっくりと彫られて初めて輝きを放ちます。