[PHP]stream_set_write_bufferで書き込みバッファを制御する|リアルタイム出力と高スループットを使い分ける実践ガイド

PHP

はじめに

PHPでファイルやネットワークストリームにデータを書き込む際、書いたデータがすぐに相手に届いているとは限りません。PHPは内部的に 書き込みバッファ を持っており、ある程度データが溜まってからまとめてOSに渡します。これは効率的ですが、「すぐに届けたい」場面では逆効果になります。

stream_set_write_buffer を使うと、この書き込みバッファのサイズをアプリケーション側から制御できます。0 を指定してバッファリングを無効にすれば即時書き込み、大きな値を設定すれば高スループットを実現できます。

この記事では、バッファの仕組みから実践的なチューニング方法まで、クラスを用いた具体例とともに丁寧に解説します。


stream_set_write_buffer とは

項目内容
関数名stream_set_write_buffer
PHPバージョンPHP 4.3.0以降
別名set_file_buffer(旧称、現在も使用可)
カテゴリストリーム関数
返り値int(成功時 0、失敗時 0 以外)

構文

stream_set_write_buffer(resource $stream, int $size): int

パラメータ

パラメータ説明
$streamresource対象のストリームリソース
$sizeintバッファサイズ(バイト数)。0 でバッファリング無効(アンバッファード)

返り値

意味
0成功
0 以外失敗(リクエストを処理できなかった)

stream_set_read_buffer と同じ仕様: 成功時が true ではなく 0 です。if (stream_set_write_buffer(...)) のように書くと 成功を失敗と誤判定します。必ず === 0 で比較してください。


書き込みバッファの仕組み

【バッファあり(デフォルト)】

 アプリ              PHPバッファ           OS / ディスク
  fwrite("AAA") →   [AAA          ]       (まだ書かない)
  fwrite("BBB") →   [AAABBB       ]       (まだ書かない)
  fwrite("CCC") →   [AAABBBCCC    ]       (まだ書かない)
  バッファ満杯  →   ─────────────→       [一括書き込み]
  fclose()      →   ─────────────→       [残りを書き込み]

【アンバッファード(size=0)】

 アプリ              PHPバッファ           OS / ディスク
  fwrite("AAA") →   (バッファなし)→     [即座に書き込み]
  fwrite("BBB") →   (バッファなし)→     [即座に書き込み]
  fwrite("CCC") →   (バッファなし)→     [即座に書き込み]

バッファありはシステムコールが少なくスループットが高い一方、アンバッファードはリアルタイム性が高くなります。


基本的な使い方

<?php
$stream = fopen('output.txt', 'w');

// バッファリングを無効化(即時書き込み)
$result = stream_set_write_buffer($stream, 0);

if ($result === 0) {
    echo "アンバッファードモードに設定しました" . PHP_EOL;
} else {
    echo "設定に失敗しました" . PHP_EOL;
}

fwrite($stream, "このデータは即座にディスクに書かれます\n");

fclose($stream);

実践例(クラスを使った実装)

例1:バッファサイズ別の書き込みパフォーマンス計測

さまざまなバッファサイズで大量のデータを書き込み、処理時間を比較します。

<?php

class WriteBufferBenchmark
{
    private string $tmpDir;

    public function __construct()
    {
        $this->tmpDir = sys_get_temp_dir();
    }

    /**
     * 指定バッファサイズで totalBytes 書き込み、処理時間を返す
     */
    public function measure(int $bufferSize, int $totalBytes = 1_048_576, int $writeChunk = 4096): array
    {
        $filePath = $this->tmpDir . '/wb_bench_' . getmypid() . '_' . $bufferSize . '.tmp';
        $stream   = fopen($filePath, 'w');

        $setResult = stream_set_write_buffer($stream, $bufferSize);

        $written    = 0;
        $writeCalls = 0;
        $payload    = str_repeat('X', $writeChunk);
        $startTime  = microtime(true);

        while ($written < $totalBytes) {
            $chunk  = substr($payload, 0, min($writeChunk, $totalBytes - $written));
            $bytes  = fwrite($stream, $chunk);
            if ($bytes !== false) {
                $written += $bytes;
                $writeCalls++;
            }
        }

        fclose($stream);
        $elapsed = microtime(true) - $startTime;
        unlink($filePath);

        return [
            'buffer_size'  => $bufferSize,
            'total_bytes'  => $written,
            'write_calls'  => $writeCalls,
            'elapsed_ms'   => round($elapsed * 1000, 3),
            'throughput_mbps' => round($written / 1_048_576 / $elapsed, 2),
            'set_result'   => $setResult,
        ];
    }
}

