Appite download súboru bez ukladania
- Čamo
- Člen | 798
Ahoj, potreboval by som vygenerovať csv súbor a následne ho poslať na stiahnutie ako odpoveď. Neviem ale ako b to malo správne vyzerať. Mám takýto kód ktorý by mal byť vhodný na odosielanie súborov v php. Ale neviem ako to napasovať na ten Appite response objekt.
$f = fopen('php://output', 'w');
foreach ($data as $line) fputcsv($f, $line, ';');
header("Content-Disposition: attachment; filename='export-$month.csv';");
header('Content-Type: text/csv');
fclose($f);
EDIT
Skúšal som to urobiť takto:
mkdir($dirName, 0777);
$f = fopen("$dirName/$fileName", 'x+');
foreach ($data as $line) fputcsv($f, $line, ';');
return $response->writeBody($f)
->withHeader("Content-Disposition: attachment", "filename='export-$month.csv';")
->withHeader('Content-Type', 'text/csv')
->withStatus(200);
Ale toto mi vyhodí error: Unable to write to stream z metody writeBody($f);
EDIT 2
V dokumentácii som našiel niečo takéto https://github.com/guzzle/psr7
$stream = stream_for($f);
$response = Psr7ResponseFactory::fromGlobal();
$response = FileResponseAdjuster::adjust($response, $stream, $fileName, 'application/octet-stream');
return $response->writeBody($stream)
->withHeader("Content-Disposition: attachment", "filename='export-$month.csv';")
->withHeader('Content-Type', 'application/octet-stream')
->withStatus(200);
Ale to mi vyhodí chybu: Argument 1 passed to Apitte\Core\Adjuster\FileResponseAdjuster::adjust() must be an instance of Apitte\Core\Http\ApiResponse, instance of Contributte\Psr7\Psr7Response given
Editoval Čamo (10. 11. 2021 12:24)
- Felix
- Nette Core | 1197
Kdyz se podivas na ten FileResponseAdjuster
tak je to simple
trida, ktera jenom resi odesilani souboru.
class FileResponseAdjuster
{
public static function adjust(
ApiResponse $response,
StreamInterface $stream,
string $filename,
string $contentType = 'application/octet-stream',
bool $forceDownload = true
): ApiResponse
{
return $response
->withHeader('Content-Type', $contentType)
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader(
'Content-Disposition',
($forceDownload ? 'attachment' : 'inline')
. '; filename="' . $filename . '"'
. '; filename*=utf-8\'\'' . rawurlencode($filename)
)
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'public')
->withHeader('Content-Length', (string) $stream->getSize())
->withBody($stream);
}
}
Klidne si ten kod vezmi a uprav dle tvych potreb. Upravit typy urcite zmaknes a zbytek vypada, ze funguje dobre.
- Čamo
- Člen | 798
Díky už som to medzitým spojazdnil. Už ostáva len otázka prečo je potom v dokumentácii to
$response = Psr7ResponseFactory::fromGlobal();
Lebo viete človek keď chce použiť nejaký balík, tak ide podľa dokumentácie a dokumentácie je na to aby nemusel čítať kód ktorý je za tým.
Editoval Čamo (14. 11. 2021 16:46)