14.04.2010
Mailinhalte fischen mit PHP und Javascript
Ich programmiere noch für den kleinen Hausgebrauch und was da so zusammenkommt, das kann man teilweise hier zum gefälligen Gebrauch oder Nichtbeachtung wiederfinden. ES dient auch mir als Erinnerungstütze.
z.B. sollte ich nicht vergessen die Methode <form action="?" method="post"> anzugeben. Wenn ich auf $_SERVER[php_self] von wegen dem XSS-Exploit das heutzutage nicht mehr bei allen Servern geht und damit ist $_SERVER[php_self] nicht mehr generell böse … wie auch immer geht eben auch ohne.
<?php $m = isset($_POST[m]) ? intval($_POST[m]) : 1 ; ?><form action="?" method="post"><input type="text"value="<?php echo $m; ?>" name="m" id="m"style="width: 4em;"onfocus="this.value=''"onChange="this.value= isNaN(this.value)? 1 : parseInt(parseFloat(this.value))"onBlur="this.value= isNaN(this.value)? 1 : parseInt(parseFloat(this.value))"/><input type="submit" value="go" class="button" /></form>
Es wird per Javascript schon dafür gesorgt, dass in das Formularfeld nur Ganzzahlen dürfen, nur Javascript kann leicht abgeschaltet werden oder im Browser überabeitet werden, ergo wird die Eingabe selbstredend auch in PHP noch einmal überprüft und überarbeitet bzw mit dem Defaultwert ersetzt. OK im PHP war ich noch etwas Faul. Schließlich müsste ich auch dort prüfen mit PHP is_float() prüfen statt mit PHP isset() seltsamer Weise aber scheint hier das Ergebnis immer false zu sein und der Default wird gewählt.
Dass die Werte in Javascript neben parseInt (= runde auf Ganzzahl ab) zunächst noch mit parseFloat (= behandle Wert als Zahl) bearbeitet wird liegt daran, dass bei der Suche nach der Javascript-Syntax für PHP intval() und Co mir die folgenden beiden Links begegneten:
A propos XSS. Da ist mir auch das Mantra “Never trust User-Input” begegnet das ausfürlich ungefähr so lautet:
Most developers worth their paycheque, I’m sure, know the common rules of “never trust the user”, such as “escape all user-supplied data on output,” “always validate user input,” and “don’t rely on something not in your control to do so (ie. Javascript cannot be trusted).” “Don’t output unescaped input” goes without saying, in most cases. Only a fool would “echo $_GET['param'];” (and we’re all foolish sometimes, aren’t we?).
Copy&paste für diesen Beitrag von XSS-Woes
Das Snippet wird bei mir dafür genutzt eine Mail aus einem Ordner meines Mailprogramms zu fischen und auszuwerten. Ich verate nun nicht welches Programm ich verwende, nur soviel es geht problemlos mit Sypheed und Thunderbird. Wer Outlook im Einsatz hat, findet hier Hilfe zu den Pfaden: Speicherorte von Outlook-Dateien
.
$dir = "[Laufwerk]:\Dokumente und Einstellungen\[Benutzer]\Lokale Einstellungen\Anwendungsdaten\[Hersteller \ Mailprogramm]\[Mailordner]";
// Pfad zum Speicherort der Mails$files = glob(utf8_decode($dir).'*');
// Datei in UTF-8 gespeichert//$files = glob($dir.'*');
// Wenn datei in Ansi gespeichert istusort($files, create_function('$a,$b', 'return filemtime($a) - filemtime($b);'));
// Mails nach Datum sortiert$MailsCount = count($files);
// Alle Mails im Ordner zählen$c = $MailsCount-$m;
\\ Mail $m von hinten$string = file_get_contents($files[$c]);
// Inhalt der Mail mit der Index-Nummer xy fischen gehen
Zur Auswertung der Mail sind die folgenden Code-Schnipsel sehr hilfreich:
- //Singleline – Zeichenfolge bis Zeilenende
preg_match_all('/(?<=Zeichenfolge)(.){0,}/',$string,$out[$k], PREG_OFFSET_CAPTURE); - //Multiline - Zeichenfolge 1 bis Zeichenfolge 2
preg_match('/Zeichenfolge1(.*)Zeichenfolge2/msU',$string,$out); - //Leere Zeilen löschen:
$string = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string);
Meine preg_match-Meriten holte ich mir von hier: PHP-Regex Blogspot
So das war es auch schon ... das heißt, weiß jemand wie man bei einer Serie von preg_match_all über die String-Position die Arrays so zusammen mischt, dass die Werte korrekt zugeordnet werden können?
- //FILTER WERTE AUS MAIL UND SCHREIBE IN ARRAY
for($k=0;$k<=6;$k++){ $werte[$k] = preg_match_all('/(?<='.$trenner[$k].')(.){0,}/',$string,$out[$k], PREG_OFFSET_CAPTURE);array_pop($out[$k]);
/*AUSGABE IN ARRAY:
[0] Bestellung [0]=> [0] wert [1] strpos
[1] Anzahl [0]=> [0] wert [1] strpos
[2] Preis [0]=> [0] wert [1] strpos
[3] Produkt-Bezeichnung-Typ1 [0]=> [0] wert [1] strpos
[4] Produkt-ID-Typ1 [0]=> [0] wert [1] strpos
[5] Produkt-Bezeichnung-Typ2 [0]=> [0] wert [1] strpos
[6] Produkt-ID-Typ2 [0]=> [0] wert [1] strpos
[7] ...-Typ3 ...etc.
*/}
Das coole daran ist, dass die mit einer Zeile Zappzerapp die Mail ausgewertet ist. Das Dumme ist, nur über den nummerischen Wert der String-Position sind die Bestellungen den Produkttypen zuzuordnen und da hatte ich bislang einen Knoten im Hirn. Zur Klarstellung alle Bestellungen die zwischen dem strpos-Wert von Produkt Index1 und Produkt Index2 (sprich: Prod1-strpos < Bestell-strpos > Prod2-strpos) ... sieht einfach genug aus, aber in der Umsetzung ist das mir aktuell noch zu hoch. Für alle die das interessiert, hier das Ganze noch einmal mit ein paar Beispieldaten.
-
<?php
-
$date = "Date: Fri, 25 Mar 2010 04:42:52 +0000 (UTC)"; $string = <<<STRING Du hast heute auf dem Marktplatz Folgendes verkauft: Frischwarename: Äpfel (Kg) Frischware-ID: 7246899 Bestellnummer: 2437838-2525661 Anzahl: 1 Einzelprovision: 2.45 € Bestellnummer: 2437838-2525661 Anzahl: 1 Einzelprovision: 2,45 €Bestellnummer: 2437838-2525661 Anzahl: 3 Einzelprovision: 2,45 € Frischware: Orangen (Kg) Frischware-ID: 5930826 Bestellnummer: 2446464-2534439 Anzahl: 1 Einzelprovision: 2,45 € Frischwarename: Birnen (Kg) Frischware-ID: 10115488 Bestellnummer: 2441306-2529176 Anzahl: 1 Einzelprovision: 2,45 EUR Kühlware: Frischkäse (Kg) Kühlware-ID: 16739414-11401126 Bestellnummer: 2445140-2533086 Anzahl: 1 Einzelprovision: 2,45 € Kühlware: Schimmelkäse (Kg) Kühlware-ID: 15054156-10369264 Bestellnummer: 2446425-2534400 Anzahl: 1 Einzelprovision: 2,45 € Kühlware: Butter (Kg) Kühlware-ID: 16739414-11401126 Bestellnummer: 2445140-2533086 Anzahl: 1 Einzelprovision: 2,45 € Kühlware: Streichwurst (Kg) Kühlware-ID: 15054156-10369264 Bestellnummer: 2446425-2534400 Anzahl: 1 Einzelprovision: 2,45 € STRING; $trenner = array( "0" => "Bestellnummer: ", "1" => "Anzahl: ", "2" => "Einzelprovision: ", "3" => "Frischwarename: ", "4" => "Frischware-ID: ", "5" => "Kühlware: ", "6" => "Kühlware-ID: "); - //FILTER WERTE AUS MAIL UND SCHREIBE IN ARRAY
for($k=0;$k<=6;$k++){ $werte[$k] = preg_match_all('/(?<='.$trenner[$k].')(.){0,}/',$string,$out[$k], PREG_OFFSET_CAPTURE);array_pop($out[$k]);
/*AUSGABE IN ARRAY:
[0] Bestellung [0]=> [0] wert [1] strpos
[1] Anzahl [0]=> [0] wert [1] strpos
[2] Preis [0]=> [0] wert [1] strpos
[3] Produkt-Bezeichnung-Typ1 [0]=> [0] wert [1] strpos
[4] Produkt-ID-Typ1 [0]=> [0] wert [1] strpos
[5] Produkt-Bezeichnung-Typ2 [0]=> [0] wert [1] strpos
[6] Produkt-ID-Typ2 [0]=> [0] wert [1] strpos
[7] ...-Typ3 ...etc.
*/}echo "<pre>\n";var_dump($out);echo "\n</pre>"; ?>
So ich hoffe, ich konnte dem einen oder anderen nun helfen seine Mail auszuwerten und wer weiß, vieleicht kommt ja auch noch zur kleinen Kniffelaufgabe mit dem Umsortieren des Arrays bzw. einem hilfreichen Index zur Zuordnung der Bestellungen zu den Waren. BTW. Ich habe eine Lösung die mit preg_match(), strpos() und substr() den String unterteilt und den Array Abschnittsweise schreibt schon entsprechend zugeordnet.
Gesucht ist wirklich die Weiterverarbeitung des Arrays, der sich ergibt durch die For-Schleife mit preg_match_all(). Natürlich sind auch Weise Worte zur Performance willkommen, sollte hier preg_match_all() eine echte Performance-Wutz sein. Ich finde an der Lösung vor allem die Kürze und Einfachheit im Code cool.
Filed under: Programmierung
No Comments