$bench       = new WriteBufferBenchmark();
$bufferSizes = [0, 512, 4096, 8192, 65536, 262144];

echo str_pad("バッファサイズ",   18)
   . str_pad("設定結果", 10)
   . str_pad("fwrite呼出",       14)
   . str_pad("処理時間",         14)
   . "スループット" . PHP_EOL;
echo str_repeat('-', 68) . PHP_EOL;

foreach ($bufferSizes as $size) {
    $r     = $bench->measure($size);
    $label = $size === 0 ? "アンバッファード" : "{$size} bytes";
    $ok    = $r['set_result'] === 0 ? "OK" : "NG";

    echo str_pad($label,            18)
       . str_pad($ok,               10)
       . str_pad("{$r['write_calls']} 回", 14)
       . str_pad("{$r['elapsed_ms']} ms",  14)
       . "{$r['throughput_mbps']} MB/s" . PHP_EOL;
}

出力例:

バッファサイズ     設定結果  fwrite呼出    処理時間      スループット
--------------------------------------------------------------------
アンバッファード   OK        256 回        12.543 ms     79.72 MB/s
512 bytes          OK        256 回        8.321 ms      120.17 MB/s
4096 bytes         OK        256 回        3.102 ms      322.38 MB/s
8192 bytes         OK        256 回        2.876 ms      347.71 MB/s
65536 bytes        OK        256 回        2.431 ms      411.35 MB/s
262144 bytes       OK        256 回        2.398 ms      417.01 MB/s

バッファを大きくするほどスループットが向上します。アンバッファードは最もシステムコールが多く低速になる傾向があります。


例2:アンバッファードモードでリアルタイムログを書き出す

ログファイルはクラッシュ時に未書き込みデータが失われないよう、アンバッファードで書くことが重要です。

<?php

class RealtimeLogger
{
    private $stream;
    private string $filePath;
    private int    $lineCount = 0;

    public function __construct(string $filePath, bool $unbuffered = true)
    {
        $this->filePath = $filePath;
        $this->stream   = fopen($filePath, 'a'); // 追記モード

        if (!$this->stream) {
            throw new RuntimeException("ログファイルを開けませんでした: {$filePath}");
        }

        if ($unbuffered) {
            $result = stream_set_write_buffer($this->stream, 0);
            if ($result !== 0) {
                throw new RuntimeException("アンバッファード設定に失敗しました");
            }
        }
    }

    public function log(string $level, string $message, array $context = []): void
    {
        $timestamp   = date('Y-m-d H:i:s');
        $contextStr  = empty($context) ? '' : ' ' . json_encode($context, JSON_UNESCAPED_UNICODE);
        $line        = "[{$timestamp}] [{$level}] {$message}{$contextStr}" . PHP_EOL;

        $written = fwrite($this->stream, $line);
        if ($written === false) {
            throw new RuntimeException("ログ書き込みに失敗しました");
        }

        $this->lineCount++;
    }

    public function info(string $message, array $context = []): void
    {
        $this->log('INFO', $message, $context);
    }

    public function error(string $message, array $context = []): void
    {
        $this->log('ERROR', $message, $context);
    }

    public function warn(string $message, array $context = []): void
    {
        $this->log('WARN', $message, $context);
    }

    public function getLineCount(): int
    {
        return $this->lineCount;
    }

    public function close(): void
    {
        if (is_resource($this->stream)) {
            fclose($this->stream);
        }
    }

    public function __destruct()
    {
        $this->close();
    }
}

// 使用例
$logFile = sys_get_temp_dir() . '/realtime_' . getmypid() . '.log';
$logger  = new RealtimeLogger($logFile, unbuffered: true);

$logger->info("アプリケーション起動");
$logger->info("データベース接続完了", ['host' => 'localhost', 'db' => 'myapp']);
$logger->warn("キャッシュミス率が高い", ['rate' => '42%']);
$logger->error("外部API呼び出し失敗", ['url' => 'https://api.example.com', 'code' => 503]);
$logger->info("処理完了", ['lines' => $logger->getLineCount()]);

$logger->close();

// 書き込まれた内容を確認
echo file_get_contents($logFile);
unlink($logFile);

出力例:

