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

Google Maps: direction of a polyline

JavaScript-Schnipsel um mit Google Maps API die Himmelsrichtung einer Linie aus einem Polygon zu bestimmen, lässt sich auch noch einfach erweitern um auch noch die Nord/Süd Richtung zu bekommen („lat()“) – ich brauchte aber nur West/Ost 😉 :

var p1 = polyline.getVertex(0);
var p2 = polyline.getVertex(1);
var direction = false;
 
if (p1.lng() < p2.lng()) {
    direction = "east";
} else if (p1.lng() > p2.lng()) {
    direction = "west";
}

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;
}

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.

DNS: Wildcard Records

Eine Sache die mir beim DNS gar nicht so bewusst war: Wildcard Records. Bei Webanwendungen arbeite ich gerne mit einem Default-Hosting und lasse die Anwendung bestimmen was bei welchem Hostnamen passiert (über den HTTP1.1 Header). In letzter Konsequenz fehlte mir eigentlich nur noch, dass ich die Hostnamen nicht mehr in die DNS-Zone eintragen muss.

Logische Folgerung (Auszug auf dem Bind-Zonenfile):

*.sub.bergercity.de.     IN A    88.151.66.11

1,2 Sekunden (eine Ewigkeit)

Bei mir jetzt auch ein Artikel über Profiling. Soeben erlebt: Eine relativ kleine Webseite mit eigenem ollen CMS brauchte relativ lange (1,25 Sekunden) um eine Seite zu generieren. Zunächst die Datenbankabfragen angeschaut – nichts schlimmes gefunden. Also schnell den (proprietären) Profiler angeschmissen. Es zeigte sich folgendes Bild:

1,2 Sekunden? Arg viel. Ein Blick in die betreffende Zeile:

$string = strtr($string, $replace);

Hmm, da scheint strtr wohl nicht so performant zu sein. Noch nett ausgedrückt. Ausweichcode ausprobiert:

foreach ($replace as $key => $value) {
       $string = str_replace($key, $value, $string);
}

Dauert jetzt 12ms. Unglaublich.

Links
http://www.cznp.com/blog/3/strtr-vs-str_replace-a-battle-for-speed-and-dignity
http://www.simplemachines.org/community/index.php?topic=175031.0