Links August 2015

A bit Elasticsearch dominated this time 😉

PHP: error_reporting setting in apache config

Schöner Denkfehler.

In der php.ini setzt man die error_reporting Stufen mittels Bitverknüpfung über Konstanten (Liste):

php_admin_value error_reporting E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

Um für einen bestimmten vhost im Apache abweichende Werte zu setzen, gibt es die Settings „php_admin_value“ und „php_admin_flag“. Kommt man jedoch (wie ich) auf die Idee es wie in der php.ini üblich einzutragen, erhält man nicht das gewünschte Ergebnis. Grund ist, dass PHP an dieser Stelle die Konstanten nicht auswerten kann.

# falsch
php_admin_value error_reporting E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
 
#richtig
php_admin_value error_reporting 22519

PHP5.3: log mail() usage

Es geschehen noch Wunder. Ein ur-alter Patch, der PHP das Loggen der „mail()“ Funktion beibringt hat es in den Core geschafft – und ich habe es nicht gemerkt ;).

Damit wird es auf Shared-Hosting Systemen endlich (ohne Klimmzüge) möglich, spammende Formulare etc. zu identifizieren…

So wird es aktiviert:

# /etc/php.ini
 
mail.add_x_header = On              # Fügt einen neuen Mailheader hinzu:
                                    # X-PHP-Originating-Script: <uid>:formmail.php
 
mail.log = /var/log/phpmail.log     # Loggt jede Benutzung der mail() Funktion

Das Log sieht dann so aus:

mail() on [/var/www/formmail.php:3]: To: otto@example.org -- Headers:

many THANKS!

PHP/bash: Konsolenausgabe positionieren

Kürzlich benötigte ich für eine PHP Konsolenanwendung die Ausgabe einer Statuszeile. Die ausgegebene Zeile sollte jedoch nicht (wie sonst üblich) jeweils in einer neuen Zeile landen, sondern immer in der selben Zeile – so dass man einen schnellen Überblick über den Scriptstatus bekommt. Wie auch immer – ich habe mich dann etwas durch die Terminal ANSI Escape Sequenzen gekämpft und das ganze mit meinem PHP Script kombiniert. Folgend die entsprechende Funktion für die Ausgabe:

function echoFixedLine($string) {
     echo "\033[K" . $string . "\033[" . strlen ($string) . "D";
}
 
echo "TEST:";
 
for ($i=0; $i<=100; $i++) {
    echoFixedLine("Number: " . $i);
    sleep(1);
}
 
// Ausgabe nach ca. 101 Sekunden:
TEST:
Number: 100

Die Funktion löscht immer zunächst die ganze Zeile, schreibt dann den gewünschten String und positioniert anschließend den Cursor wieder an den Anfang für die eventuelle nächste Zeile. Denkbar wären damit z.B. auch „grafische“ Fortschrittsanzeigen…

Hier ein paar weiter Informationen zu den Escape-Sequenzen – eine komplette Referenz haben ich leider noch nicht gefunden.

PHP: IP ranges überprüfen

Quick and dirty PHP-Script zum überprüfen ob eine IP-Adresse in einem angegebenen IP-Range ist.

 
$ranges = array(
    "10.10.10.2-4",
    "192.168.0-255.0-255",
    "10.20.0.1",
    );
 
if (inIpRange("10.10.10.3", $ranges)) {
    echo "bingo!";
}
 
function inIpRange($needle, $haystack) {
 
    if (!is_array($haystack)) {
        $haystack = array($haystack);
    }
 
    foreach ($haystack as $ip) {
 
        $d = explode('.', $ip);
        $r = explode('.', $needle);
 
        foreach ($d as $key => $num) {
 
            if (strpos($num, '-') !== false) {
                $range = explode('-', $num);
 
                if ($r[$key] < $range[0] || $r[$key] > $range[1]) {
                    continue 2;
                }
            } elseif ($num != $r[$key]) {
                continue 2;
            }
        }
 
        return true;
    }
 
    return false;
}

Plesk: FastCGI wrapper unter Ubuntu

Um eine Domainspezifische php.ini laden zu können verwende ich einen angepassten Wrapper für die FastCGI Schnittstelle. Plesk verwendet das Script /var/www/cgi-bin/cgi_wrapper/cgi_wrapper als Wrapper für PHP-Scripts.