[2026-05-25 12:00:01] [INFO] アプリケーション起動
[2026-05-25 12:00:01] [INFO] データベース接続完了 {"host":"localhost","db":"myapp"}
[2026-05-25 12:00:01] [WARN] キャッシュミス率が高い {"rate":"42%"}
[2026-05-25 12:00:01] [ERROR] 外部API呼び出し失敗 {"url":"https:\/\/api.example.com","code":503}
[2026-05-25 12:00:01] [INFO] 処理完了 {"lines":5}

例3:バッファサイズを切り替えて大容量CSVを高速書き出す

大量データの一括書き出しでは大きめのバッファを設定してスループットを最大化します。

<?php

class BufferedCsvWriter
{
    private $stream;
    private int    $rowCount   = 0;
    private float  $startTime;
    private int    $bufferSize;

    public function __construct(string $filePath, int $bufferSize = 65536)
    {
        $this->bufferSize = $bufferSize;
        $this->stream     = fopen($filePath, 'w');

        if (!$this->stream) {
            throw new RuntimeException("ファイルを開けませんでした: {$filePath}");
        }

        $result = stream_set_write_buffer($this->stream, $bufferSize);
        if ($result !== 0) {
            throw new RuntimeException("バッファサイズの設定に失敗しました");
        }

        $this->startTime = microtime(true);
    }

    public function writeHeader(array $columns): void
    {
        $this->writeRow($columns);
    }

    public function writeRow(array $fields): void
    {
        $line = implode(',', array_map([$this, 'escape'], $fields)) . "\n";
        fwrite($this->stream, $line);
        $this->rowCount++;
    }

    public function writeBatch(array $rows): void
    {
        foreach ($rows as $row) {
            $this->writeRow($row);
        }
    }

    private function escape(mixed $value): string
    {
        $str = (string) $value;
        if (str_contains($str, ',') || str_contains($str, '"') || str_contains($str, "\n")) {
            return '"' . str_replace('"', '""', $str) . '"';
        }
        return $str;
    }

    public function close(): array
    {
        fclose($this->stream);
        $elapsed = microtime(true) - $this->startTime;

        return [
            'row_count'   => $this->rowCount,
            'elapsed_ms'  => round($elapsed * 1000, 2),
            'buffer_size' => $this->bufferSize,
            'rows_per_sec'=> round($this->rowCount / $elapsed),
        ];
    }
}

// 使用例:10万行のCSVを書き出す
$tmpFile = sys_get_temp_dir() . '/bulk_' . getmypid() . '.csv';
$writer  = new BufferedCsvWriter($tmpFile, bufferSize: 65536);

$writer->writeHeader(['id', 'name', 'email', 'score', 'created_at']);

$rows = array_map(
    fn($i) => [
        $i,
        "ユーザー{$i}",
        "user{$i}@example.com",
        rand(0, 100),
        date('Y-m-d', strtotime("-{$i} days")),
    ],
    range(1, 100_000)
);

$writer->writeBatch($rows);
$stats = $writer->close();

echo "書き込み行数   : {$stats['row_count']} 行" . PHP_EOL;
echo "バッファサイズ : {$stats['buffer_size']} bytes" . PHP_EOL;
echo "処理時間       : {$stats['elapsed_ms']} ms" . PHP_EOL;
echo "書き込み速度   : {$stats['rows_per_sec']} 行/秒" . PHP_EOL;
echo "ファイルサイズ : " . number_format(filesize($tmpFile)) . " bytes" . PHP_EOL;

unlink($tmpFile);

出力例:

書き込み行数   : 100001 行
バッファサイズ : 65536 bytes
処理時間       : 342.18 ms
書き込み速度   : 292,241 行/秒
ファイルサイズ : 4,688,902 bytes

例4:返り値 0 = 成功の仕様を安全にハンドリングするマネージャー

stream_set_read_buffer と同様に、返り値の判定に注意が必要です。

<?php

class WriteBufferManager
{
    private $stream;
    private string $label;
    private ?int   $appliedSize = null;

    public function __construct(resource $stream, string $label = 'stream')
    {
        $this->stream = $stream;
        $this->label  = $label;
    }

    /**
     * バッファサイズを設定する
     * 返り値 0 = 成功、0以外 = 失敗 という仕様に注意
     */
    public function setWriteBuffer(int $size): bool
    {
        if ($size < 0) {
            throw new InvalidArgumentException("バッファサイズは0以上の整数を指定してください。得た値: {$size}");
        }

        // NG パターン(よくある間違い)
        // if (!stream_set_write_buffer($this->stream, $size)) { ... }
        // → 成功(0 = falsy)を失敗と判定してしまう!

        // OK パターン:=== 0 で厳密比較
        $result = stream_set_write_buffer($this->stream, $size);

        if ($result === 0) {
            $this->appliedSize = $size;
            return true;
        }

        return false;
    }

