Monatsarchiv für Dezember 2010

 
 

PHP-Skript im Hintergrund ausführen

Wenn gleichzeitig mit einem Seitenaufruf eine rechen- oder zeitintensive Aufgabe ausgeführt werden soll, hat das den Nachteil, dass der Benutzer im Browser so lange einen Ladebalken sieht, bis die gesamte Rechenoperation beendet ist. Auch wenn die Berechnung an das Skriptende mit vorherigem ob_flush() gesetzt wird, bleibt der Ladebalken im Browser sichtbar. Das sieht nicht nur unschön aus – auch JavaScript-Events wie onload oder domready werden verzögert gefeuert.

Idealerweise startet man rechenintensive Aufgaben nicht zusammen mit einem Webseitenaufruf, sondern per cron direkt über das PHP CLI ohne Webserver-Overhead. Cron steht aber nicht immer zur Verfügung. Außerdem macht es die Anwendung weniger portabel.

Die Tatsache, dass jeder Browser die Verbindung beendet, sobald er alle mittels HTTP-Header “content-length” angekündigten Bytes empfangen hat, lässt sich ausnutzen. Den Rest regelt PHPs Ausgabepuffer.

Beispiel:

<?php
 ignore_user_abort(true);
 ob_start();
 
 // Webseiten-Content
 echo '<html>...</html>';
 
 header('HTTP/1.1 200 OK');
 header('Content-Length: ' . ob_get_length());
 
 ob_end_flush();
 flush();
 
 // Background-Prozess ab hier
 sleep(10);
?>

Ein ignore_user_abort(true) verhindert den Scriptabbruch durch den Benutzer während der Ladezeit. Nach dem flush() kann das Skript in keinem Fall mehr abgebrochen werden (abgesehen von Runtime-Fehlern, time- oder memory_limit). Sämtlicher Output vom Background-Prozess landet im Nirvana.

Wird das obige Skript aufgerufen, erscheint nur während der Ladezeit des ge-flush-ten Buffers ein Ladebalken (“Webseiten-Content”). Der Background-Prozess (beispielhaftes Sleep(10)) findet statt, nachdem die Verbindung zum Browser bereits beendet wurde.

Die Implementierung ist je nach Browser/Webserver-Umgebung etwas hakelig und bedarf in jedem Einzelfall der genauen Überprüfung. Der Beispielcode oben hat in meinen Tests gut funktioniert.

Wider Erwarten funktioniert das auch ohne die explizite Angabe von header(‘Connection: close’). Im IE6 führt die Angabe sogar dazu, dass der Hintergrundprozess überhaupt nicht mehr funktioniert. Wenn der IE darüber hinaus immer noch Zicken macht, so hilft es vielleicht mindestens 256 Byte zu flushen. Code:

echo '<html>...</html>';
 
if (($diff = 256 - ob_get_length()) > 0) echo str_repeat(' ', $diff);
 
header('HTTP/1.1 200 OK');
header('Content-Length: ' . ob_get_length());

Ade, ‘s war schee!

Augmented reality und OCR

Augmented reality, die erweiterte Realität: Beispiele dafür gibt es mittlerweile einige – fast alle sind total sinnlos. So wohl auch das App “Word Lens“. Aber es ist einfach nett anzusehen. Im Moment gibt’s das nur fürs iPhone. In der Demo-Version, in der erkannte Wörter lediglich umgedreht statt übersetzt werden, ist es kostenlos. Übersetzungspakete (z. Zt. nur EN<->ES) kosten 3,99 Euro.

Das App funktioniert auch ohne Internetverbindung. Die live OCR-Erkennung, und die miese Maschinenübersetzung  sind für mich noch soweit nachvollziehbar. Aber das Ersetzen des Originaltextes unter Berücksichtigung der Schriftart, -farbe und -größe unter den verschiedensten Winkeln: mind = blown.

Ein Jahr neunzehn83.de

Habe ich doch glatt den ersten Geburtstag meines Blogs verpennt. Am 3. Dezember 2009 ging es hier offiziell los. Seither habe ich es auf immerhin 28 mehr oder minder sinnvolle Beiträge geschafft – diesen eingeschlossen :)

Für 2011 nehme ich mir vor, die Frequenz etwas zu erhöhen, auch wenn nach wie vor gilt: Qualität vor Quantität. Zu einem Picdump- oder Linkblog kann ich die Seite ja dann immer noch verkommen lassen.

Für EUCH silent-reader da draußen wird es so langsam höchste Zeit mal einen Kommentar zu hinterlassen. Wenn euch zu meinen sonstigen Posts einfach nichts einfällt, kann ich das gut verstehen. Ist ja stellenweise auch echt kranker Scheiß. Dieser Post hingegen läd selbst den einfachst gestrickten Menschen zum Kommentieren ein. Ich weiß übrigens, dass Ihr mindestens zwei seid, also los!