PHP 5.3 ist da: Namespaces und Closures

Keine Zeit? Hier die Kurzversion in 30 Sekunden.
- PHP 5.3.0 ist seit Ende Juni draußen und bringt Namespaces, Closures und Late Static Binding.
- Namespaces trennt man mit dem Backslash, importiert wird mit
use.- Anonyme Funktionen bekommen Variablen von außen nur über
use (...)mit.- Mit
static::undnew staticzeigt eine statische Methode auf die aufgerufene Klasse, nicht auf die definierende.- Viele Hoster laufen noch auf 5.2, also vor dem Umstieg prüfen.
Seit dem 30. Juni gibt es PHP 5.3.0, und ich habe mir die neuen Sachen am Wochenende mal in Ruhe angeschaut. Es ist das größte Update seit langem. Ich picke mir die drei Dinge raus, die ich am spannendsten finde.
Namespaces
Bisher hat man Klassen gern Blog_Util_Str genannt, damit sich nichts in die Quere kommt. Das war schon okay, aber unhandlich. Jetzt geht es richtig:
<?php
// datei Str.php
namespace Blog\Util;
class Str {
public static function slug($text) {
return strtolower(preg_replace('/[^a-z0-9]+/i', '-', $text));
}
}
function hallo() {
return 'Hallo aus Blog\Util';
}Benutzen kann man das auf zwei Arten:
<?php
require 'Str.php';
use Blog\Util\Str;
echo Str::slug('Hallo Welt'); // hallo-welt
echo \Blog\Util\hallo(); // voller Name mit führendem BackslashEin Stolperstein: Innerhalb eines Namespace sucht PHP Klassen erst mal im eigenen Namespace. Wollt ihr die eingebaute Exception werfen, müsst ihr \Exception schreiben, sonst gibt es einen Fehler. Bei Funktionen wie strlen greift dagegen ein Fallback auf den globalen Namensraum, das ist ein bisschen inkonsequent, aber bequem.
Warum das Ganze? Sobald ein Projekt wächst und man fremde Bibliotheken dazunimmt, ist die Chance groß, dass zwei Klassen Logger oder Config heißen. Mit Namespaces ist das kein Drama mehr, und die endlosen Präfixe in den Klassennamen verschwinden. Auch der Autoloader wird dadurch übersichtlicher, weil man den Namespace einfach auf einen Ordnerpfad abbilden kann. Ich habe das bisher nur in einem kleinen Testprojekt gemacht, aber es fühlt sich richtig an.
Closures
Anonyme Funktionen gab es mit create_function schon, aber das war ein Zeichenketten-Gefummel. Jetzt schreibt man die Funktion einfach hin:
<?php
$mwst = 0.19;
$netto = array(10, 20, 30);
$brutto = array_map(function ($n) use ($mwst) {
return $n * (1 + $mwst);
}, $netto);
$personen = array(
array('name' => 'Meier'),
array('name' => 'Albers'),
);
usort($personen, function ($a, $b) {
return strcmp($a['name'], $b['name']);
});Wichtig ist das use ($mwst). Anders als in JavaScript sieht die Funktion Variablen von außen nicht automatisch, ihr müsst sie ausdrücklich hereinreichen. Am Anfang vergisst man das ständig. Und die Variable wird als Kopie übergeben, Änderungen drinnen sieht draußen niemand (es sei denn, ihr nehmt use (&$var)).
Gerade bei usort finde ich das angenehm, weil man für eine einmalige Sortierung keine extra Funktion mit Namen mehr anlegen muss.
Noch ein Nebeneffekt: Closures kann man auch in Variablen speichern und später wie Funktionen aufrufen, mit $f(5). Damit lassen sich kleine Callbacks sauber weiterreichen, ohne dass man Funktionsnamen als Strings herumschiebt. Das sieht man in anderen Sprachen schon lange, in PHP ist es neu.
Late Static Binding
Kurz noch, weil es mich schon öfter geärgert hat: self:: zeigt immer auf die Klasse, in der der Code steht. Mit static:: zeigt es auf die Klasse, die tatsächlich aufgerufen wurde.
<?php
class Model {
public static function create() {
return new static();
}
}
class User extends Model {}
$u = User::create();
echo get_class($u); // UserMit new self() hätte man hier ein Model bekommen. Für kleine Active-Record-Spielereien ist das Gold wert.
Praktisch ist das etwa, wenn eine Basisklasse eine Fabrikmethode anbietet und die Unterklassen nichts extra überschreiben müssen. Vorher musste man sich mit Tricks behelfen oder in jeder Unterklasse dieselbe Methode wiederholen.
Und der Hoster?
Jetzt der Dämpfer: Viele Hoster bieten noch PHP 5.2 oder sogar 4 an. Wenn ihr Software für fremde Server schreibt, könnt ihr die neuen Sachen also vorerst nicht einfach voraussetzen. Ein namespace auf einem 5.2-Server gibt nur einen Parse-Fehler. Für eigene Projekte auf eigenem Server spricht dagegen nichts.
Habt ihr 5.3 schon im Einsatz oder wartet ihr noch auf euren Hoster? Schreibt mir gern, was bei euch kaputtgegangen ist.
Beitragsbild: eigene Collage mit Logos von Wikimedia Commons (PHP-Logo: Colin Viebrock), jeweils gemeinfrei; die Marken gehören ihren Inhabern.
Christian Ackermann
Softwareentwickler (C++, C, Java, C#) aus der Oberpfalz, bloggt seit 2001 über Linux, Technik und Kochen.