はじめに
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
パラメータ
| パラメータ | 型 | 説明 |
|---|---|---|
$stream | resource | 対象のストリームリソース |
$size | int | バッファサイズ(バイト数)。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_buffer は stream_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://memory、php://temp などの一部ラッパーではバッファ設定が無視される場合があります。主にファイルシステムやネットワークソケットで効果を発揮します。
バッファサイズ選択の目安
| ユースケース | 推奨バッファサイズ |
|---|---|
| リアルタイムログ・即時送信 | 0(アンバッファード) |
| 一般的なファイル書き込み | 8192(8KB、デフォルト相当) |
| 大容量ファイルの一括書き出し | 65536〜262144(64KB〜256KB) |
| ネットワーク(低遅延優先) | 0〜4096 |
| ネットワーク(高スループット優先) | 65536〜131072 |
まとめ
| 項目 | 内容 |
|---|---|
| 関数名 | 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をトータルに最適化できます。
