Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0151376

Browse files
[HttpFoundation] Add BinaryFileResponse::createFromTempFile()
1 parent 4e16f7b commit 0151376

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

src/Symfony/Component/HttpFoundation/BinaryFileResponse.php

+18-9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class BinaryFileResponse extends Response
3131
* @var File
3232
*/
3333
protected $file;
34+
protected ?\SplTempFileObject $tempFileObject = null;
3435
protected $offset = 0;
3536
protected $maxlen = -1;
3637
protected $deleteFileAfterSend = false;
@@ -65,15 +66,18 @@ public function __construct(\SplFileInfo|string $file, int $status = 200, array
6566
*/
6667
public function setFile(\SplFileInfo|string $file, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true): static
6768
{
69+
$isTemporaryFile = $file instanceof \SplTempFileObject;
70+
$this->tempFileObject = $isTemporaryFile ? $file : null;
71+
6872
if (!$file instanceof File) {
6973
if ($file instanceof \SplFileInfo) {
70-
$file = new File($file->getPathname());
74+
$file = new File($file->getPathname(), !$isTemporaryFile);
7175
} else {
7276
$file = new File((string) $file);
7377
}
7478
}
7579

76-
if (!$file->isReadable()) {
80+
if (!$file->isReadable() && !$isTemporaryFile) {
7781
throw new FileException('File must be readable.');
7882
}
7983

@@ -83,7 +87,7 @@ public function setFile(\SplFileInfo|string $file, string $contentDisposition =
8387
$this->setAutoEtag();
8488
}
8589

86-
if ($autoLastModified) {
90+
if ($autoLastModified && !$isTemporaryFile) {
8791
$this->setAutoLastModified();
8892
}
8993

@@ -301,19 +305,25 @@ public function sendContent(): static
301305
}
302306

303307
$out = fopen('php://output', 'w');
304-
$file = fopen($this->file->getPathname(), 'r');
308+
309+
if ($this->tempFileObject) {
310+
$file = $this->tempFileObject;
311+
$file->rewind();
312+
} else {
313+
$file = new \SplFileObject($this->file->getPathname(), 'r');
314+
}
305315

306316
ignore_user_abort(true);
307317

308318
if (0 !== $this->offset) {
309-
fseek($file, $this->offset);
319+
$file->fseek($this->offset);
310320
}
311321

312322
$length = $this->maxlen;
313-
while ($length && !feof($file)) {
323+
while ($length && !$file->eof()) {
314324
$read = $length > $this->chunkSize || 0 > $length ? $this->chunkSize : $length;
315325

316-
if (false === $data = fread($file, $read)) {
326+
if (false === $data = $file->fread($read)) {
317327
break;
318328
}
319329
while ('' !== $data) {
@@ -329,9 +339,8 @@ public function sendContent(): static
329339
}
330340

331341
fclose($out);
332-
fclose($file);
333342
} finally {
334-
if ($this->deleteFileAfterSend && is_file($this->file->getPathname())) {
343+
if (null === $this->tempFileObject && $this->deleteFileAfterSend && is_file($this->file->getPathname())) {
335344
unlink($this->file->getPathname());
336345
}
337346
}

src/Symfony/Component/HttpFoundation/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Make `HeaderBag::getDate()`, `Response::getDate()`, `getExpires()` and `getLastModified()` return a `DateTimeImmutable`
88
* Support root-level `Generator` in `StreamedJsonResponse`
99
* Add `UriSigner` from the HttpKernel component
10+
* Add `BinaryFileResponse::createFromTempFile()`
1011

1112
6.3
1213
---

src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,25 @@ public static function tearDownAfterClass(): void
434434
@unlink($path);
435435
}
436436
}
437+
438+
public function testCreateFromTemporaryFile()
439+
{
440+
$file = new \SplTempFileObject();
441+
$file->fwrite('foo,bar');
442+
443+
$response = new BinaryFileResponse($file, 201, [
444+
'Content-Type' => 'text/csv',
445+
]);
446+
447+
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
448+
449+
$this->assertSame(201, $response->getStatusCode());
450+
$this->assertSame('text/csv', $response->headers->get('Content-Type'));
451+
$this->assertEquals('attachment; filename=temp', $response->headers->get('Content-Disposition'));
452+
453+
ob_start();
454+
$response->sendContent();
455+
$string = ob_get_clean();
456+
$this->assertSame('foo,bar', $string);
457+
}
437458
}

0 commit comments

Comments
 (0)