💧

PHPのストリームフィルタとは

2021/08/11に公開

はじめに

PHPのストリームフィルタについて、使い方は知っているけど仕組みなどが分かっていなかったので、整理してみました。

結論

  • ストリームフィルタとは
    • ストリームの読み書きをトリガに何らかの処理ができるオブジェクト
    • filterメソッド、及びphp_user_filterクラスを独自に定義して具体的な処理を書き、stream_filter_registerで「登録」する
    • ストリーム関数で「登録」したストリームフィルタが適用される
  • ストリームとは
    • ファイルアクセスのインターフェースである
    • 位置とバイト数でアクセス先を指定できる
    • ファイルのサイズが確定できないデータを読み書きするのに使うと便利

そもそもストリーム[1]とは

公式ドキュメントの説明では次のとおりです。

ストリームは、 ファイル、ネットワーク、データ圧縮などに関する、 共通した一連の関数群と利用法を持つ操作の一般化の手法です。 もっとも単純な定義では、ストリーム というのは、ストリーミング可能な動作を体現する resource オブジェクトといえます。つまり、ストリームには線的に読み出したり、 あるいは書き込んだりすることが可能で、かつ、 ストリーム上の任意の場所に fseek() できる場合もあります。

公式ドキュメントの説明は読解しきれませんでしたが、意訳と自分の理解で述べると次のとおりです。

  • ファイルアクセスのインターフェース
  • ファイル単位ではなく、ファイル内のデータの位置を指定するもの
  • 開始位置をファイルポインタで、範囲をバイト数で指定できる

ストリーム関数の例

ストリームじゃない関数(ファイルアクセス用)の例

ストリーム関数と非ストリーム関数の使い分け

個人的には、扱うデータの総量が確定しないファイルを処理するならストリーム、それ以外は非ストリームを利用する、というケースが多いです。

ストリームフィルタ[2]とは

  • ストリームから読み込まれたり、書き込まれたりするデータに対して、何らかの処理を行うもの
  • stream_filter_register()を使ってストリームフィルタを自作することができる

stream_filter_register()[3]とは

ストリームにカスタムストリームフィルタを登録するメソッド。
使い方は次の通り。

  • 次の入力を基にストリームフィルタを登録する
    • filter_name
    • class
      • php_user_filter を継承したクラスである必要がある

php_user_filterクラス[4]とは

ストリームフィルタのプロパティやメソッドを定義するクラス。
filterメソッド(php_user_filter::filter)を定義する必要がある

filterメソッド(php_user_filter::filter)[5]とは

ストリームフィルタの処理を定義するメソッド
メソッドの作り方は次の通り。

  • 次の4つの入力パラメータを指定する
    • $in
      • フィルタ対象のバケット群
      • おそらく、イメージ的には列ごとに格納されたバイナリの配列
    • $out
      • フィルタ適用後(変更後)のバケット群
    • $consumes
      • フィルタで読み込んだり変更したりしたデータの長さ
    • closing
      • ストリームが終了処理の最中である場合(最後のフィルタ処理を行っている場合?)にtrueとするもの
  • 返り値は以下のいずれか
    • PSFS_PASS_ON
      • 成功
    • PSFS_FEED_ME
      • 成功したけど返すデータがない
    • PSFS_ERR_FATAL
      • エラー

バケット群ってなに?

  • bucket brigadeのこと。bucket brigadeというのは要するにストリームが触っているバイナリ列の配列のこと(だと思います)
    • 一つのバイナリ列に対応するのがBucket
    • Bucketが複数入っているのがBucket Brigade

だと思います、と書いたのですが、理由は公式ドキュメントから説明が見つけられなかったためです。
なお、こちらにBucket brigadeについて触れられていましたので、これをヒントに考察しました。

脚注
  1. PHP: ストリーム - Manual https://www.php.net/manual/ja/book.stream.php ↩︎

  2. PHP: ストリームフィルタ - Manual https://www.php.net/manual/ja/stream.filters.php ↩︎

  3. PHP: stream_filter_register - Manual https://www.php.net/manual/ja/function.stream-filter-register.php ↩︎

  4. PHP: php_user_filter - Manual https://www.php.net/manual/ja/class.php-user-filter.php ↩︎

  5. PHP: php_user_filter::filter - Manual https://www.php.net/manual/ja/php-user-filter.filter.php ↩︎

Discussion