PHPのストリームフィルタとは
はじめに
PHPのストリームフィルタについて、使い方は知っているけど仕組みなどが分かっていなかったので、整理してみました。
結論
- ストリームフィルタとは
- ストリームの読み書きをトリガに何らかの処理ができるオブジェクト
- filterメソッド、及びphp_user_filterクラスを独自に定義して具体的な処理を書き、stream_filter_registerで「登録」する
- ストリーム関数で「登録」したストリームフィルタが適用される
- ストリームとは
- ファイルアクセスのインターフェースである
- 位置とバイト数でアクセス先を指定できる
- ファイルのサイズが確定できないデータを読み書きするのに使うと便利
[1]とは
そもそもストリーム公式ドキュメントの説明では次のとおりです。
ストリームは、 ファイル、ネットワーク、データ圧縮などに関する、 共通した一連の関数群と利用法を持つ操作の一般化の手法です。 もっとも単純な定義では、ストリーム というのは、ストリーミング可能な動作を体現する resource オブジェクトといえます。つまり、ストリームには線的に読み出したり、 あるいは書き込んだりすることが可能で、かつ、 ストリーム上の任意の場所に fseek() できる場合もあります。
公式ドキュメントの説明は読解しきれませんでしたが、意訳と自分の理解で述べると次のとおりです。
- ファイルアクセスのインターフェース
- ファイル単位ではなく、ファイル内のデータの位置を指定するもの
- 開始位置をファイルポインタで、範囲をバイト数で指定できる
ストリーム関数の例
ストリームじゃない関数(ファイルアクセス用)の例
-
file_get_contents, file_put_contents
- ○○というファイルを丸っと読み込む、とか
ストリーム関数と非ストリーム関数の使い分け
個人的には、扱うデータの総量が確定しないファイルを処理するならストリーム、それ以外は非ストリームを利用する、というケースが多いです。
[2]とは
ストリームフィルタ- ストリームから読み込まれたり、書き込まれたりするデータに対して、何らかの処理を行うもの
- stream_filter_register()を使ってストリームフィルタを自作することができる
[3]とは
stream_filter_register()ストリームにカスタムストリームフィルタを登録するメソッド。
使い方は次の通り。
- 次の入力を基にストリームフィルタを登録する
- filter_name
- class
- php_user_filter を継承したクラスである必要がある
[4]とは
php_user_filterクラスストリームフィルタのプロパティやメソッドを定義するクラス。
filterメソッド(php_user_filter::filter)を定義する必要がある
[5]とは
filterメソッド(php_user_filter::filter)ストリームフィルタの処理を定義するメソッド
メソッドの作り方は次の通り。
- 次の4つの入力パラメータを指定する
- $in
- フィルタ対象のバケット群
- おそらく、イメージ的には列ごとに格納されたバイナリの配列
- $out
- フィルタ適用後(変更後)のバケット群
- $consumes
- フィルタで読み込んだり変更したりしたデータの長さ
- closing
- ストリームが終了処理の最中である場合(最後のフィルタ処理を行っている場合?)にtrueとするもの
- $in
- 返り値は以下のいずれか
- PSFS_PASS_ON
- 成功
- PSFS_FEED_ME
- 成功したけど返すデータがない
- PSFS_ERR_FATAL
- エラー
- PSFS_PASS_ON
バケット群ってなに?
- bucket brigadeのこと。bucket brigadeというのは要するにストリームが触っているバイナリ列の配列のこと(だと思います)
- 一つのバイナリ列に対応するのがBucket
- Bucketが複数入っているのがBucket Brigade
だと思います、と書いたのですが、理由は公式ドキュメントから説明が見つけられなかったためです。
なお、こちらにBucket brigadeについて触れられていましたので、これをヒントに考察しました。
- PHP: stream_bucket_prepend - Manual https://www.php.net/manual/ja/function.stream-bucket-prepend.php
- bucket brigadeについて書いてある
-
PHP: ストリーム - Manual https://www.php.net/manual/ja/book.stream.php ↩︎
-
PHP: ストリームフィルタ - Manual https://www.php.net/manual/ja/stream.filters.php ↩︎
-
PHP: stream_filter_register - Manual https://www.php.net/manual/ja/function.stream-filter-register.php ↩︎
-
PHP: php_user_filter - Manual https://www.php.net/manual/ja/class.php-user-filter.php ↩︎
-
PHP: php_user_filter::filter - Manual https://www.php.net/manual/ja/php-user-filter.filter.php ↩︎
Discussion