    public function disableBuffer(): bool
    {
        return $this->setWriteBuffer(0);
    }

    public function getAppliedSize(): ?int
    {
        return $this->appliedSize;
    }

    public function describe(): string
    {
        return match(true) {
            $this->appliedSize === null => "[{$this->label}] 未設定(PHPデフォルト)",
            $this->appliedSize === 0    => "[{$this->label}] アンバッファード",
            default                     => "[{$this->label}] バッファ: {$this->appliedSize} bytes",
        };
    }

    /**
     * 設定前後の状態を比較表示する
     */
    public static function demonstrate(resource $stream): void
    {
        $mgr = new self($stream, 'demo');

        $cases = [
            [0,      "アンバッファード指定"],
            [4096,   "4KBバッファ指定"],
            [65536,  "64KBバッファ指定"],
            [-1,     "不正な値(例外テスト)"],
        ];

        echo str_pad("指定値",   12)
           . str_pad("備考",     22)
           . str_pad("結果",     10)
           . "状態" . PHP_EOL;
        echo str_repeat('-', 58) . PHP_EOL;

        foreach ($cases as [$size, $note]) {
            try {
                $ok     = $mgr->setWriteBuffer($size);
                $status = $ok ? "✓ 成功" : "✗ 失敗";
                echo str_pad($size,   12)
                   . str_pad($note,   22)
                   . str_pad($status, 10)
                   . $mgr->describe() . PHP_EOL;
            } catch (InvalidArgumentException $e) {
                echo str_pad($size,   12)
                   . str_pad($note,   22)
                   . str_pad("✗ 例外", 10)
                   . $e->getMessage() . PHP_EOL;
            }
        }
    }
}

// 使用例
$stream = fopen('php://temp', 'r+');
WriteBufferManager::demonstrate($stream);
fclose($stream);

出力例:

指定値      備考                  結果      状態
----------------------------------------------------------
0           アンバッファード指定  ✓ 成功    [demo] アンバッファード
4096        4KBバッファ指定       ✓ 成功    [demo] バッファ: 4096 bytes
65536       64KBバッファ指定      ✓ 成功    [demo] バッファ: 65536 bytes
-1          不正な値(例外テスト)✗ 例外    バッファサイズは0以上の整数を指定してください。得た値: -1

例5:ネットワークストリームへの書き込みをアンバッファードで即時送信する

TCPソケットでチャット風のメッセージ送信など、即時性が重要な場面での使い方です。

<?php

class ImmediateSocketWriter
{
    private $socket;
    private int $messageCount = 0;
    private array $sendLog    = [];

    public function __construct(string $host, int $port, int $connectTimeout = 5)
    {
        $this->socket = fsockopen($host, $port, $errno, $errstr, $connectTimeout);

        if (!$this->socket) {
            throw new RuntimeException("接続失敗 [{$errno}]: {$errstr}");
        }

        // 書き込みをアンバッファードに設定(即時送信)
        $result = stream_set_write_buffer($this->socket, 0);
        if ($result !== 0) {
            throw new RuntimeException("アンバッファード設定失敗");
        }

        stream_set_timeout($this->socket, 3);
    }

    public function send(string $message): int
    {
        $data    = $message . "\r\n";
        $written = fwrite($this->socket, $data);

        if ($written === false) {
            throw new RuntimeException("送信失敗: {$message}");
        }

        $this->messageCount++;
        $this->sendLog[] = [
            'seq'     => $this->messageCount,
            'message' => $message,
            'bytes'   => $written,
            'time'    => microtime(true),
        ];

        return $written;
    }

    public function readLine(): string
    {
        $line = fgets($this->socket, 4096);

        $meta = stream_get_meta_data($this->socket);
        if ($meta['timed_out']) {
            throw new RuntimeException("受信タイムアウト");
        }

        return $line !== false ? rtrim($line) : '';
    }

    public function getSendLog(): array
    {
        return $this->sendLog;
    }

    public function close(): void
    {
        if (is_resource($this->socket)) {
            fclose($this->socket);
        }
    }
}

