Appite download súboru bez ukladania

Čamo
Člen | 786
+
0
-

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 | 1186
+
0
-

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 | 786
+
0
-

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)

Felix
Nette Core | 1186
+
0
-

Mas pravdu, upravim to v kodu a v dokumentaci.