Skip to content

Commit 6d7694c

Browse files
committed
Use temp stream instead of string to buffer content
* Update MultipartStreamBuilder::build to buffer built content in a php://temp stream resource instead of (string) $contents. This way, the size of the stream built won't be limited by PHP runtime limit.
1 parent 121299c commit 6d7694c

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/MultipartStreamBuilder.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,28 +116,44 @@ public function addResource($name, $resource, array $options = [])
116116
*/
117117
public function build()
118118
{
119-
$streams = '';
119+
// Open a temporary read-write stream as buffer.
120+
// If the size is less than predefined limit, things will stay in memory.
121+
// If the size is more than that, things will be stored in temp file.
122+
$buffer = fopen('php://temp', 'r+');
120123
foreach ($this->data as $data) {
121124
// Add start and headers
122-
$streams .= "--{$this->getBoundary()}\r\n".
123-
$this->getHeaders($data['headers'])."\r\n";
125+
fwrite($buffer, "--{$this->getBoundary()}\r\n".
126+
$this->getHeaders($data['headers'])."\r\n");
124127

125-
// Convert the stream to string
126-
/* @var $contentStream StreamInterface */
128+
/**
129+
* @var \Psr\Http\Message\StreamInterface
130+
*/
127131
$contentStream = $data['contents'];
132+
133+
// Read stream into buffer
128134
if ($contentStream->isSeekable()) {
129-
$streams .= $contentStream->__toString();
135+
$contentStream->rewind(); // rewind to beginning.
136+
}
137+
if ($contentStream->isReadable()) {
138+
while (!$contentStream->eof()) {
139+
// read 8KB chunk into buffer until reached EOF.
140+
fwrite($buffer, $contentStream->read(8192));
141+
}
130142
} else {
131-
$streams .= $contentStream->getContents();
143+
// Try to getContents for non-readable stream.
144+
// Less controllable chunk size (thus memory usage).
145+
fwrite($buffer, $contentStream->getContents());
132146
}
133-
134-
$streams .= "\r\n";
147+
fwrite($buffer, "\r\n");
135148
}
136149

137150
// Append end
138-
$streams .= "--{$this->getBoundary()}--\r\n";
151+
fwrite($buffer, "--{$this->getBoundary()}--\r\n");
152+
153+
// Rewind to starting position for reading.
154+
fseek($buffer, 0);
139155

140-
return $this->createStream($streams);
156+
return $this->createStream($buffer);
141157
}
142158

143159
/**

0 commit comments

Comments
 (0)