// 使用例(HTTPリクエストを即時送信)
try {
    $writer = new ImmediateSocketWriter('example.com', 80);

    // 各行が即座に送信される(バッファに溜まらない)
    $writer->send("GET / HTTP/1.0");
    $writer->send("Host: example.com");
    $writer->send(""); // 空行でヘッダー終端

    $statusLine = $writer->readLine();
    echo "レスポンス: {$statusLine}" . PHP_EOL;

    // 送信ログを表示
    echo PHP_EOL . "=== 送信ログ ===" . PHP_EOL;
    foreach ($writer->getSendLog() as $entry) {
        echo "  [{$entry['seq']}] {$entry['bytes']} bytes: \"{$entry['message']}\"" . PHP_EOL;
    }

    $writer->close();
} catch (RuntimeException $e) {
    echo "エラー: " . $e->getMessage() . PHP_EOL;
}

出力例:

レスポンス: HTTP/1.0 200 OK

=== 送信ログ ===
  [1] 18 bytes: "GET / HTTP/1.0"
  [2] 20 bytes: "Host: example.com"
  [3] 2 bytes: ""

例6:読み書きバッファを両方チューニングするストリーム設定ファクトリー

ユースケースに応じたプリセットで、読み書き両バッファを一括設定します。

<?php

class StreamBufferFactory
{
    /**
     * ユースケース別プリセット
     */
    private const PRESETS = [
        'realtime' => [
            'read_buffer'  => 0,
            'write_buffer' => 0,
            'description'  => 'リアルタイム(アンバッファード)',
        ],
        'balanced' => [
            'read_buffer'  => 8192,
            'write_buffer' => 8192,
            'description'  => 'バランス(8KB)',
        ],
        'bulk' => [
            'read_buffer'  => 262144,
            'write_buffer' => 262144,
            'description'  => '大容量一括転送(256KB)',
        ],
        'log' => [
            'read_buffer'  => 8192,
            'write_buffer' => 0,
            'description'  => 'ログ書き込み(読み込み8KB、書き込みアンバッファード)',
        ],
    ];

    /**
     * プリセット名からストリームを設定して返す
     */
    public static function configure(resource $stream, string $preset): array
    {
        if (!isset(self::PRESETS[$preset])) {
            throw new InvalidArgumentException(
                "不明なプリセット: {$preset}。使用可能: " . implode(', ', array_keys(self::PRESETS))
            );
        }

        $config = self::PRESETS[$preset];

        $readResult  = stream_set_read_buffer($stream,  $config['read_buffer']);
        $writeResult = stream_set_write_buffer($stream, $config['write_buffer']);

        return [
            'preset'        => $preset,
            'description'   => $config['description'],
            'read_buffer'   => $config['read_buffer'],
            'write_buffer'  => $config['write_buffer'],
            'read_success'  => ($readResult  === 0),
            'write_success' => ($writeResult === 0),
        ];
    }

    public static function listPresets(): void
    {
        echo "=== 利用可能なプリセット ===" . PHP_EOL;
        foreach (self::PRESETS as $name => $config) {
            echo "  [{$name}]" . PHP_EOL;
            echo "    説明         : {$config['description']}" . PHP_EOL;
            echo "    read_buffer  : {$config['read_buffer']} bytes" . PHP_EOL;
            echo "    write_buffer : {$config['write_buffer']} bytes" . PHP_EOL;
        }
    }
}

// 使用例
StreamBufferFactory::listPresets();
echo PHP_EOL;

$presets = ['realtime', 'balanced', 'bulk', 'log'];

foreach ($presets as $preset) {
    $stream = fopen('php://temp', 'r+');
    $result = StreamBufferFactory::configure($stream, $preset);

    $r = $result['read_success']  ? '✓' : '✗';
    $w = $result['write_success'] ? '✓' : '✗';

    echo "[{$result['preset']}] read:{$r} write:{$w} → {$result['description']}" . PHP_EOL;

    fclose($stream);
}

出力例:

=== 利用可能なプリセット ===

[realtime]

説明 : リアルタイム(アンバッファード) read_buffer : 0 bytes write_buffer : 0 bytes

[balanced]

説明 : バランス(8KB) read_buffer : 8192 bytes write_buffer : 8192 bytes

[bulk]

説明 : 大容量一括転送(256KB) read_buffer : 262144 bytes write_buffer : 262144 bytes

[log]

説明 : ログ書き込み(読み込み8KB、書き込みアンバッファード) read_buffer : 8192 bytes write_buffer : 0 bytes [realtime] read:✓ write:✓ → リアルタイム(アンバッファード) [balanced] read:✓ write:✓ → バランス(8KB) [bulk] read:✓ write:✓ → 大容量一括転送(256KB) [log] read:✓ write:✓ → ログ書き込み(読み込み8KB、書き込みアンバッファード)


