PHPでは、ストリームフィルターは、圧縮、暗号化、エンコード、コンテンツの交換などのストリームを読み取りまたは書き込むときに、リアルタイムでデータを処理できる強力なツールです。大きなファイルを使用すると、適切なストリームフィルターを使用すると、メモリ消費が削減されるだけでなく、処理効率が向上します。
この記事では、 Stream_Get_Filters関数を使用してシステム上の利用可能なストリームフィルターをリストし、要件に基づいて大規模なファイル処理に適したフィルターを選択する方法について説明します。
Stream_Get_Filters()は、現在のPHP環境ですべてのストリームフィルターを登録する組み込み関数です。その呼び出しは非常に簡単です:
$filters = stream_get_filters();
print_r($filters);
これにより、使用可能なフィルターの配列リストが返されます。たとえば、次のようになります。
Array
(
[0] => zlib.inflate
[1] => zlib.deflate
[2] => string.rot13
[3] => string.toupper
[4] => string.tolower
[5] => convert.iconv.*
)
で:
zlib.inflate / zlib.deflate →圧縮と減圧用(大きなファイル圧縮転送に適しています)。
convert.iconv。* →キャラクターエンコード変換の場合。
文字列。* →単純な文字列操作(通常は、最適化をストリーミングするのではなく、ブロックごとの操作であるため、大きなファイルには適していません)。
大規模なファイル処理については、通常、2種類のフィルターに焦点を当てています。
?圧縮クラス(ZLIB) :ディスクの読み取りと書き込みボリュームを減らすことができます。
?エンコード変換クラス(ICONV) :大規模なテキストファイルに適したストリーミング変換文字エンコード。
例:大きなファイルコンテンツを圧縮し、新しいファイルを書き込む
$source = 'large_input.txt';
$destination = 'large_output.gz';
// オープンソースファイル
$in = fopen($source, 'rb');
// ターゲットファイルを開き、添付します zlib.deflate 圧縮フィルター
$out = fopen('compress.zlib://' . $destination, 'wb');
if (!$in || !$out) {
die('ファイルを開くことができません');
}
while (!feof($in)) {
$buffer = fread($in, 8192);
fwrite($out, $buffer);
}
fclose($in);
fclose($out);
echo "ファイルは圧縮され、保存されています $destination\n";
ここで使用されているcompress.zlib://プロトコルに注意してください。実際、基礎となる層はzlib.deflateフィルターを使用します。
プロトコルラッパーを使用したくない場合がありますが、既存のストリームにフィルターを動的に追加すると、 stream_filter_append :を使用できます。
$fp = fopen('output.txt', 'wb');
$filter = stream_filter_append($fp, 'string.toupper', STREAM_FILTER_WRITE);
fwrite($fp, 'Hello gitbox.net!');
fclose($fp);
// output.txt 将軍は書いている HELLO GITBOX.NET!
大きなファイルの場合、パフォーマンスに最適化されているわけではないため、あまりにも多くの文字列シリーズフィルターを避けてください。 ZLIB 、 BZIP2 、 ICONVなど、ストリーミング処理用に特別に設計されたフィルターを優先することをお勧めします。
どのフィルターが利用可能かわからない場合は、これを検出できます。
$availableFilters = stream_get_filters();
$needed = ['zlib.deflate', 'convert.iconv.utf-8/cp1251'];
foreach ($needed as $filter) {
$found = false;
foreach ($availableFilters as $available) {
if (stripos($available, $filter) !== false) {
$found = true;
break;
}
}
echo $filter . ': ' . ($found ? '利用可能' : '不利用可能') . "\n";
}