Archiv der Kategorie: php

PHP WTF #5

…oder: Bei magischen Funktionen gut aufpassen.

class TestingEmpty
{
	public function __get($var)
	{
		if ($var == "test_empty")
			return "Hi there!";
	}
}

$t = new TestingEmpty();
echo $t->test_empty; //Hi there! 
var_dump(strlen($t->test_empty)); //int(9)
var_dump(empty($t->test_empty)); //bool(true)
$externalvar = $t->test_empty;
var_dump(empty($externalvar)); //bool(false)

Aha, also empty, aber mit String-Length von 9 Zeichen. Nach dem Zuweisen zu einer „wirklichen“ Variable dann auch nicht mehr empty.

Zur Abwechslung wollen wir aber nicht nur meckern, sondern noch konstruktiv zeigen, wie man diesen WTF (der vielleicht garkeiner ist?) behebt:

class TestingEmpty
{
	public function __get($var)
	{
		if ($var == "test_empty")
			return "Hi there!";
	}
	
	public function __isset($var)
	{
		echo "__isset triggered";
		
		if ($var == "test_empty")
			return true;
		
		return false;
	}
}

$t = new TestingEmpty();
echo $t->test_empty; //Hi there!
Den ganzen Post lesen
Veröffentlicht unter php, PHP-WTF, webdev | 9 Kommentare

Testen mal anders: phpt

phpt ist ein schmuckes, kleines Testframework, welches u.a. auch zur PHP Quality Assurance verwendet wird, um damit PHP-eigene Funktionen in PHP zu testen. Wir beginnen mit einem Beispiel:

--TEST--
My first cool test!
--FILE--
<?php 
class Foobar
{
	public function __construct()
	{
		for ($i = 0; $i < 6; $i++)
		{
			if ($i % 2 != 0)
				echo $i;
		}
	}
}

new Foobar();
?>
--EXPECT--
135

Und das Beste: Mit PEAR kommt der Spaß gleich mit:

Das ists aber lang noch nicht gewesen. Man führe sich folgenden Test zu Gemüte:

--TEST--
Second example: errortesting
--FILE--
<?php 
$foo = array(1, 3) * array(2, 6);
?>
Den ganzen Post lesen
Veröffentlicht unter php, Software Engineering, webdev | 3 Kommentare

Systemaufrufe, Linux, Windows, Rückgabewerte und der Errorstream

Heute folgendes Problem gehabt: Es soll ein Systemaufruf an openssl ts zur Signierung von Timestamps (siehe hier) erfolgen. Das an sich ist ja erst mal noch kein Problem. Allerdings soll die geschriebene Klasse gleichermaßen unter Linux und Windows mit möglichst aussagekräftigen Fehlermeldungen zum Einsatz kommen. Jetzt ist die pikante Sache daran, dass der ts-Parameter von openssl erst ab Version 0.99 mit dabei ist, die standardmäßig unter Debian Lenny nicht mit installiert ist. Jetzt erzeugt netterweise ein Aufruf von openssl ts einen Returnwert von 0 (= alles okay), obwohl openssl den ts-Befehl in der installierten Version garnicht kennt – wir haben also keine Möglichkeit über eine Prüfung des Returnwertes alleine über Erfolg oder Misserfolg der Funktion zu entscheiden:

Als Waffe der Wahl haben wir uns nun also für exec entschieden, da shell_exec keinen Returnwert zurückliefert und system / passthru den Programmoutput einfach rausfeueren und nicht returnen.… Den ganzen Post lesen

Veröffentlicht unter php, Quicktips, webdev, Linux | 1 Kommentar

Needle/Haystack Übersicht

Ich schreibe bald eine Klausur (so richtig auf Papier). Und da sind keine Handbücher oder Funktionsreferenzen erlaubt. Das befinde ich jetzt erstmal für großen Schwachsinn, weil es total an der Realität vorbeigeht. So. Nun habe ich mal eine kleine Übersicht erstellt, wie die Needle/Haystack-Reihenfolge bei den meistgenutzten Funktionen ist. Durch die Hilfe der IDE ist man ja nicht gezwungen, sich das merken zu müssen. Naja, beim stöbern im PHP Handbuch ist mir nun aufgefallen, dass mein Gefühl der total willkürlichen Reihenfolge gar nicht zutreffend war ;-). Wenn man sich mal ein paar PHP-Basher anhört, ist das ja auch das erste Argument.… Den ganzen Post lesen

Veröffentlicht unter php, Quicktips, webdev | 8 Kommentare

PHP WTF #4

…oder warum man überall wo möglich 3 Gleichheitszeichen verwenden sollte ;).

<?php
$var1 = 0;
$var2 = 'foobar';

var_dump($var1 == false); //true
var_dump($var1 == $var2); //true
var_dump($var2 == true); //true

Womit dann schlussendlich true == false gilt. qed… Den ganzen Post lesen

Veröffentlicht unter php, PHP-WTF, webdev | 7 Kommentare

Datenbank-Transaktionen von akademischer Seite: Behind the Scenes

