Meine Feature-Wünsche für PHP

So kurz vor Weihnachten schreibe ich heute mal meinen Wunschzettel. Natürlich nicht irgendeinen Wunschzettel, sondern meine größten Wünsche für kommende Features in PHP.

1.) Skalares Type Hinting
Type Hinting für Klassen und Arrays ist bereits seit PHP 5.1 problemlos möglich. Eine weitere Verbesserung wäre zusätzlich noch sklares Type Hinting einzuführen, also Integer und Float-Werte für Funktionsparameter anzugeben.

function calculate(int $x)
{
    var_dump($x);
}
 
calculate("99");
// int(99)

Da PHP aber schwache Typisierung verwendet, wäre es sinnvoll hier keinen Fehler zu werfen, sondern den String in einen Integerwert zu casten. Diskutiert wurde dieses Thema in der PHP-Community bereits ausgiebig, aber ob dieses Feature wirklich umgesetzt wird, steht noch nicht fest.

2.) Annotations
Viele Frameworks (u.a. Flow, Symfony und Doctrine) setzten bereits auf Annotations, die aber zum großen Teil noch selbständig mittels der Reflection-API geparst werden müssen. Eine allgemeingültige Lösung von PHP selbst wäre nicht nur performanter, sondern würde aus den Annotations auch ein echtes Sprachkonstrukt machen. Auch dieses Thema stand in der PHP-Community bereits zur Debatte.

3.) Foreach-else-Konstrukt
Smarty bietet bereits eine Funktion um foreach-else-Blöcke zu bauen, schöner wäre es aber, wenn PHP diese Möglichkeit von sich aus mitbringen würde.

$array = array();
 
// Aktueller Stand:
if(count($array))
{
    foreach($array as $key => $value)
    {
        echo $value.PHP_EOL;
    }
}
else
{
    echo "Keine Datensätze vorhanden.";
}
 
// Und so könnte es zukünftig aussehen:
foreach($array as $key => $value)
{
    echo $value.PHP_EOL;
}
else
{
    echo "Keine Datensätze vorhanden.";
}

Der untere Code ist wesentlich kürzer und lesbarer.
Die Community diskutiert sogar darüber das gleiche Konstrukt auch für for- und while-Schleifen einzusetzen und darüber hinaus die Abfragen noch mit elseif zu erweitern. Ich wäre allerdings schon mit der einfachen foreach-else Variante sehr zufrieden.

Bleibt abzuwarten welche Features sich in den kommenden Releases von PHP durchsetzen werden. Zumindest die oben beschriebenen Features wären von meiner Seite aus die meistgewünschten.

TYPO3 Extbase > Eigene Validatoren schreiben

