Schlagwort-Archiv: PHP

Piwik-Bug bei Output-Compression

Nach dem Update von Piwik (eine OpenSource Software zum Erstellen von Besucherstatistiken auf Websites) auf die aktuelle Version 1.1.1 stellte ich fest, dass das Design vollständig zerschossen war und auch die JS-Dateien nicht mehr geladen werden konnten. Genauer: es wurde noch alles geladen allerdings enthielten all diese Dateien nur noch seltsam anmutende Zeichen. Ein genauerer Blick verriet, dass es sich hier um doppelt gepackte Serverausgaben handelte.

Da mein Server von sich aus alles komprimiert (per gzip) was auszugeben ist – inkl. aller von PHP generierten Inhalte, lag es nahe zu vermuten, dass Piwik selbst ebenfalls noch einmal zur Tat schreitet. In der zentralen Klasse „Piwik“ (core/Piwik.php) Zeilen 664 und 665 findet sich der Auslöser:

$zlibOutputCompression = ini_get('zlib.output_compression');
$phpOutputCompressionEnabled = !empty($zlibOutputCompression);

Hier wird offensichtlich nur eine von mehreren Möglichkeiten der Ausgabe-Komprimierung geprüft. Ergebnis: für alle anderen möglichen Einstellungen wird die interne Kompression im nachfolgenden else-Zweig aktiv und somit doppelt komprimiert. Um das zu umgehen habe ich meine eigene config mit geprüft – heraus gekommen ist nun folgendes:

$zlibOutputCompression = ini_get('zlib.output_compression');
$outputHandler = ini_get('output_handler');
$phpOutputCompressionEnabled = (!empty($zlibOutputCompression) || $outputHandler == 'ob_gzhandler');

Mit diesem Fix läuft Piwik jetzt für mich wieder problemlos.

PHP-Bug im Vergleichsoperator == ?

Heute habe ich, zusammen mit einem Kollegen, feststellen müssen dass der Vergleichsoperator scheinbar ein Typecasting bei Vergleichen zwischen (etwaigen) Integerwerten und Strings vornimmt – und zwar immer zu Integer-Werten. Das hat zur Folge, dass Vergleiche mit „0“ mit einem String „abc“ zu einer wahren Aussage führen. Bei uns hat das eine „kleine“ Sicherheitslücke gerissen, die alles andere als schön war. Das ganze lässt sich unter Debian mit der PHP-Version 5.2.6-0.1~lenny1 und folgendem Code nachvollziehen:

$a = 0;
$b = "abdbbsb";
 
if($a == $b) echo 1;
else echo 0;
# Ausgabe 1

if((string)$a == $b) echo 1;
else echo 0;
# Ausgabe 0

if($a === $b) echo 1;
else echo 0;
# Ausgabe 0

Automatische Spracherkennung in PHP

Da ich es bisher schon ein paar Projekten benötigt habe, möchte ich hier ein kleines Script zur Ermittlung der vom Benutzer (bzw. Browser) gewünschten Sprache veröffentlichen. Es geht dabei nicht darum anhand der Benutzereingaben oder der geografischen Herkunft des Benutzers die Sprache zu ermitteln, sondern nur anhand der übermittelten Browserdaten. Natürlich hat dieses Verfahren den Nachteil, dass wenn keine vernünftige Anforderung durch den Browser erfolgt, eine Standardsprache verwendet werden muss. Andererseits wird dem Benutzer auch nicht auf Grund der Herkunft seiner IP-Adresse, die nicht mit seiner tatsächlichen Herkunft übereinstimmen muss, eine x-beliebige Sprachversion der Website vorgesetzt wird. Der Code bedarf denke ich über die schon vorhandenen Kommentare hinaus keiner weiteren Erläuterung.

// set $requested_language = "" for security reasons (activated register globals or what ever else)
$requested_language = "";
// first step: check if this is allready done
if (!isset($_SESSION["language"]))
{
	// second step - check if something usefull had been committed
	if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]) && $_SERVER["HTTP_ACCEPT_LANGUAGE"] != "")
	{
		// get the iso-code for the requested language - mostly these are the first alphabethical and decimal signs)
		$requested_language = preg_split("/[\W]+/",$_SERVER["HTTP_ACCEPT_LANGUAGE"], 2);
		$requested_language[0] = strtolower($requested_language[0]);
	}
	// set the language, if the first signs are alphabetical or decimal and if there is a language-file in the given folder
	if (preg_match('/^[\w]{2,3}$/', $requested_language[0]) && is_file(BACKEND_PATH."config/languages/".$requested_language[0].".php")) 
	{
		$_SESSION["language"] = $requested_language[0];
	}
	// otherwise set the DEFAULT_LANGUAGE - you will have to set this somewhere else (e.g.: define("DEFAULT_LANGUAGE", "de"))
	else 
	{
		$_SESSION["language"] = DEFAULT_LANGUAGE;
	}
}
// include the language-file - in this case the containing array $langVar have all the language-vars
require_once (CONFIG_PATH."languages/".$_SESSION["language"].".php");