関連する関数との比較

関数役割返り値
stream_set_write_buffer書き込みバッファサイズを設定0=成功、0以外=失敗
stream_set_read_buffer読み取りバッファサイズを設定0=成功、0以外=失敗
stream_set_chunk_sizeフィルタへのチャンクサイズを設定変更前のサイズ
stream_set_blockingブロッキング/ノンブロッキング切り替えbool
stream_set_timeoutタイムアウトを設定bool
fflushバッファを強制フラッシュbool

stream_set_write_buffer(0) vs fflush

// stream_set_write_buffer(0): 以降すべての fwrite が即時書き込みになる
stream_set_write_buffer($stream, 0);
fwrite($stream, "A"); // 即座にOSへ
fwrite($stream, "B"); // 即座にOS へ

// fflush: そのタイミングのバッファだけをフラッシュ。次の fwrite はまたバッファに溜まる
fwrite($stream, "A"); // バッファに溜まる
fwrite($stream, "B"); // バッファに溜まる
fflush($stream);       // ここでまとめてフラッシュ
fwrite($stream, "C"); // またバッファに溜まる
観点stream_set_write_buffer(0)fflush
適用範囲以降のすべての書き込みその時点のバッファのみ
パフォーマンス低(毎回システムコール)中(任意のタイミングで制御)
使いどころ常に即時書き込みが必要な場面特定タイミングだけ即時に書きたい場面

よくある注意点・落とし穴

1. 返り値の判定は === 0 を使う

stream_set_read_buffer と同様、成功時は 0(falsy)を返します。

// NG:成功(0)を falsy として失敗と誤判定する
if (!stream_set_write_buffer($stream, 8192)) {
    echo "成功";  // ← 実は 0=成功 でここに入ってしまう
}

// OK
if (stream_set_write_buffer($stream, 8192) === 0) {
    echo "成功";
}

2. set_file_buffer は古い別名

set_file_bufferstream_set_write_buffer の旧称です。現在も動作しますが、新しいコードでは stream_set_write_buffer を使いましょう。

// 旧称(現在も動作するが非推奨)
set_file_buffer($stream, 0);

// 推奨
stream_set_write_buffer($stream, 0);

3. アンバッファードはパフォーマンスに注意

size=0 はリアルタイム性が高まる反面、fwrite のたびにシステムコールが発生します。高頻度の小さい書き込みが続く場面では、パフォーマンスが低下することがあります。

// 高頻度の小さい書き込み × アンバッファード → システムコールが多発
stream_set_write_buffer($stream, 0);
for ($i = 0; $i < 10_000; $i++) {
    fwrite($stream, "x"); // 毎回OSへ → 遅い
}

// 対策:ある程度まとめて書き込む
stream_set_write_buffer($stream, 0);
$buffer = str_repeat("x", 10_000);
fwrite($stream, $buffer); // 1回のシステムコール → 速い

4. すべてのストリームラッパーで効果が出るわけではない

php://memoryphp://temp などの一部ラッパーではバッファ設定が無視される場合があります。主にファイルシステムやネットワークソケットで効果を発揮します。


バッファサイズ選択の目安

ユースケース推奨バッファサイズ
リアルタイムログ・即時送信0(アンバッファード)
一般的なファイル書き込み8192(8KB、デフォルト相当)
大容量ファイルの一括書き出し65536262144(64KB〜256KB)
ネットワーク(低遅延優先)04096
ネットワーク(高スループット優先)65536131072

まとめ

項目内容
関数名stream_set_write_buffer(resource $stream, int $size): int
主な用途書き込みバッファサイズの制御
size=0アンバッファード(即時書き込み)
返り値0 = 成功、0 以外 = 失敗
旧称set_file_buffer(現在は非推奨)
注意点返り値判定は === 0、アンバッファードはパフォーマンス低下の可能性
PHP バージョンPHP 4.3.0 以上

stream_set_write_buffer は「いつデータをOSに渡すか」を制御する関数です。ログ・ソケット通信では 0(即時)、大容量書き出しでは大きなバッファ、というように ユースケースに応じた使い分け が重要です。

stream_set_read_buffer と合わせて設定し、さらに fflush との違いも意識することで、ストリームI/Oをトータルに最適化できます。

タイトルとURLをコピーしました