ストリームは、PHP が提供する強力なツールであり、それをうまく活用すると、PHP の生産性が大幅に向上します。 Streams のパワーを活用することで、アプリケーションを次のレベルに引き上げることができます。
以下はPHPマニュアルのStreamsの説明です:
リーリー各 Streams オブジェクトにはラッパー クラスがあり、特別なプロトコルやエンコーディングの処理に関連するコードを追加できます。よく使用されるパッケージ クラスの一部は PHP に組み込まれており、カスタム パッケージ クラスを作成して登録することもできます。既存のコンテキストとフィルターを使用してラッパー クラスを変更および拡張することもできます。
ストリームは
PHP のデフォルトのパッケージング クラスは file:// です。これは、ファイル システムにアクセスするときに実際にはストリームを使用することを意味します。ファイルの内容は、readfile('/path/to/somefile.txt') または readfile('file:///path/to/somefile.txt') の 2 つの方法で読み取ることができます。これらのメソッドは同等です。 。 readfile('http://google.com/') を使用すると、PHP は動作する HTTP ストリーム ラッパー クラスを選択します。
上で述べたように、PHP は多くの組み込みラッパー クラス、プロトコル、フィルターを提供します。 以下で説明する方法に従って、このマシンでサポートされているパッケージング クラスをクエリできます:
1 2 3 4 |
<?php
print_r(stream_get_transports());
print_r(stream_get_wrappers());
print_r(stream_get_filters());
|
私のマシンでの出力は次のとおりです:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
Array
(
[0] => tcp
[1] => udp
[2] => unix
[3] => udg
[4] => ssl
[5] => sslv3
[6] => sslv2
[7] => tls
)
Array
(
[0] => https
[1] => ftps
[2] => compress.zlib
[3] => compress.bzip2
[4] => php
[5] => file
[6] => glob
[7] => data
[8] => http
[9] => ftp
[10] => zip
[11] => phar
)
Array
(
[0] => zlib.*
[1] => bzip2.*
[2] => convert.iconv.*
[3] => string.rot13
[4] => string.toupper
[5] => string.tolower
[6] => string. strip_tags
[7] => convert.*
[8] => consumed
[9] => dechunk
[10] => mcrypt.*
[11] => mdecrypt.*
)
|
たくさんの機能が提供されていますが、良さそうですか?
上記の組み込みストリームに加えて、Amazon S3、MS Excel、Google ストレージ、Dropbox、さらには Twitter 用のサードパーティ ストリームを作成することもできます。
PHP には、この言語で I/O ストリームを処理するための組み込みラッパー クラスがあります。基本的なストリームは php://stdin、php://stdout、および php://stderr です。これらの 3 つのストリームはそれぞれデフォルトの I/O リソースにマップされます。同時に、PHP は php://input も提供します。これを介して、POST リクエストの生の本文に読み取り専用でアクセスできます。 これは、特に POST リクエストにデータ ペイロードを埋め込むリモート サービスを扱う場合に、非常に便利な機能です。
次に、cURL ツールを使用して簡単なテストを実行します。
1 |
curl -d "Hello World" -d "foo=bar&name=John" <a href= "http://localhost/dev/streams/php_input.php" >http://localhost/dev/streams/php_input.php</a>
|
PHP スクリプトで print_r($_POST) を使用したテスト結果は次のとおりです:
1 2 3 4 5 |
Array
(
[foo] => bar
[name] => John
)
|
$_POST配列ではデータの最初の項目にアクセスできないことに注意してください。しかし、readfile('php://input') を使用すると、結果は異なります:
1 |
Hello World&foo=bar&name=John
|
PHP 5.1 では、一時データの読み取りと書き込み用に、php://memory と php://tempstream という 2 つのパッケージ クラスがさらに追加されています。ラッパー クラスの名前が示すように、このデータは基盤となるシステムのメモリまたは一時ファイルに保存されます。
php://filter は、ストリームにフィルター機能を追加するために使用されるメタパッケージ クラスです。フィルタは、readfile() または file_get_contents()/stream_get_contents() を使用してストリームを開くときに有効になります。以下に例を示します:
1 2 3 4 5 6 |
<?php
// Write encoded data
file_put_contents file_put_contents ( "php://filter/write=string.rot13/resource=file:///path/to/somefile.txt" , "Hello World" ); "php://filter/write=string.rot13/resource=file:///path/to/somefile. txt" , "Hello World" );</コードコード>
<code class="php comments">// Read data and encode/decode
readfile( "php://filter/read=string.toupper|string.rot13/resource=http://www.google.com" );
|
最初の例では、ディスクに保存されたデータをエンコードするためにフィルターが使用されています。2 番目の例では、リモート URL からデータを読み取るために 2 つのカスケード フィルターが使用されています。フィルターを使用すると、アプリケーションに非常に強力な機能をもたらすことができます。
コンテキストは、ストリーム関連のパラメータまたはオプションのセットであり、コンテキストを使用してラッパー クラスの動作を変更または強化します。たとえば、コンテキストを使用して HTTP ラッパーを変更することは、一般的に使用される使用シナリオです。 このようにして、cURL ツールを使用せずにいくつかの単純なネットワーク操作を完了できます。以下に例を示します:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php
$opts = array (
'http' => array (
'method' => "POST" ,
'header' => "Auth: SecretAuthTokenrn" .
"Content-type: application/x-www-form-urlencodedrn" .
"Content-length: " . strlen ( "Hello World" ),
'content' => 'Hello World'
)
);
$default = stream_context_get_default( $opts $default = stream_context_get_default( $opts );
readfile( 'http://localhost/dev/streams/php_input.php' readfile( 'http://localhost/dev/streams/php_input.php' );
|
まず、2桁の配列であるオプション配列を定義します。パラメータは$array['wrapper']['option_name']の形式でアクセスできます。 (各ラッパー クラスのコンテキスト オプションは異なることに注意してください)。次に、stream_context_get_default() を呼び出してこれらのオプションを設定します。stream_context_get_default() も結果としてデフォルトのコンテキストを返します。設定が完了したら、readfile() を呼び出すと、設定したばかりのコンテキストがコンテンツのキャプチャに使用されます。
上記の例では、コンテンツはリクエストの本文に埋め込まれているため、リモート スクリプトは php://input を使用してコンテンツを読み取ることができます。同時に、以下に示すように、apache_request_headers() を使用してリクエストのヘッダーを取得することもできます。
Array
(
[Host] => localhost
[Auth] => SecretAuthToken
[Content-type] => application/x-www-form-urlencoded
[Content-length] => 11
)
|
1 2 3 |
<?php
$alternative = stream_context_create( $other_opts );
readfile( 'http://localhost/dev/streams/php_input.php' , false, $alternative );
|
現実世界でストリームの力をどのように活用すればよいでしょうか?ストリームを使用すると、プログラムにどのような実際的な利点がもたらされるのでしょうか? 前述したように、ストリームはすべてのファイル システム関連の機能を抽象化するため、私が考える最初のアプリケーション シナリオは、仮想ファイル システムのラッパー クラスを使用して、PaaS プロバイダーが提供するサービス ( HeroKu や AppFog へのアクセスなど) にアクセスすることです。実際には実際のファイルシステムがあります。 ストリームを使用すると、わずかな変更を加えるだけでアプリケーションをクラウドに移植できます。 次の記事では、特別なファイル形式とエンコード形式で動作するカスタム ラッパー クラスを作成する方法について説明します。