Loadbalancing für MySQL (-Slaves)

Dieser Artikel im Blog eines Kollegen hat mich dazu veranlasst mir den verwendeten Algorithmus mal ein wenig näher anzusehen und zu überarbeiten – und ihn zumindest in Sachen Speicherbedarf zu verbessern. Heraus gekommen ist folgendes:

function getSlave($cluster)
{
        // gibt es nur einen Server im Array, wird dieser zurückgeliefert
        if(count($databaseClusters[$cluster]) == 1) {
                return "master";
        }
        else {
                $sum = 0;
                foreach($databaseClusters[$cluster] as $slave) {
                        $sum += $slave["prio"];
                }
                $randomVal = rand(0, $sum);
                if($randomVal < $sum / 2) {
                        $i = 0;
                        $tmpSum = 0;
                        while($tmpSum < $randomVal) {
                                  $tmpSum += $databaseClusters[$cluster]["slave$i"]["prio"];
                                  $i++;
                        }
                }
                else {
                        $i = count($databaseClusters[$cluster]);
                        $tmpSum = $sum;
                        while($tmpSum < $randomVal) {
                                $tmpSum -= $databaseClusters[$cluster]["slave$i"]["prio"];
                                $i--;
                        }
                }
 
                return "slave$i";
        }
}

Herausgekommen ist dadurch zwar eine längere aber im Allgemeinen speicherschonendere Methode um Datenbankqueries zu verteilen. Um weitere Informationen zu erhalten lest bitte bei meinem Kollegen weiter.

PHP 5.2.5 veröffentlicht (Update)

Am 08.11. (also am Donnerstag) wurde eine neue Version von PHP veröffentlicht. Die aktuelle Version ist somit 5.2.5. Es wurden in diesem Release keine neuen Funktionen hinzugefügt sondern etwa 60 Bugs behoben, von denen ein paar SIcherheitsrelevant sind. Für die Behandlung von regulären Ausdrücken bringt PHP 5.2.5 PCRE 7.3 mit..

Hier eine Liste der sicherheitsrelevanten Änderungen (englisch – zitiert von PHP.net):

  • Fixed dl() to only accept filenames. Reported by Laurent Gaffie.
  • Fixed dl() to limit argument size to MAXPATHLEN (CVE-2007-4887). Reported by Laurent Gaffie.
  • Fixed htmlentities/htmlspecialchars not to accept partial multibyte sequences. Reported by Rasmus Lerdorf
  • Fixed possible triggering of buffer overflows inside glibc implementations of the fnmatch(), setlocale() and glob() functions. Reported by Laurent Gaffie.
  • Fixed „mail.force_extra_parameters“ php.ini directive not to be modifiable in .htaccess due to the security implications. Reported by SecurityReason.
  • Fixed bug #42869 (automatic session id insertion adds sessions id to non-local forms).
  • Fixed bug #41561 (Values set with php_admin_* in httpd.conf can be overwritten with ini_set()).

Eine vollständige Liste der Änderungen findet ihr hier: ChangeLog

12.11.07: Artikel bei golem.

PHP-Entwicklung – Neuerungen in PHP, Zend-Framework, PHP-Sicherheit

(Fortsetzung von: PHP-Entwicklung – Umstieg von 4 auf 5 sowie 5 auf 6)

Auf Golem wurde bereits am Freitag der zweite Teil des Interviews mit veröffentlicht, darin kamen unter anderem die Neuerungen in PHP6 noch einmal mehr zur Sprache.Ich werde daher heute eine „Liste“ der Neuerungen mit einer kurzen Erklärung dazu hier veröffentlichen (angelehnt an den genannten (und verlinkten) Artikel auf golem.de). Im Weiteren werde ich noch auf die Themen Sicherheit in PHP und das Zend-Framework eingehen. PHP-Entwicklung – Neuerungen in PHP, Zend-Framework, PHP-Sicherheit weiterlesen

PHP-Entwicklung – Umstieg von 4 auf 5 sowie 5 auf 6

Zend-Mitbegründer Zeev Suraski hat im Interview mit golem.de einige recht interessante Aussagen gemacht – die wichtigsten werde ich hier kurz zusammen fassen und für den Rest, verweise ich einfach auf den (1.) Teil des Artikels bei Golem. Ich werde mich bei der Zusammenfassung eher auf die Probleme mit der Einstellung von PHP4 bzw. bei der Migration von PHP5 auf 6 eingehen. Zu den Fragen über die Zusammenarbeit Zends mit Microsoft und IBM sowie die PHP Development Tools (PDT) und Zend Studio verweise ich wiederum auf den Artikel von Golem. PHP-Entwicklung – Umstieg von 4 auf 5 sowie 5 auf 6 weiterlesen