#!/bin/bash
 
DIR=`fgrep "$UID" /etc/passwd | cut --delimiter=: -f6`
 
if [ -f "$DIR/private/php/php.ini" ]; then
        PHPRC=$DIR/private/php/php.ini
else
        PHPRC=/etc/php5/cgi/php.ini
fi
 
export PHPRC
exec /usr/bin/php-cgi

Nebenbei erwähnt: Hier findet sich der Grund warum der angepasste Wrapper für FastCGI unter Ubuntu zunächst nicht funktioniert hat.

Netbeans: Scanning for external changes

Vor einiger Zeit bin ich von PHPEd auf Netbeans PHP umgestiegen. Mir gefällt z.B. das Projekthandling, die eingebaute Versionierungsanbindung und speziell die Plattformunabhängigkeit. PHPEd ist zwar klasse unter Windows aber da ich meist unter Linux unterwegs bin und die Wine-Unterstützung für PHPEd nicht so gut ist (Geschwindigkeit) bin ich letztendlich zu Netbeans gewechselt. Dies nur am Rande.

Netbeans nervt aber ab und an mit seiner ewigen Scannerrei nach Änderungen im Code. Mitunter wechselt man den Fokus und Netbeans scannt (auch den Server) nach Änderungen („Scanning for external Changes“).

Unter folgendem Link ist ein Plugin beschrieben mit welchem man das Verhalten normalisiert: ScanOnDemand.

Debug-Modus per Cookie

Jeder Entwickler baut sich wohl seinen eigenen Debug-Modus für seine Anwendungen. Bisher habe ich bei Webanwendungen meist GET Parameter verarbeitet. Mit den prinzipbedingten Nachteilen – z.B. Tracking über mehrere Seiten. Andere Variante ist per Config-Variable den Debugmodus einzuschalten. Oder abhängig von der Source-IP. Oder wie auch immer.

Eine andere Methode habe ich mir von Google abgeschaut: Setzen von Spezialmodi per Cookie über die Adressleiste des Browsers. Google hat schon des öfteren neue Funktionen zunächst nur für einen „eingeweihten“ Nutzerkreis zugänglich gemacht. Eingeschaltet wurde die Funktion dann über ein spezielles Cookie. Gesetzt wurde dieses einfach über die Adressleiste des Browsers. So hat z.B. die folgende Eingabe in der Adressleiste auf google.com das „suggest“ Feature eingeschaltet:

javascript:document.cookie= "PREF=ID=175eb54605c0202d:U=a14f58424228a2a5:LD=en:
NR=10:CR=2:TM=1240146048:LM=1242596928:DV=AA:GM=1:IG=1:S=zW53HscJwnEL89bQ;
path=/;domain=.google.com";void(0);

Mittlerweile verwende ich auch immer öfter dieses Verfahren:

javascript:document.cookie="xyz_debug=1";window.location.reload();

Das so gesetzte Cookie mit dem Namen „xyz_debug“ kann man dann einfach mit bekannten Funktionen serverseitig auswerten (hier PHP):

if ($_COOKIE["xyz_debug"]) {
    var_dump($_POST);
}

Natürlich sollte das verwendete Cookie nicht leicht zu erraten sein. Ich wüste gerne wie viele Debugausgaben in den weiten des Internets darauf warten über versteckte Zugänge, Parameter etc. abgerufen zu werden 😉

PHP: strpos mit Integern

Wieder 2 Stunden bei der Fehlersuche verplempert…

$string = "X20";
echo (strpos("XYX20", $string) !== false) ? "JA" : "NEIN";
 
$string = 20;
echo (strpos("XYX20", $string) !== false) ? "JA" : "NEIN";

Output:

JA
NEIN

Erwartet hätte ich 2x „JA“. Leider habe ich nicht in die Doku zu strpos geschaut – hätte mir einiges an Zeit für die Fehlersuche erspart. Es ist aber immer so: Die Funktion strpos habe ich schon 1000 Mal verwendet und den Fehler definitiv nicht dort vermutet.

So geht’s:

$string = 20;
echo (strpos("XYX20", (string)$string) !== false) ? "JA" : "NEIN";

Merke: gerade die viel gelobte/gehasste vermeintlich dynamische Typumwandlung von PHP stellt einem oft ein Bein.