Facebook
Twitter
Google+
Kommentare
26

PHP 5.3 – Die neuen Features

Als erstes möchte ich mal bei Nils bedanken das er dieses tolle Projekt ins Leben gerufen hat! Und als zweites möchte ich mich kurz vorstellen. Ich bin Manuel Grundner, ich komme aus dem Herzen der Steiermark, genauer gesagt aus Graz, und bin seit längerer Zeit Freier Mitarbeiter beziehungsweise Selbstständiger auf dem Websektor mit Schwerpunkt auf PHP-Entwicklung.
So aber genug um den heißen Brei herum geredet, ich werde versuchen euch die neuen Sprachfeatures von PHP5.3 vorallem in Verbindung mit Patterns etwas näher zu bringen. Für die, die es noch nicht wissen, PHP5.3 ist bereits mit RC2 am Start, und viele (vor allem ich) warten schon gierig auf die neuen Features:

  • Namespaces – Welch ein Segen für jeden Framework-Entwickler
  • Late Static Binding – Ein tolles Feature, das ich auch schon lange vermisst habe
  • Type-Hinting – self, parent, interfaces; könnte zwar schwören das die Interfaces in 5.2 schon gingen, aber je mehr Type-Hinting desto besser!
  • Closures & Lambda – Ein bisschen prozedural darfs sein…
  • GOTO – Ein Feature dem ich weniger positiv gegenüber stehe… es hat jedoch sicher irgendwo seine Berechtigung
  • NOWDOC – Late Static Binding für die HEREDOC-Syntax
  • __invoke – Benutz mich! Wie das schon wieder klingt… 😉 Objekte als Funktionen
  • __callStatic – __call im statischen Kontext
  • Rundungsverhalten – Kam einen auch schon öfter in die Quere…
  • __DIR__ – Wo bin ich? oder dirname(__FILE__) mal anders
  • Und noch einiges mehr, für weitere Schmökereien: das Scratchpad (http://wiki.php.net/doc/scratchpad/upgrade/53)
  • Und für die die Undokumentiertes lieben (http://wiki.php.net/doc/todo/undocumented)

Da hat sich ja einiges getan! Ich bin so aufgeregt, ich weiß gar nicht wo ich anfangen soll! Ach was, machen wirs wie ein Interpreter, schön brav von oben nach unten!

Namespaces sind wirklich ein Feature, bei dem sich die Community wahrhaftig die Seele aus dem Leib gebrüllt hat. Viele andere Sprachen machten es vor, oder hatten es bereits von Anfang an Bord, PHP brauchte eben noch etwas Zeit.

Aber Namespaces? Kann man das essen? Naja essen nicht gerade, aber man kann den Küchenjungen vorm Gast „verstecken“ oder so ähnlich.

Um aus dem Wiki zu zitieren:
Ein Namensraum ist ein deklaratorischer Bereich, der einen zusätzlichen Bezeichner an jeden Namen anheftet, der darin deklariert wurde. Dieser zusätzliche Bezeichner macht es weniger wahrscheinlich, dass ein Namenskonflikt auftritt mit Namen, die anderswo im Programm deklariert wurden. Es ist möglich, den gleichen Namen in unterschiedlichen Namensräumen ohne Konflikt zu verwenden, auch wenn der gleiche Name in der gleichen Übersetzungseinheit vorkommt. Solange er in unterschiedlichen Namensräumen erscheint, ist jeder Name eindeutig aufgrund des zugefügten Namensraumbezeichners.

Oke was bedeutet das jetz aber genau, und vorallem im Bezug auf PHP?

Fangen wir mal mit der Syntax an:

<?php
namespace PHPHatesMe;

function sometimesSure()
{
  return 'Yeah!';
}
?>

Das Keyword „namespace“ leitet die Deklaration eines neuen Namensraums ein. Wenn Namespaces verwendet werden sollen, muss es vor jeder Zeile PHP-Code stehen. Hierbei sei zu beachten das diese Notation nur einen einzigen Namespace pro Datei möglich zulässt.

Aber was bedeutet das jetzt?
Will ich nun die Funktion sometimesSure() aufrufen, kann ich sie nicht mehr ohne weiteres mit sometimesSure() aufrufen, es sei denn diese Funktion liegt im selben Namespace. Der Interpreter präfixed jeden Funktions-, Klassen- oder Methodenname mit dem Namespace in dem er liegt.

Der Aufruf:
PHP hat zwar einen nicht sehr benutzerfreundlichen Trenner (\) für Namespaces gewählt, und Wunsch der Community nach dem :: oder ::: Operator verdrängt, aber hinsichtlich auf Konflikte mit der bestehenden Engine (Statische Variablen, Methoden und Konstanten) und der einfacheren Tippweise auf Englischen Tastaturen sich für den Backslash entschieden.

Möchte ich nun aus einer anderen Datei, oder aus einem anderen Namespace herraus aufrufen muss ich den Präfix voranstellen.

<?php
echo \PHPHatesMe\sometimesSure(); //Yeah!
?>

Liest sich etwas holprig, aber das Leben wird schön, wenn man das „use“ Keyword kennt (oder endlich IDE’s mit Namespace-Unterstützung auftauchen)

<?php
use PHPHatesMe;
echo PHPHatesMe\sometimesSure(); //Yeah!
?>

„use“ importiert einen Namensraum in einen anderen (in diesem Fall in den globalen). Der Globale Namensraum ist eine wichtige Sache! Spätestens dann wenn man PHP-Interne Klassen oder Konstanten aus einem Namespace-Focus anspricht:

<?php
namespace PHPHatesMe\Really;

use \Exception as BaseException;

class Exception extends BaseException;
{

}
function throwMe()
{
  throw new Exception('Who am I?');  //PHPHatesMe\Really\Exception
}
?>

Hier wird auch der Vorteil Namespaces sehr deutlich, endlich Klassen die einen Namen tragen der ihrer Verwendung entspricht! Zugegeben, das Beispiel war nicht gerade das Beste, aber ich denke der Grundgedanke kam durch.

Gleich haben wir ein neues Keyword gelernt „as“. Dieses Keyword in Verbindung mit „use“ ermöglicht es dem Entwickler einen Alias für einen Namen zu verwenden und diesen komplett in den Namespace zu integrieren. Dies kann bei Namenskonflikten hilfreich sein, oder bei zu langen Klassennamen Abhilfe schaffen. Hierbei sollte man natürlich beachten, dass die Lesbarkeit und somit die Wartbarkeit von Code reduziert werden kann. Es sei also mit Bedacht gewählt, denn wer aus dem Klassennamen User schlicht und ergreifend U macht, wird sich nach einiger Zeit fragen was U ist, und wer möchte schon ständig in der Namespace-Deklaration nachsehen was U eigentlich bedeutet.
Keine Angst, sollten Namenskonflikte bei der Alias-Zuweisung auftreten meckert PHP und es wird nicht einfach irgendwas aufgerufen.

Ich denke das dies als kleine Einführung in die Welt der PHP-Namespaces fürs erste genügt. Wer Lust darauf bekommen hat kann natürlich in der Online-Dokumentation (http://de.php.net/manual/en/language.namespaces.php) weitere Informationen erhalten. Ich verweise hier bewusst auf die Englische, da das deutsche Dokumentationsteam leider immer etwas nachhinkt.

In meinen (hoffentlich) weiteren Artikeln werde ich immer Gebrauch der neuen Sprachfeatures machen, was das gute Zusammenspiel der Features hervorhebt, jedoch leider auch aufbauendes Wissen auf ältere Artikel fordert. Aber keine Angst, PHP hasst euch nicht immer.

Über den Autor

Manuel Grundner

Kommentare

26 Comments

  1. Von allen Neuigkeiten finde ich Late Static Binding und __DIR__ am besten. 😉

    Die anderen Sachen sind natürlich auch nicht zu verachten.

    Reply
  2. Ich freu mich am meisten auf LSB und __callStatic und natuerlich Namespaces, wobei ich da immer noch der Meinung bin, dass es einfach daemlich aussieht, aber naja, wird man sich wohl dran gewoehnen muessen.

    Auch wenn ich langsam zu Ruby und RoR ueberwechsele, bin ich trotzdem drauf gespannt, wenn die 5.3er endlich draussen ist.

    Reply
  3. Ruby und RoR habe ich mir auch schon öfters mal angeschaut, ich glaube insgesamt drei Mal allerdings immer nur kurzfristig, ich bin auch immer wieder begeistert und fasziniert gewesen, so richtig hängen geblieben bin ich allerdings bisher nicht. 😉

    Reply
  4. Naja die Syntax der Namespaces ist wirklich sehr gewöhnungsbedürftig..
    Was mich mehr ärgerte war die Tatsache das sie von :: nach \ gewechselt haben.
    Nachdem ich ja ein Framework auf Basis PHP5.3 entwickle war das natürlich sehr spannend… Search & Replace war da natürlich nicht mehr…
    Ansonsten find ichs jetz auch recht interessant das man auch 2 Namespaces in einer Datei verwednen kann (auch wenn ich das noch nie gebraucht hätte:

    namespace abc {
    }
    namespace dfg{
    }

    Reply
  5. Pingback: ITWS
  6. Ich freue mich auf header_remove() – das habe ich schon lange erhofft, weil man ja doch immer mal mit schwachsinnigem Code zusammenarbeiten muß. Und mit den »undokumentierten Features« zu Notation der Unicodepositionen muß ich mal herumspielen.

    Auch Phar (http://docs.php.net/manual/en/intro.phar.php) sieht sehr interessant aus.

    Die Namespaces riechen mir noch zu sehr nach »lieber eine schlechte Lösung als gar keine«. Wie Manuel schon andeutet, wird das Suchen per Regex jetzt noch ein bißchen komplizierter … das hätte sich bestimmt besser einrichten lassen.

    Reply
  7. Ich halte es für eine gute Entscheidung, dass sie \ statt :: verwenden, denn sonst ist es sehr schwierig herauszufinden, was „new A::B()“ bezeichnet: Das Erstellen der Klasse B im Namespace A oder das Erstellen einer Klasse dessen Rückgabewert von entweder der Methode B der Klasse A stammt oder der Funktion B aus dem Namespace A stammt. Wenn man dann noch berücksichtigt, dass es dann noch weitere Auflösungsregeln gibt (Stichwort: globaler Namespace) finde ich es schon besser, dass ein neuer Operator dafür spendiert wurde – auch wenn er nicht schön ist. 🙂

    Reply
  8. @Thomas
    Ich habe zum Glück recht wenig mit Legacy Code zu kämpfen, deswegen ist mir header_remove noch gar nicht aufgefallen, werde ich mir aber mal angucken.
    Mit PHAR wollte ich schon herumspielen, hatte bis dato aber noch nicht die Gelegenheit. Das wäre für ein Package-management, oder eine Plugin-architektur sicher von Vorteil, ich hoffe das der Overhead dort nicht zu groß ist. Leider steckt das Teil halt im PECL, und das schreckt mich halt noch immer ab.

    @Backflash
    Ja, das war ja der Hauptgrund für die Wahl des \. Trotzdem hätte ~ auch nicht schlecht gepasst, oder irgendwas anderes.. wenn man mit Klassennamen herumspielt, wirds oft schön gefährlich…
    „PHPHatesMe\\never\\ever“
    Das liest sich nicht nur katastrophal, sondern kann echt verquere Seiteneffekte mitbringen, leider.

    Reply
  9. Nachtrag:
    Man sollte die Dokumentation genauer lesen…

    Since PHP 5.3.0, Phar extension is built-in, no DLL is needed.

    Reply
  10. Gestern haben wir übrigens RC3 veröffentlicht, der Artikel is somit out of date 😉
    (oh und einen 5.2.10 RC gab es gestern auch)

    Und hey, bitte testet es. Jetzt! – Wer JETZT nicht testet braucht sich später nicht zu beschweren, wenn wir versehentlich irgendwo Abwärtskompatibilität gebrochen haben. :-p

    Reply
  11. @Johannes
    Danke für den Tipp! Ihr macht das mit den Updates immer so klammheimlich.. ^^
    Bei mir funktioniert nocht alles 😛

    Reply
  12. Ich denke nicht das LSB ein Weg ist schlechtes Design zu kompensieren. Es kommt immer drauf an wie und wann man es einsetzt.
    Viele Bindungen sind zur Laufzeit einfach besser und eleganter aufzulösen. Das Decorator-Pattern ist ja im Prinzip nichts anderes, nur das es halt Objekte sind.
    LSB hat viele Vorteile wenn es darum geht statische Methoden oder Eigenschaften noch überladbar zu machen.

    BTW: Ich bin begeistert welche Diskussion ich hier für meinen ersten Blogeinstrag losgerissen habe! 😀

    Reply
  13. Ich werde wahrscheinlich nie Gebrauch von LSB machen, da ich es vorziehe mit Objekten und nicht Klassen (deshalb OOP und nicht KOP ;-)) zu programmieren. Denn durch das Verwenden von statischen Methoden führt man i.d.R. nur globale Abhängigkeiten ein, die schlicht nicht notwendig sind. Aber das hat weniger mit PHP 5.3 zu tun…

    Reply
  14. @Manuel: muss ganz ehrlich sagen, ich verwend viele externe klassen, und muss diese auch öfter extenden aber bei static methoden/klassen hatte ich noch nie probleme. liegt vielleicht auch daran das die meisten static methoden getInstance() waren oder wirklich nur eine alleinstehende methode die einfach in einer Utils klasse gecapselt war.

    Reply
  15. Wo sich LSB in der Architektur gut bemerkbar macht sind z.B Klassen die sich selbst irgendwo registrieren.
    Ich denke ich werde hier mal einen Artikel drüber verfassen, wo sich LSB in meinen Augen produktiv sinnvoll einsetzen lässt.

    Reply
  16. @Toby: Du hast vollkommen Recht!
    @Nils: Kannst du das ändern? Oder darf ich in meinen eigenen Beiträgen rumpfuschen? 😀

    Reply
  17. @Christopher: Ja es ist das, was du denkst. Aber wenn du es nicht brauchst, dann musst du es ja nicht verwenden. Leute die Ahnung haben, werden es schon an den richtigen Stellen anwenden. Von Leuten die keine Ahnung haben, habe ich eh noch nie aktiv Code verwendet.

    Reply
  18. Oh du hast recht, ich hab mich falsch ausgedrückt, ich meinte eher Heredoc für statische Member.
    Aber danke für die Korrektur.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen