7 einfache Tipps zur Verbesserung von Code-Qualität

PHP ist dafür bekannt, dass es kaum Anwendungen mit qualitativ hochwertigen Code gibt. Dabei gibt es viele Tools, die dabei helfen mit relativ wenig Aufwand die Code-Qualität enorm zu steigern. Die 7 einfachsten – und meiner Meinung nach auch wichtigsten – Tipps zur Steigerung von Code-Qualität habe ich hier einmal zusammengestellt.
Auch wenn diese Tipps speziell für PHP zugeschnitten sind, kann man fast alle Tipps auch für andere Programmiersprachen anwenden.

  1. Versionskontrolle verwenden
    Tools wie Subversion oder Git helfen das Versions-Wirr-Warr bei Anwendungen besser verwalten zu können. Und wenn Fehler auftreten, lässt sich schnell eine alte Version zurückholen, oder ein Patch erstellen, der anderen Entwicklern zur Verfügung gestellt werden kann.
    http://subversion.tigris.org/
    http://git-scm.com/
  2. Unit-Tests schreiben
    Wenn man ein neue Anwendung entwickelt, dann sollte man direkt zu Beginn Unit-Tests für jede Komponente schreiben. Das spart extrem viel Zeit, wenn die Anwendung zu einem späteren Zeitpunkt erweitert oder geändert wird und nochmal getestet werden muss.
    http://www.phpunit.de/
    http://www.junit.org/
  3. Profiling
    Ab und zu macht es Sinn einmal ein komplettes Profil der Anwendung generieren zu lassen. Dabei werden alle Funktionsaufrufe aufgenommen, die Zeit festgehalten und anschließend geguckt an welchen Stellen die Anwendung zu langsam ist oder sich die Anzahl der Funktionsaufrufe optimieren lässt. Das ist ein wichtiger Faktor für die Performance-Optimierung der Anwendung.
    http://www.xdebug.org/
  4. Kommentare
    Der komplette Code sollte immer mit einheitlichen Kommentarblöcken versehen werden, die Klassen, Funktionen oder Interfaces genauer beschreiben. Das hilft nicht nur dabei eine technische Dokumentation des Codes generieren zu lassen, sondern kann auch von einigen IDEs gelesen werden und unterstützt somit die Autovervollständigung bei der Entwicklung.
    http://www.phpdoc.org/
    http://www.stack.nl/~dimitri/doxygen/index.html
  5. Einheitlicher Code (Coding Standards)
    Der Code sollte immer einem einheitlich Coding Standard folgen. Das heißt gleiche Abstände, Einrückungen, Anführungszeichen, Namenskonventionen oder Zeilenumbrüche. Dadurch lässt sich der Code von jedem Entwickler leichter lesen.
    Manchmal gibt es auch Tools, die den Code untersuchen und anschließend überprüfen ob die vorher definierten Standards tatsächlich überall eingehalten wurden.
    http://pear.php.net/package/PHP_CodeSniffer
  6. Doppelter Code
    Manchmal findet man Code-Fragmente, die sich bis auf wenige Parameter gleichen, oder die selbe Aufgabe haben. Hier sollte man unbedingt überprüfen, ob sich diese Fragmente nicht ausgelagern lassen in eine eigene Klasse oder Methode. Auch dazu gibt es wieder Tools, die solche Stellen im Code automatisiert finden können.
    https://github.com/sebastianbergmann/phpcpd
  7. Code-Trennung
    Dieser Punkt ist besonders bei Webanwendungen wichtig: Der Code von verschiedenen Sprachen sollte immer getrennt in eigenen Dateien liegen. JavaScript-Code und CSS-Anweisungen haben nichts im HTML-Quellcode zu suchen. Und bei PHP-Templates z.B. sollte darauf geachtet werden, dass diese möglichst wenig Programmlogik enthalten. Wer mag, kann auch eine Template-Engine verwenden.

Wer sich an diese Tipps hält, hat schonmal ein solides Grundgerüst für eine hohe Code-Qualität in seiner Anwendung.

PHP: Datei-Rechte rekursiv ändern

Manchmal möchte man auf UNIX-basierten Servern die Dateirechte via PHP für alle Dateien und Unterverzeichnissen ändern (also rekursiv). Das lässt sich recht einfach lösen, vorallem wenn man keine UNIX-Funktionen aufrufen kann. Wir nutzen dazu einfach die rekursiven Iterator, die der Spl beiliegen:

<?php
$folder  = dirname(__FILE__);
$folder .= '/verzeichnis'; // Hier das Verzeichnis angeben (ausgehend vom Verzeichnis dieser Datei)
 
chmod($folder, 0777);
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder), RecursiveIteratorIterator::CHILD_FIRST);
foreach($dir as $file)
{
	chmod($file->getPathname(), 0777);
	echo 'chmod 0777 '.$file->getPathname().'<br>';
}
?>

Um es kurz zu erklären: Wir erstellen ein Objekt RecursiveIteratorIterator, mit dem wir das zweite Objekt RecursiveDirectoryIterator in einer Foreach-Schleife durchlaufen können. Etwas verzwickt, ist aber die einfachste und schnellste Methode um rekursiv Verzeichnisse zu durchlaufen.

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.