Wer mit TYPO3 und Extbase eine eigene Extension mit einem Formular schreiben will, der kommt um Validatoren kaum rum (sofern man sich an die Vorgaben des Extbase-Frameworks hält). Wie ich bereits in einem älteren Artikel erwähnt habe, verwendet Extbase Annotations um einem Validator zu registrieren. Das heißt wir haben für jedes Formular ein Model, für dessen Eigenschaften ein oder mehrere Validatoren angemeldet werden. TYPO3 stellt bereits einige Standard-Validatoren zu Verfügung (z.B. um zu überprüfen, ob ein Feld nicht leer ist, oder ob die Eingabe nur Zahlen enthält.
Irgendwann kommt man aber an den Punkt, wo die Standards nicht mehr ausreichen und dann muss man einen eigenen Validator schreiben. Als praktisches Beispiel nehmen wir einfach mal ein typisches Kontaktformular. Nehmen wir mal an, wir hätten bereits eine funktionierende Extension contact_form mit einem Controller, Model und Template. Jetzt hat unser Kontaktformular allerdings ein Telefon-Feld und hier dürfen natürlich nur bestimmte Zeichen erlaubt sein. Um das zu lösen müssen wir einen eigenen Validator schreiben.

Aktuell sieht unser Model (in verkürzter Form) etwa so aus:

class Tx_ContactForm_Domain_Model_Contact extends Tx_Extbase_DomainObject_AbstractEntity
{
	/**
	 * @var string
	 * @validate NotEmpty
	 */
	protected $phone;
 
	public function getPhone()
	{
		return $this->phone;
	}
 
	public function setPhone($phone)
	{
		$this->phone = $phone;
	}
}

Über das @validate NotEmpty sagen wir Extbase, dass unser Formular nur dann gültig ist, wenn das Telefon-Feld befüllt ist. Andernfalls gibt es eine entsprechende Fehlermeldung.

Eigene Validatoren zu schreiben ist mehr als einfach. Zuerst legen wir eine neue Klasse an unter dem Verzeichnis typo3conf/ext/contact_form/Classes/Validation/Validator/PhoneNumberValidator.php:

class Tx_ContactForm_Validation_Validator_PhoneNumberValidator extends Tx_Extbase_Validation_Validator_AbstractValidator
{
	public function isValid($value)
	{
		$this->errors = array();
		if(preg_match('#([^0-9\-\+\(\)\s])#', $value))
		{
			$this->addError('The given subject is no valid value.', 40213131);
			return false;
		}
		return true;
	}
}

Unser Validator erbt von der Klasse AbstractValidator aus Extbase, die uns alle Basis-Funktion zum validieren zur Verfügung stellt. Wir müssen lediglich eine Methode isValid() schreiben, die unsere Logik für den Validtor enthält. Mit der Variable $value bekommen wir den über das Formular eingegebenen Wert übergeben und können den durch z.B. einen regulären Ausruck überprüfen. Wenn der Wert falsch ist, rufen wir die Methode $this->addError() auf und übergeben ihr eine Fehlermeldung und einen eindeutigen Error-Code. Der Error-Code ist wichtig, wenn man Fehlermeldungen bei der Ausgabe später übersetzen möchte.

Jetzt müssen wir unseren Validator nur noch für die Eigenschaft aus unserem Model registrieren. Das geht dann so:

class Tx_ContactForm_Domain_Model_Contact extends Tx_Extbase_DomainObject_AbstractEntity
{
	/**
	 * @var string
	 * @validate NotEmpty
	 * @validate Tx_ContactForm_Validation_Validator_PhoneNumberValidator
	 */
	protected $phone;
}

Es reicht aus dem @validate den kompletten Klassennamen zu nennen. Den Rest macht Extbase von alleine.

Achja, getestet habe ich das ganze mit Extbase 1.3 und der aktuellen TYPO3 Version 4.5. Falls sich etwas an dem Vorgehen verändert, versuche ich das hier zu aktualisieren.

Annotations in PHP sind böse

Was sind Annotations?

In der Software-Entwicklung werden Annotations verwendet, um die Dokumentation und Kommentierung des Quellcodes
zu verbessern. Für das ausführbare Programm sind Annotations völlig irrelevant.

Annotations unter PHP

In PHP findet man Annotations im Zusammenhang mit phpDoc-Kommentaren. PhpDoc-Kommentare werden verwendet, um Dateien, Klassen, Funktionen, Klassen-Eigenschaften und Methoden einheitlich zu beschreiben. Dort steht z.B. welche Parameter eine Funktion erwartet, welchen Rückgabewert es gibt oder welche Variablen-Typen verwendet werden.

Hier ein kleines Beispiel:

/**
 * Beschreibung der Datei.
 *
 * @author Name XYZ
 * @pacakge Lorem ipsum
 * @copyright Urherberrechtshinweis
 * @license GNU/GPL
 * @version 1.0
 */
 
/**
 * Beschreibung der Klassse.
 *
 * @category Dolor sit
 * @subpackage Lorem ipsum dolor
 */
class MeineKlasse
{
    /**
     * Beschreibung der Eigenschaft.
     *
     * @var integer
     */
    protected $eigenschaft = 0;
 
    /**
     * Beschreibung der Methode.
     *
     * @param integer $eigenschaft
     * @return boolean
     */
    public function setEigenschaft($eigenschaft)
    {
        $this->eigenschaft = $eigenschaft;
        return true;
    }
}

Die einheitliche Syntax der Kommentare wird unter anderem von den Entwicklungsumgebungen Zend Studio, Eclipse PDT oder NetBeans verwendet, um dem Entwickler weitere Informationen zu liefern. Außerdem nutzt der phpDocumentor die Kommentarblocks zur Generierung einer technischen Dokumentation.

Das klingt doch super. Warum sollten Annotations also böse sein?

Na ja, Annotations selbst sind vielleicht nicht böse, aber in einigen Fällen können sie böse werden. Z.B. dann, wenn man in Annotations Programmlogik versteckt. Also, wenn sich Annotations direkt auf das Verhalten des Programms auswirken.

So wird es leider im neuen TYPO3 5.0 Framework Flow3 gehandhabt. In Flow3 können Annotations u.a. eingesetzt werden, um Model-Eigenschaften zu validieren und das ist meiner Meinung nach keine gute Lösung. Denn Annotations sind ja erst einmal nur Kommentare und die werden bekanntlich vom Compiler (bzw. in PHP vom Interpreter) ignoriert. Leider ist PHP trotzdem in der Lage, durch die Reflection-API die Annotations auszuwerten. Hier wird also das Verhalten des Programms durch einen Kommentar direkt beeinflusst. Kommentare haben den Nachteil, das sie gerne überlesen oder entfernt werden und dann wird es umso schwieriger, eventuell auftretende Fehler zu finden.

Also liebe Entwickler von TYPO3 5.0 und alle anderen, die in Annotations gerne Programmlogik verpacken: Bitte überdenkt diese Programmierweise nochmals. Solange Annotations in PHP noch nicht als eigenes Sprachkonstrukt existieren (anders als in Java), sollten Kommentare immer entfernt werden können, ohne dabei das Verhalten des Programms zu beeinflussen.