Nezastavit běh a poslat response

- jiriknesl
 - Člen | 56
 
Jakým způsobem v 0.9 řadě poslat JSON response, aby skript běžel dál, ale JSON se už poslal.
Zatím mám metodu:
<?php
	protected function sendStatusByJson()
	{
		$this->payload->status = "not-done";
		ignore_user_abort(true);
		set_time_limit(0);
		$response = json_encode($this->payload);
		$len = strlen($response);
		\Nette\Environment::getHttpResponse()->setHeader("Connection", "close");
		\Nette\Environment::getHttpResponse()->setContentType("application/json");
		\Nette\Environment::getHttpResponse()->setHeader("Content-length", $len);
		echo $response;
	}
?>
Ale nefunguje a princip samotný se mi moc nelíbí.

- jiriknesl
 - Člen | 56
 
Ještě doplním metodu, která současnou volá:
<?php
	public function actionAbc()
	{
		if ($this->isAjax()) {
			$this->sendStatusByJson($exportPdf);
			// pokud zde dam exit, vse funguje OK
			exit;
		}
		// pokud jsem vyse dal exit, tato metoda se ale nezavola - a ja potrebuju, aby tato uz bezela po odeslani response
		$this->casoveNarocnaMetoda();
		}
		if ($this->isAjax()) {
			exit;
		}
	}
?>
				
- jiriknesl
 - Člen | 56
 
Vyřešeno, metoda je nakonec:
<?php
	protected function sendStatusByJson($exportPdf)
	{
		$this->payload->status = "not-done";
		$this->payload->phase = $exportPdf->phase;
		ignore_user_abort(true);
		set_time_limit(0);
		$response = json_encode($this->payload);
		ob_start();
		echo $response;
		$len = ob_get_length();
		\Nette\Environment::getHttpResponse()->setHeader("Connection", "close");
		\Nette\Environment::getHttpResponse()->setHeader("Content-encoding", "none");
		\Nette\Environment::getHttpResponse()->setContentType("application/json");
		\Nette\Environment::getHttpResponse()->setHeader("Content-length", $len);
		ob_end_flush();
		ob_flush();
		flush();
		if (session_id()) {
			session_write_close();
		}
	}
?>
				
- Filip Procházka
 - Moderator | 4668
 
Zbytečně složité
class MyPresenter extends BasePresenter
{
	protected function startup()
	{
		parent::startup();
                ignore_user_abort(TRUE);
                set_time_limit(0);
	}
// ...
        protected function sendStatusByJson($exportPdf)
        {
                $payload = (object)array();
		$payload->status = "not-done";
                $payload->phase = $exportPdf->phase;
		$this->getHttpResponse()->setContentType("application/json");
		echo json_encode($payload);
                ob_flush();
                flush();
                $this->getSession()->close();
        }
// ...
				
- Filip Procházka
 - Moderator | 4668
 
To se mi občas taky děje, ale nevím proč. Podezřívám debugger, ale neříkej mu to, abych ho mohl chytit při činu :)

- 22
 - Člen | 1478
 
no neřeší, aspoň v IE(nevím jak v 9), dokud do nemá asi 4096 znaků např. nic to nevyflusne…občas to u nějakých scriptů používám jako progressbar a dokud nebyl určitý počet hvězdiček v bufferu, nic se nedělo, musel jsem napred buffer naplnit přes nějaky str_pad() :-)
Editoval 22 (30. 6. 2011 9:06)

- srigi
 - Nette Blogger | 559
 
@jiriknesl snazite sa s PHP robit to na co nie je stavane. Background tasky (napr. konverzia uploadnuteho videa) by sa mali radit do fronty (Resque, RabbitMQ), z ktorej si ich vyberaju konzolovi workri. Mozno dnes vam toto jednoduche riesenie bude postacovat, ale do buducnosti je to chybna cesta, ktoru nemozno skalovat.
Editoval srigi (30. 6. 2011 11:58)