PHP und die Konsole/STDIN
Heute in der Firma durfte ich einen kleinen Ausflug auf die Konsole machen. Ziel war es, ein kleines Script zu schreiben, welches via „Standard-Eingabe“ ein serialisiertes Objekt erhält, und dann eine Email versendet mit Informationen aus diesem Objekt.
Da man das nicht allzu oft macht, hier ein paar Grundlagen:
Sowohl unter Linux als auch Windows kann man ein Programm (oder besser einen Prozess) auch direkt via Shell starten, so wie hier zB:
Hier habe ich beispielhaft die ipconfig.exe unter Windows aufgerufen, die bei jedem Windows mit dabei ist.
Nun kann man einem Programm auch noch Parameter/Argumente mitgeben:
Parameter übergibt man einfach durch ein Leerzeichen getrennt hier der eigentlichen Programmdatei.
Als fortgeschrittener Nutzer hat man vielleicht schonmal von „Pipes“ gehört. Unter Linux deutlich häufiger genutzt, aber auch in Windows möglich. Pipes sind einfach Datenströme, die von einem Programm an das nächste weitergegeben werden. Hier ein häufig genutztes Beispiel unter Linux:
„ls -al“ erzeugt eine Liste der Ordner und Dateien des aktuellen Verzeichnisses. Die Ausgabe dieses Befehls leite ich weiter an das Programm „grep“, welches mit nur die Zeilen ausgibt, die ein „e“ enthalten.
Genau dieses „Empfangen von der Eingabe“ und das „Senden an die Ausgabe“ kann PHP auch. Standardmäßig wird alles, was man via echo, print und Konsorten ausgibt, in die Standard-Ausgabe (StdOut) geschrieben.
Hier ein einfaches Beispiel, wie ich den Inhalt einer Datei an ein PHP-Script schicken kann:
Aber wie kann ich in PHP nun diese Zeichen lesen? Ganz einfach, indem man den Stream liest:
// read serialized object from stdIn $stdIn = ""; if ($fp = fopen("php://stdin", "r")) { while (!feof($fp)) { $stdIn .= fgets($fp, 4096); } fclose($fp); }
Danach habe ich die Zeichen, die dem Script via StdIn übergeben wurden, in der Variablen $stdIn verfügbar.
Der zweite Teil des Scriptes ist auch ähnlich simpel:
Wenn ich weiß, dass ich in $stdIn nun ein serialisiertes Objekt der Klasse „My_User“ habe, kann ich es einfach wieder deserialisieren:
// $stdIn is our My_User object! $myUser = unserialize($stdIn);
Die Email verschickt man dann auf bewährtem Wege, entweder mit PHP-Bordmitteln
// load email template text file $content = file_get_contents(TMPL_EMAIL); // fill the placeholder(s) $href = "http://www.domain.de/kontakt/kontakt2.php?custId=".$UID; $subject = "AR: ".$subject." ---->>(AUTOREPLY)"; $sender = $myUser->getUsername(); $to = $myUser->getEmail(); $content = str_replace("<!-- [HREF] -->", $href, $content); $content = str_replace("<!-- [SUBJECT] -->", $subject, $content); $content = str_replace("<!-- [DATE] -->", $date, $content); $content = str_replace("<!-- [ANREDE_DE] -->", $sender ? 'Sehr geehrte(r) Herr/Frau ' . $sender : 'Sehr geehrte Damen und Herren', $content); $content = str_replace("<!-- [ANREDE_FR] -->", $sender ? 'Chère Madame/ Cher Monsieur ' . $sender : 'Mes Dames et Messieurs', $content); $content = str_replace("<!-- [ANREDE_NL] -->", $sender ? 'Geachte mevrouw/ mijnheer ' . $sender : 'Geachte mevrouw/ mijnheer', $content); # send the mail $header = 'MIME-Version: 1.0' . "\r\n"; $header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; $header .= "From: noreply@domain.de"."\r\n"; ini_set("SMTP", SMTP_HOST); return mail($to, $subject, $content, $header, '-fnoreply@domain.de');
oder auch via PEAR_Mime oder Zend_Mail oder oder oder.
Weitere Informationen findet man zB hier:
http://www.php.net/manual/de/features.commandline.php
http://www.contentmanager.de/magazin/artikel_213_datenstroeme_in_php.html
http://talk.cmyweb.net/tag/phpstdin/
oder bei Dr. Google.
$stdIn = stream_get_contents($fp); funktioniert auch
cu ECMA-262 3rd
ECMA-262 3rd
26 Aug 11 at 16:44