Skip to content

Commit 9499697

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 9addfcf commit 9499697

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
@@ -133,28 +133,44 @@ public function addResource($name, $resource, array $options = [])
133133
*/
134134
public function build()
135135
{
136-
$streams = '';
136+
// Open a temporary read-write stream as buffer.
137+
// If the size is less than predefined limit, things will stay in memory.
138+
// If the size is more than that, things will be stored in temp file.
139+
$buffer = fopen('php://temp', 'r+');
137140
foreach ($this->data as $data) {
138141
// Add start and headers
139-
$streams .= "--{$this->getBoundary()}\r\n".
140-
$this->getHeaders($data['headers'])."\r\n";
142+
fwrite($buffer, "--{$this->getBoundary()}\r\n".
143+
$this->getHeaders($data['headers'])."\r\n");
141144

142-
// Convert the stream to string
143-
/* @var $contentStream StreamInterface */
145+
/**
146+
* @var \Psr\Http\Message\StreamInterface
147+
*/
144148
$contentStream = $data['contents'];
149+
150+
// Read stream into buffer
145151
if ($contentStream->isSeekable()) {
146-
$streams .= $contentStream->__toString();
152+
$contentStream->rewind(); // rewind to beginning.
153+
}
154+
if ($contentStream->isReadable()) {
155+
while (!$contentStream->eof()) {
156+
// read 8KB chunk into buffer until reached EOF.
157+
fwrite($buffer, $contentStream->read(8192));
158+
}
147159
} else {
148-
$streams .= $contentStream->getContents();
160+
// Try to getContents for non-readable stream.
161+
// Less controllable chunk size (thus memory usage).
162+
fwrite($buffer, $contentStream->getContents());
149163
}
150-
151-
$streams .= "\r\n";
164+
fwrite($buffer, "\r\n");
152165
}
153166

154167
// Append end
155-
$streams .= "--{$this->getBoundary()}--\r\n";
168+
fwrite($buffer, "--{$this->getBoundary()}--\r\n");
169+
170+
// Rewind to starting position for reading.
171+
fseek($buffer, 0);
156172

157-
return $this->createStream($streams);
173+
return $this->createStream($buffer);
158174
}
159175

160176
/**

0 commit comments

Comments
 (0)