Disclaimer

An diejenigen mit ordentlichen Vorkenntnissen auf dem Gebiet der Transaktionen: Bitte nicht Abschrecken lassen. Es geht nach der kurzgehaltenen Einführung noch ordentlich in die Tiefe.

Was sind Transaktionen

Nach Definition ist eine Transaktion eine logische Arbeitseinheit, die entweder ganz oder garnicht durchgeführt wird. Bei einem Fehler wird die Datenbank also in den Zustand vor Ausführung der Transaktion versetzt, als ob nie etwas geschehen wäre.

Beispiel: Wo könnte man Transaktionen mehr benötigen als auf einem Gebiet, auf dem Fehler richtig weh tun? Die Bankenwelt! Man stelle sich folgendes ultrasimples Datenmodell vor:

CREATE TABLE  `konto` (
`kontonr` INT NOT NULL PRIMARY KEY ,
`betrag` INT NOT NULL DEFAULT  '0',
`kundenid` INT NOT NULL
) ENGINE = INNODB;

CREATE TABLE  `ueberweisung` (
`ueberweisungsid` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`from_kontonr` INT NOT NULL ,
`to_kontonr` INT NOT NULL ,
`betrag` INT NOT NULL
) ENGINE = INNODB;

Man beachte InnoDB als Engine, da MyISAM keine Transaktionen unterstützt.… Den ganzen Post lesen

Veröffentlicht unter php, Datenbanken, Security, webdev | 9 Kommentare

PHP WTF #3

Und ein neuer WTF-Teil (Teil 1, Teil 2)!

var_dump(1/3 + 4/3 == 5/3);

Ergebnis? false natürlich! Wie auch sonst, wär ja anderenfalls kein WTF. Genaugenommen hat das „Phänomen“ nichts mit PHP zu tun sondern mit Floating Point-Berechnungen und deren Präzision. Trotz allem hat mich der Spaß gerade eine Viertelstunde Debugging-Zeit gekostet, und zwar in C++. Deswegen mal kurz in PHP getestet – mit gleichem Ergebnis.

Und noch einer:

var_dump(19.99 + 19.99 == 49.98); //bool(false)

Richtigstellung: Schande über mein Haupt und danke an Enrico (siehe Kommentar). Grober Rechenfehler meinerseits. Das Ergebnis lautet natürlich nicht 49.98, sondern 39.98, was dann auch zu einem bool(true) führt.… Den ganzen Post lesen

Veröffentlicht unter php, PHP-WTF, Quicktips, webdev | 3 Kommentare

fieser Bug in PHP 5.3 [Update]

Man stelle sich folgenden Quellcode in einem Onlinebanking-Formular vor:

<?php
if (!empty($_POST['ueberweisungsbetrag']) && filter_var($_POST['ueberweisungsbetrag'], FILTER_VALIDATE_FLOAT)!==false)
{
    $ueberweisungsbetrag = $_POST['ueberweisungsbetrag'];
}
else
{
    $ueberweisungsbetrag = 0;
}
?>
<input type="text" name="ueberweisungsbetrag" value="<?php echo $ueberweisungsbetrag; ?>" />

Sieht ja eigentlich erstmal ganz vernünftig aus, oder? Validierung des einigegebenen $_POST-Betrags, um dem Benutzer bei einem Fehler das erneute eintippen zu ersparen. Wenn man nun allerdings die verdammt kleine Gleitkommazahl 2.2250738585072011e-308 als Betrag eintippt, hat das den gleichen Effekt wie

while (true) {}

Nämlich: Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/test.php on line 3. Diese ominöse Zahl führt also PHP-intern zu einem verrecken des Scripts.… Den ganzen Post lesen

Veröffentlicht unter php, Security, webdev | 3 Kommentare

Best-of-the-Web 4

Und hier die nächste Runde an interessanten Links.

Den ganzen Post lesen
Veröffentlicht unter php, Javascript, Best of the Web, webdev | 4 Kommentare

Überdeckungsorientierte Testverfahren

Unit-Tests sind ja hinreichend bekannt. Die nachfolgend vorgestellten Testverfahren sicher jedoch weniger. Deshalb gibts heut mal einen kleinen Ausflug. Ohne viel Vorgeplänkel stelle ich verschiedene überdeckungsorientierte Testverfahren vor.

Zeilenüberdeckung

Folgender (sinnloser) Code:

function foo($bar)
{
	if ($bar && !$bar)
		return true;
		
	return false;
}

Was fällt auf? Die Funktion kann nie true returnen. Durch einen Test auf Zeilenabdeckung kann also erkannt werden, dass hier irgendwas nicht stimmt, weil die return true; – Zeile niemals erreicht wird. Allerdings (großes allerdings!), würde folgende „Umstellung“ des Codes bereits zu einer 100%igen Zeilenüberdeckung führen:

function foo($bar)
{
	if ($bar && !$bar) return true;
		
	return false;
}

Klasse, oder?… Den ganzen Post lesen

Veröffentlicht unter php, Software Engineering, webdev | 4 Kommentare