Chyba poslání hlavičky když v output bufferu jsou již data

igi
Člen | 24
+
0
-

Zdravím, mám presenter, který má akci pro poslání vygenerovaného souboru (soubor se generuje mým programem v C++, důvod je ten, že se může volat ještě i odjinud mimo PHP), funguje to dobře, až na to, že mi Nette zahlásí:
Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or send cookies/start session earlier.
Menší problém je ten, že nevím jak ten debugger zapnout. Četl jsem dokumentaci, ale nevím jak to napasovat přímo do té Nette konfigurace. Větší problém je ten, že bych stejně nejspíše nevěděl co s tím i tak :-D
Můj kód dané akce

		public function actionSendAuthFile(): void
	{
		$id = $this->getUser()->id;
		$fileName = system("/var/makeAuthFiles/bin/makeAuthFiles $id", $fileName);
		$this->sendResponse(new FileResponse("/var/authFiles/$fileName", $fileName, 'text/plain'));
	}

Tipuji, že problém by mohl být v předkovi presenteru, kde mám

		public function startup(): void
	{
	parent::startup();

	if (!$this->getUser()->isLoggedIn()) {
		$this->redirect('Sign:in');
	}
}

ale nevím co s tím, potřebuji soubor posílat jen danému přihlášenému uživateli, takže zrušit to přihlašování nemůžu.

Děkuji předem za rady jak to vyřešit.

Marek Bartoš
Nette Blogger | 1146
+
0
-

Zavolej \Tracy\OutputDebugger::enable() kdekoli v App\Bootstrap::boot()

igi
Člen | 24
+
0
-

Díky, to sice fungovalo, akorát to dopadlo jak jsem předvídal, nevím co s tím.. vypsalo mi to toto:
…/application/src/Application/Responses/FileResponse.php:130 'Salted___<\xA5+\xAE(zkráceno, ale v tomto formátu další „byty“)
Nevíte prosím, kde by mohla být chyba? Děkuji.

m.brecher
Generous Backer | 717
+
+2
-

@igi

Překvapil mě kód který Jsi použil:

   $fileName = system("/var/makeAuthFiles/bin/makeAuthFiles $id", $fileName);

V dokumentaci PHP je tento příklad použití funkce system():

<?php
echo '<pre>';

// Outputs all the result of shellcommand "ls", and returns
// the last output line into $last_line. Stores the return value
// of the shell command in $retval.
$last_line = system('ls', $retval);

// Printing additional info
echo '
</pre>
<hr />Last line of the output: ' . $last_line . '
<hr />Return value: ' . $retval;
?>

Nemám teď čas, abych to otestoval, takže to píšu bez záruky, ale řekl bych, že system() rovnou pošle výsledek příkazu shellu na výstup – a zřejmě tam nebudou ty správné http hlavičky. Výstup si současně zachytíš do $retval, ale to není to samé jako výstup do $last_line !! Pak odesíláš pomocí Nette, ale já se domnívám, že system() už pravděpodobně výstup bez hlaviček odeslal !!

Zkus na to jít nějak takhle:

ob_start();
    system("/var/makeAuthFiles/bin/makeAuthFiles $id", $file);
ob_end_clean();

// a tady by data toho souboru měly být v proměnné $file - tyhle data poslat s příslušnými hlavičkami http !!

Ale napsal jsem to z hlavy, nezkoušel jsem to!

Editoval m.brecher (19. 1. 2023 14:05)

igi
Člen | 24
+
0
-

@m.brecher
Díky, moc. Bylo to skutečně tím voláním system. Použil jsem místo toho:

	exec("/var/makeAuthFiles/bin/makeAuthFiles $id", $fileName);
	$this->sendResponse(new FileResponse("/var/authFiles/$fileName[0]", $fileName[0], 'text/plain'));

Jen pro zajímavost, ten program v C++ vygeneruje soubor a uloží ho na disk. Jeho std výstup je jen právě název vytvořeného souboru. V budoucnu(jestli na to bude čas) mám v plánu to optimalizovat, že se bude generovat jen při změně v databázi, jinak se bude posílat vždy ten stejný soubor.

m.brecher
Generous Backer | 717
+
0
-

@igi

Díky, moc. Bylo to skutečně tím voláním system.

Ono to staré PHP je záludné, třeba ta funkce system() má ukázkově nepovedené api – magicky posílá na výstup návratovou hodnotu příkazové řádky, paralelně to samé předává do druhého PARAMETRU a vrací návratovou hodnotu, což NENÍ výstup toho cmd, jak by se očekávalo, ale jenom PRVNÍ ŘÁDEK – ha ha ha.

Jenom ostřílený php borec tohle použije správně :).

Editoval m.brecher (19. 1. 2023 17:00)