Nezastavit běh a poslat response

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
jiriknesl
Člen | 56
+
0
-

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

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

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

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();
        }

// ...
mcmatak
Člen | 504
+
0
-

nemáte někdo tip, proč mi ten flush nefunguje? pod nette? mám ho normálně v action, celý výsledek se stejně vypíše až na konci, když si projíždím zdroják nette, tak nikde nevidím, že by bufferoval

Filip Procházka
Moderator | 4668
+
0
-

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

není to tím, že není dosaženo min. velikost bufferu??

Filip Procházka
Moderator | 4668
+
0
-

Což ale řeší ob_flush(); a flush(); ;)

22
Člen | 1478
+
0
-

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)

paranoiq
Člen | 392
+
0
-

if (pcntl_fork()) exit; :P (míněno jako vtip. ale funguje)

srigi
Nette Blogger | 558
+
0
-

@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)