2017-09-18 2 views
0

Ich habe eine lange Aufgabe für einen schlanken Controller, ich möchte die Ausgabe zu Client früh beenden und dann die Backend-Ausarbeitung fortsetzen.Slim Framework: wie zu früh Client-Verbindung zu schließen

Gibt es eine Lösung mit Slim?

+0

Die Ausgabe ist eine letzte Stufe der Skriptausführung. –

+0

Mögliches Duplikat von [Asynchrone PHP-Aufrufe?] (Https://stackoverflow.com/questions/124462/asynchronous-php-calls) – OptimusCrime

+0

Haben Sie versucht, "PHP async method" zu googeln? – OptimusCrime

Antwort

0

Die einfachste hier Option ist es, ein Verfahren mit einem Systemaufruf zu rufen und zurück, bevor es fertig ist:

exec('/bin/php /path/to/a/script.php > /dev/null &'); 

Beachten Sie, dass dies eine Vereinfachung ist als PHP Anforderung orientiert, was bedeutet, dass ein neuer Prozess gestartet wird für jede Anfrage, und der Webserver sendet die Antwort an den Benutzer, sobald die Anfrage beendet ist. Sie können flush und andere Techniken verwenden, aber diese sind anfällig für Fehler und hängen auch von den Konfigurationen des Webservers ab.

0

Dies ist ein Verfahren für Slim-Controller mit Json Ansicht:

$app->get('/test/', function() use($app) { 
     $app->view = new Json(); 
     try{ 
      //here the output of Json view 
      $model=["myjsondata"=>[]]; 
      $app->render(200,$model); 
     }catch (\Slim\Exception\Stop $e) {} 

     //following code is copied from Slim->run() to early output 
     $app->response()->headers->replace(["Content-Length"=>$app->response()->length()]); 
     $app->response()->headers->replace(["Connection"=>"close"]); 
     list($status, $headers, $body) = $app->response->finalize(); 
     \Slim\Http\Util::serializeCookies($headers, $app->response->cookies, $app->settings); 
     if (headers_sent() === false) { 
      if (strpos(PHP_SAPI, 'cgi') === 0) { 
       header(sprintf('Status: %s', \Slim\Http\Response::getMessageForCode($status))); 
      } else { 
       header(sprintf('HTTP/%s %s', $app->config('http.version'), \Slim\Http\Response::getMessageForCode($status))); 
      } 
      foreach ($headers as $name => $value) { 
       $hValues = explode("\n", $value); 
       foreach ($hValues as $hVal) { 
        header("$name: $hVal", false); 
       } 
      } 
     } 
     if (!$app->request->isHead()) { 
      echo $body; 
     } 

     //early output to client 
     ob_end_flush(); 
     ob_flush(); 
     flush(); 
     if (session_id()) session_write_close(); 

     //my async job 
     sleep(5); 
    }); 

Ich denke, das kann leicht in einem schlanken Plugin einsetzen werden. Dies funktioniert nur mit Json-Ansicht, da dies mein Bedarf ist, aber es kann mit Twig oder anderen Slim-Ansichten verwendet werden, die mit ob * php-Funktionen ausgegeben werden, anstatt die Stop() -Ausnahme zu erfassen.