note 126518 added to function.stream-set-write-buffer

From: Date: Wed, 20 Oct 2021 12:56:01 +0000
Subject: note 126518 added to function.stream-set-write-buffer
Groups: php.notes 
Request: Send a blank email to php-notes+get-217089@lists.php.net to get a copy of this message
The stream_set_write_buffer() function has been broken since PHP 4.3.0. As a workaround, I would suggest using a php_user_filter as an output buffer. By using the following class I have measured over 50% performance improvements with scripts that generate large text files by writing them one line at a time: class my_output_buffer extends php_user_filter { protected static $BUFFER_SIZE = 4096; function onCreate( ) { $this->bff = []; $this->len = 0; return true; } public function filter($in, $out, &$consumed, $closing) { $rv = PSFS_FEED_ME; /* assume no output */ /* process input */ while ($bucket = stream_bucket_make_writeable($in)) { /* bucket is too big for the buffer? */ $space = static::$BUFFER_SIZE - $this->len; if ($bucket->datalen >= $space) { /* consume data by placing it into internal buffers */ $this->bff[] = substr($bucket->data, 0, $space); $this->len += $space; $overflow = substr($bucket->data, $space); $ovfl_len = $bucket->datalen - $space; $consumed += $bucket->datalen; assert($this->len == static::$BUFFER_SIZE); /* make one big bucket */ $bucket->data = implode('', $this->bff); $bucket->datalen = static::$BUFFER_SIZE; stream_bucket_append($out, $bucket); $rv = PSFS_PASS_ON; /* we have output! */ /* handle overflow */ $this->bff = [$overflow]; $this->len = $ovfl_len; } else { /* consume data by placing it into internal buffers */ $this->bff[] = $bucket->data; $this->len += $bucket->datalen; $consumed += $bucket->datalen; } } /* stream is closing and we have data? */ if ($closing && $this->len > 0) { /* make one last bucket */ $data = implode('', $this->bff); $bucket = stream_bucket_new($this->stream, $data); stream_bucket_append($out, $bucket); $rv = PSFS_PASS_ON; /* we have output! */ /* clear internal buffer */ $this->bff = []; $this->len = 0; } return $rv; } } $fp = fopen('foobar.txt', 'w'); /* enable filtering */ stream_filter_register('output.buffer', 'my_output_buffer'); stream_filter_append($fp, 'output.buffer'); /* a lot of small writes */ for ($i = 0; $i < 10000; $i++) { fwrite($fp, 'x'); } fclose($fp); ---- Server IP: 45.112.84.4 Probable Submitter: 45.112.85.242 (proxied: 84.239.137.109) ---- Manual Page -- https://php.net/manual/en/function.stream-set-write-buffer.php Edit -- https://main.php.net/note/edit/126518 Del: integrated -- https://main.php.net/note/delete/126518/integrated Del: useless -- https://main.php.net/note/delete/126518/useless Del: bad code -- https://main.php.net/note/delete/126518/bad+code Del: spam -- https://main.php.net/note/delete/126518/spam Del: non-english -- https://main.php.net/note/delete/126518/non-english Del: in docs -- https://main.php.net/note/delete/126518/in+docs Del: other reasons-- https://main.php.net/note/delete/126518 Reject -- https://main.php.net/note/reject/126518 Search -- https://main.php.net/manage/user-notes.php

« previous php.notes (#217089) next »