PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


PHP 5.4.0 released! Neue Funktionen

with 37 comments

Soeben wurde PHP 5.4.0 released! Nach 8 Release Candidates ist nun die finale Version erschienen und kann auf php.net heruntergeladen werden. Ich habe 2 meiner größeren Applikationen bereits mit der neuen Version getestet (mit dem RC8, der gleich der finalen Version ist). Sobald DotDeb die neue Version released wird der Server upgedated.

So, hier eine Übersicht der wichtigsten Änderungen:

    1. Das wohl größte Feature: Traits (auch „Horizontal Reuse“ renannt). Hier im Blog gibt es auch schon einen sehr ausführlichen Artikel über Traits.
      <?
      class Base {
          public function sayHello() {
              echo 'Hello ';
          }
      }
      
      trait SayWorld {
          public function sayHello() {
              parent::sayHello();
              echo 'World!';
          }
      }
      
      class MyHelloWorld extends Base {
          use SayWorld;
      }
      
      $o = new MyHelloWorld();
      $o->sayHello();

      Weitere Details und Beispiele zu Traits gibt es in diesen Blogartikeln.

  • Auf das nächste Feature habe ich schon einige Jahre gewartet, endlich kommt es: Array-Dereferenzierung!
    <?
    function autos () {
        return array('a' => 'audi', 'b' => 'bmw');
    }
    
    echo autos()['a'];
  • Nun sind Methodenaufrufe direkt nach dem Constructor möglich, also ein Fluent Interface:
    echo (new Auto())->getName();
  • Neuer Typehint „callable„, der Parameter muss also „irgendwie aufrufbar“ sein, sprich ein Funktionsname, ein Array mit Klassennamen und statischem Methodennamen, oder ein Array mit Objekt und Methodennamen. Details siehe is_callable()
    <?
    function doSomething(callable $cb) {
        $cb();
    }
  • Die Short Array Syntaxkommt! Ob ich sie mag weiß ich noch nicht so ganz, man spart sich einfach 5 Zeichen. Aber immerhin hat man dann in Javascript bzw. JSON die gleiche Syntax.
    <?
    $a = [1, 2, 3];
    $b = ['key1' => 'value1', 'key2' => 'value2'];
  • Native Binärzahlen kommen (wer sie braucht)
    <?
    $x = 0b001110;
    echo $x;
  • Mehr Flexibilität bei variablen Methodenaufrufen: Class::{expr}()
    <?
    class ClassA
    {
        public function doSomething() {
            echo "something\n";
        }
    }
    
    $method = 'doSomething';
    
    $classA = new ClassA();
    
    $classA->doSomething();
    $classA->$method();
    $classA->{'doSomething'}();
    
    ClassA::doSomething();
    ClassA::$method();
    ClassA::{'doSomething'}();
  • $GLOBALS ist nun eine Just-In-Time (JIT) Variable. Andere würden es „lazy initialisation“ nennen. Sie wird also erst initialisiert wenn sie das erste Mal benutzt wird, man gewinnt also eventuell etwas Performance wenn man es nicht nutzt.
  • Die Performance des Silence-Operators wurde etwas verbessert:
    <?
    for ($i=0; $i<1000000; $i++) {
        $x = @file_get_contents('/etc/passwdff');
        echo $x;
    }
    PHP 5.3.9
    
    real    0m4.134s
    user    0m3.244s
    sys    0m0.884s
    
    PHP 5.4 RC6
    
    real    0m3.050s
    user    0m2.176s
    sys    0m0.872s
  • Zugriff auf den Upload Progress ohne Extension. Details siehe Artikel bei Johannes oder im PHP Manual.
  • E_ALL enthält nun E_STRICT
  • Ein kleiner eingebauter Webserver für Tests und Entwicklungsumgebungen. Ich hatte ja bereits hier im Blog darüber geschrieben.
  • <?= ist nun immer verfügbar, auch wenn short_open_tag ausgeschaltet ist
  • Wenn ein Array automatisch in einen String gecastet wird („Array“) gibt es nun eine Notice
  • „default_charset“ php.ini Einstellung von ISO-8859-1 auf UTF-8 gesetzt
  • Und noch einige weitere Performance- sowie Speicheroptimierungen und Bugfixes.

 

Einige Dinge wurden nun auch endgültig entfernt:

  • Bei break und continue kann nun nicht mehr eine Variable genutzt werden um die Anzahl der Schleifenabbrüche zu definieren.
  • Die seit PHP 5.3 als DEPRECATED markierten Safe-Mode-Funktionen sowie alle php.ini Variablen wurden entfernt.
  • Magic Quotes (magic_quotes_gpc) wurden entfernt!
  • Endlich wurden register_globals und register_long_arrays aus der php.ini entfernt.
  • Die Einstellung allow_call_time_pass_reference wurde entfernt.

CHANGELOG + NEWS + Migrationshilfe von 5.3 nach 5.4

Habe ich etwas wichtiges vergessen? Welche Änderung findet ihr am herausragendsten?

Written by Michael Kliewe

März 2nd, 2012 at 12:41 am

Posted in PHP

Tagged with , , , , ,

37 Responses to 'PHP 5.4.0 released! Neue Funktionen'

Subscribe to comments with RSS or TrackBack to 'PHP 5.4.0 released! Neue Funktionen'.

  1. Deiner Liste zufolge sind die Features #2 und #3 in meinen Augen am angenehmsten. Traits habe ich nie vermisst.
    Der Rest ist teilweise ganz nett, teilweise auch einfach sinnfrei.

    Sören Noormann

    2 Mrz 12 at 01:02

  2. Schöne Zusammenfassung, die Traits muss ich mir auch erst genauer angucken 🙂

    Jens

    2 Mrz 12 at 02:15

  3. PHP 5.4 stellt ist meiner Meinung nach mal ein richtig rundes, von Altlasten gesäubertes PHP. Sehr schön. Freue mich vor allem über Traits, die Array-Dereferenzierung und den direkten Aufruf nach dem Konstruktor.

    Martin Kuckert

    2 Mrz 12 at 07:30

  4. Schöne Übersicht.
    Ein großartiges Feature hast du aber vergessen. Es gibt nun ein SessionHandlerInterface.

    Am Interessantesten finde ich ist der integrierte Webserver. Ein Feature was ich sehr vermisst habe.

    Markus

    2 Mrz 12 at 08:22

  5. Oh, die nativen Binärzahlen sind aber sehr schön! Das wusste ich noch nicht.

    Bin ja ein sehr großer Fan von Bitmaps und Bitmap-Handling für bestimmte Arten von Optionen. Mit Dezimalzahlen, gerade wenn mehrer schon kombiniert sind, ist das ja ein Graus (Oder wer von euch kann aus der error_reporting-Zahl direkt sagen welche Dinge nun aktiviert sind?).

    Das SessionHandlerInteface hab ich auch schon manchmal vermisst.

    Die abgekürzten Array-Schreibweise, gerade als MongoDB-Nutzer – ein Traum!

    Bei den Traits bin ich gespannt. Hätte ja auch an echter Mehrfachvererbung Freude, aber vielleicht sind Traits der bessere Kompromiss.

    @Sören: Sinnfreies kann ich eigentlich nicht entdecken? Kann glaube ich alles unter bestimmten Umständen gebrauchen?

    Florian Heinze

    2 Mrz 12 at 09:16

  6. Meine Favoriten: #2, #3, #10, #11, #12, #13 und #15
    Und ich muss nun erstmal ne Menge Kundenprojekte testen, ob die überhaupt ein Update vertragen … ui, das dauert 🙁
    Aber: Danke für die super Zusammenfassung.

    Sascha Presnac

    2 Mrz 12 at 10:51

  7. Ich persönlich empfinde im übrigen #2 als beste Neuerung.
    #9 halte ich dagegen für relativ wertlos, zumindest mir bringt es nichts – wenn ich mir das mal umrechne, wie wenig Performance dort in all meinen Scripten draufgeht, dann finde ich, gibt es schlimmere Baustellen innerhalb von PHP.

    #7 ist ansonsten noch ganz nett, gefällt mir!

    voodoo44

    2 Mrz 12 at 11:26

  8. Hm, ich würd mir ja als erstes mal wünschen, dass alle wichtigen Extensions laufen, bzw. bald released werden. Ich hab manchmal das Gefühl, als würde keiner der Extension Maintainer gegen die RCs testen. ext-memcache wirft mal schön ne Runde Seg-faults in die Runde, APC und xDebug laufen nur aus master oder trunk. Ich könnte grad son klein bissl kotzen.

    Mario Mueller

    2 Mrz 12 at 12:15

  9. Muss Mario zustimmen. Das xdebug (unter Windows) noch nicht mit 5.4 tut, ist ein Grund für mich, meine lokales Entwicklungssystem nicht zu updaten (bzw. mein WebApps mit 5.3.x zu entwickeln). Ziemlich schade.

    Ich hoffe ausserdem, dass sich ziemlich schnell eine Quasi-Standard für Traits entwickelt. Nicht das sie jeder versucht anzuwenden, nur damit er sie benutzt hat. Auch vom Naming/Namespacing her sollte sich eine gänginge Lösung finden lassen. Allerdings wird das wohl in naher Zukunft nichts, da die grossen Framework-Entwickler die nächsten 2 Jahre eh nicht für 5.4 entwicklen werden.

    Das mit der binären Notation ist besonders für Bitsets kuhl:

    FLAG_FOO = 0b0001;
    FLAG_BAR = 0b0010;
    FLAG_BAZ = 0b0100;

    Und natürlich für Bitmasks. Aber die trifft man ja eher selten an.

    Im Grossen ein tolles Update für PHP. Besten Dank an alle Beteiligten!

    Phil

    2 Mrz 12 at 12:34

  10. Ahja: Ich erfreue mich besonders der „kleineren“ Dingen wie callable-Typehint, UTF-8 Standard, Stabilitäts-/Performanceboost, Short Array Syntax und dass man Altlasten los wurde.

    PS: Vorhin ging’s etwas schnell… #typos

    Phil

    2 Mrz 12 at 12:38

  11. @Mario, @Phil
    Klar wäre es am besten wenn gleich alle Extensions gut laufen.

    Nur wie sollten man das Problem auflösen? Wenn die Extension-Manager mal keine Zeit haben ist das ja durchaus nachvollziehbar.

    Vermutlich ist es denen ja sogar bekannt das es diese Probleme gibt. Aber was soll man tun? Warten bis alle Extension-Manager ein okay gäben? Dann gäbe es vermutlich nur selten neue Versionen 😉

    Von daher nehme ich es halt einfach so hin wie es ist. Will ich den aktuellsten Kram benutzen, muss ich halt leider dafür mit Problemen rechnen. Oder ich muss C lernen 😉

    Florian Heinze

    2 Mrz 12 at 13:05

  12. Ich glaube auch dass innerhalb der nächsten 2-3 Wochen da viel passieren wird, denn der Druck steigt 😉

    DotDeb hat bereits „Preview Packages“ veröffentlicht für debianbasierte Systeme. Dort wird auch aufgelistet welche Extensions noch Probleme machen (z.B. auch suhosin):
    http://www.dotdeb.org/2012/03/01/php-5-4-0-preview-packages/

    Michael Kliewe

    2 Mrz 12 at 13:10

  13. @Phil:

    Das die großen Framework Entwickler nicht für PHP5.4 entwickeln stimmt nicht. Symfony 2 und Twig unterstützen PHP5.4 sehr gut.

    Markus

    2 Mrz 12 at 15:07

  14. @Markus: Na hoffentlich ist Symfony vorwärtskompatibel. Die nächsten 1.5 – 2 Jahre wird es aber auch rückwärtskompatibel zu PHP 5.3 sein. Ausser das Unmögliche geschieht und alle Hoster fangen plötzlich an, ihre PHP-Installationen zeitlich zu updaten.

    Phil

    2 Mrz 12 at 16:47

  15. Habe mir mal die mühe gemacht die Installation von PHP 5.4 unter Windows XP mit WAMP zu „filmen“, falls also jemand mal testen will und mehrere PHP Versionen braucht:

    http://bit.ly/z9Cgmk

    Hoffe der Link ist ok.

    Arne

    3 Mrz 12 at 12:17

  16. Ui.
    Wer schonmal „Clean Code“ von Robert C. Martin gelesen hat, wird vieles in PHP 5.4 sicherlich ein wenig befremdlich finden. Gerade Traits. Mal ehrlich: Welchen echten Nutzen haben die, wo es doch mit DI einen sauberen Ansatz gibt?

    Warum wurde eigentlich der Parameter von break und continue abgeschafft? Zugunsten von GOTO?

    Immer noch kein Typehinting fuer primitive Typen? Dafuer aber mehr Moeglichkeiten, Code durch Magic zu verklausulieren?

    PHP fuehlt sich so schon in groesseren Projekten falsch an. Dieses Release setzt da noch ein Ausrufungszeichen hinter.

    Ronald Kirschler

    4 Mrz 12 at 15:31

  17. @Ronald:

    Ich verstehe den Ansatz von PHP eigentlich so, das die Sprache einem eine sehr große Freiheit gibt. Mit dieser Freiheit mit Bedacht umzugehen, dafür ist der Entwickler dann selbst verantwortlich.

    Mir gefällt der Ansatz gut.

    Florian Heinze

    4 Mrz 12 at 16:44

  18. Traits ringen mir keine Entzückensschreie ab, verursachen aber auch keine Albträume. Ich schätze sie als begrenzt und eher situativ sinnvoll ein. Mal abwarten. Sie erinnern mich an die Einführung von goto.

    Die Syntaxvereinfachungen sollte man nicht unterschätzen. Wahrscheinlich ist [] statt array() der Aspekt des Releases, der am meisten verwendet werden wird. Das läppert sich.

    Der Wegfall von Altlasten ist natürlich zu begrüßen, ist aber nichts, mit dem wir nicht notgedrungen anderswie umzugehen gelernt hätten (z. B. error_reporting(-1);). Immerhin tut sich in der Hinsicht mal wieder etwas.

    Den Zuwachs an „Magie“ (siehe Ronald zwei Kommentare über diesem) mag ich ebenfalls nicht, auch wenn damit wohl in erster Linie Syntaxlücken geschlossen werden. Und, ja, nutzen muss man es ja nicht.

    @Ronald:

    The break and continue statements no longer accept variable arguments (e.g., break 1 + foo() * $bar;). Static arguments still work, such as break 2;.

    Ich hatte sozusagen bis zum Lesen des Changelogs keine Ahnung, dass der Quark überhaupt möglich war. Da wäre ich von selbst nicht drauf gekommen.

    mermshaus

    4 Mrz 12 at 17:19

  19. @Mermshaus: Ah, danke fuer den Hinweis. Die Aussage im Bezug auf break und continue war fuer mich oben nicht ganz eindeutig. So macht das jetzt Sinn.

    @Florian: Vor 10 Jahren haette ich gesagt „nun, mal sehen was passiert“. Heute kennen wir viele Dinge, die passiert sind. Ich gehe davon aus, dass Traits fuer haeufige Verstaendnisprobleme bei Refactoring-Iterationen sorgen werden. Da ist PHP so schon nicht gut drin. Zumindest macht es Code weniger lesbar.

    Ronald Kirschler

    4 Mrz 12 at 19:12

  20. Ich finde traits gerade im Zusammenhang mit sauberen Code super. Beispielsweise habe ich mehrere Komponenten, die alle auf die Datenbank gehen wollen. Anstatt diesen jeweils einen Setter zu spendieren, d.h. effektiv Copy&Paste zu machen, kann ich ein Trait erstellen und nutzen:

    trait HasDatabase {
      private $_database=NULL;
      public function getDatabase() {
        return $this->_database;
      }
      public function setDatabase($value) {
        $this->_database=$value;
        return $this;
      }
    }

    class MyModule extends BaseModule {
      use HasDatabase;
    }

    Find ich super nützlich, weil mein Module jetzt direkt lesbarer wird. Das kann ich natürlich auch für andere Komponenten wie Cache, Log, etc. nutzen und „steck“ mir meine Module aus Traits zusammen.

    Martin Kuckert

    5 Mrz 12 at 07:41

  21. Ich stelle jetzt mal folgende Behauptung auf: Es gibt kein Problem, welches man mit Traits sauberer lösen kann, als durch Vererbung und Delegation. Und es gibt keon Problem, welches man erst durch Traits lösen kann.

    Ronald Kirschler

    5 Mrz 12 at 09:19

  22. […] PHP 5.4.0 released! Neue Funktionen | PHP Gangsta – Der PHP Blog mit Praxisbezug […]

  23. Hallo,

    eine bescheidene Frage aus dem Off-Topic-Bereich. Gibt es eine Möglichkeit um in multidimensionalen Arrays direkt auf einen bestimmten Schlüssel zuzugreifen, außerhalb des Anwendens von Schleifen? Mit array_reduce bleiben die Schlüssel nicht erhalten.

    Beispiel:
    $var[0][‚value‘] = ‚foo‘;
    $var[1][‚value‘] = ‚bar‘;
    $var[2][‚value‘] = ‚var‘;
    $var[‚lorem‘][‚value‘] = ‚lorem‘;
    $var[‚ipsum‘][‚value‘] = ‚ipsum‘;
    $values = getValueOfMultiArrayByKey($var, ‚value‘);

    erwünschter Rückgabewert:
    Array
    (
    [0] => foo
    [1] => bar
    [2] => var
    [lorem] => lorem
    [ipsum] => ipsum
    )

    Vielleicht gibt es eine Variante wie $var[][‚value‘] oder $var[*][‚value‘] in einer der zukünftigen Versionen von PHP.

    php

    6 Mrz 12 at 13:29

  24. Ich stelle jetzt mal folgende Behauptung auf: Es gibt kein Problem, welches man mit Traits sauberer lösen kann, als durch Vererbung und Delegation. Und es gibt keon Problem, welches man erst durch Traits lösen kann.

    Nein, das stimmt so nicht. Traits verfolgen ein anderes Konzept als Vererbung, die sogenannte horizontale Wiederverwendung. Es sind also zwei verschiedene Ansätze: Vererbung implementiert „ist ein“-Beziehungen, Traits dienen lediglich der Code-Wiederverwendung. Wenn du bisher Vererbung zur Code-Wiederverwendung genutzt hast, hast du sie streng genommen falsch genutzt…

    Martin Kuckert

    6 Mrz 12 at 15:46

  25. Vor allem kann man auch mehrere Traits in einer Klasse benutzen. Mehrfachvererbung gibt es ja nicht in PHP.

    Wie Martin schon sagte, Vererbung ist eine „ist ein“-Beziehung, Traits sind eher eine „kann folgendes“-Beziehung.

    Somit kann man sich recht einfach eine Klasse „zusammenbauen“ die 5 Traits benutzt, und eine andere Klasse nutzt auch 2 dieser Traits plus 2 andere. Mit Vererbung wird das echt eklig, es sei denn man hat für jede Kombination eine Zwischenklasse gebaut, oder eine große Gott-Klasse von der alle erben.

    Traits haben schon ihre Daseinsberechtigung und mit ihnen kann man einige Probleme besser lösen als vorher, aber sie können auch falsch benutzt werden, es gibt eben auch Situationen wo man keine Traits benutztn sollte sondern lieber mit Vererbung arbeiten sollte.
    Aber dazu fehlen aktuell Best Practices, Beispiele und Code Smells, damit wir alle besser einschätzen können wofür das eine und wofür das andere gut ist, und wie man es richtig einsetzt.

    Michael Kliewe

    6 Mrz 12 at 16:09

  26. @martin: Streng genommen ist es falsch eine Klasse an eine konkrete Implementierung einer sach-fremden Funktionalität zu binden. Dafuer gibt es ja dependency injection. Und wenn man mit DI nicht weiter kommt, dann hat man ein architektonisches Problem. Idr zu lösen durch: http://en.wikipedia.org/wiki/Separation_of_concerns

    Es gibt kein Problem, welches man erst durch Traits lösen kann.

    @php: Ich habe in meinem Framework da ne Klasse fuer. Die kann eigentlich noch viel mehr. Ich habe da gerade mal das wichtigste rausgeholt und in eine statische Klasse gepackt: http://pastebin.com/0KXY5gCY

    Ronald Kirschler

    6 Mrz 12 at 16:16

  27. @Ronald: Korrigiere mich, wenn ich falsch liege, aber mein HasDatabase-Beispiel weiter oben macht doch durchaus Sinn mit Traits. Ich nutze DI ausgiebigst, aber dennoch gibt es Codeteile, die in Traits gekapselt und so sinnvoll wiederverwendet werden können.

    Martin Kuckert

    6 Mrz 12 at 16:19

  28. Sehe das wie Martin.

    Ein nützliches Anwendungsbeispiel für Traits wäre wohl sowas wie „Configurable“. Ein Trait das Methoden wie „getConfig()“, „setConfig($config)“, „getConfigValue($key“), „setConfigValue($key, $value)“, etc. einführt.

    Das ist auch keine Verletzung von SoC.

    Phil

    6 Mrz 12 at 16:30

  29. @martin: Dein Beispiel sagt zuwenig darueber aus, was du da machen willst. Warum sollte ein „Modul“ (Was immer das in diesem Fall auch ist) eine Datenbank „haben“? Wenn du in einem MVC-Modell denkst, und das „Modul“ ein Controller ist, dann delegierst du ja jede Form von Interaktion mit einer Datenquelle an ein Model, eine Factory, ein Repository, o.Ae. In einem Modell greift man dann idealerweise auf eine abstrakte Datenquelle, zumindest aber auf eine abstrakte Datenbank zu. Die konkrete Datenbank kann ja von einem DI-Container verborgen werden, welcher wiederzum beim Instanziieren der Modell-Klasse als Referenz uebergeben werden kann… Das alles gibt es schon lange.

    @phil: Klar, kann man machen. Ich sehe hier aber eine verletzung von Soc. Warum sollte man über z.B. einen Controller direkt die Konfiguration verändern können? Das sollte doch keine Eigenschaft eines Controllers sein, oder doch? Aber wie kommen die Methoden dann an den Konfigurationsprovider? Du musst beim Initialisieren der Klasse wissen, dass die Klasse das noch irgendwie brauchen wird und diese Abhaengigkeit zusätzlich aufloesen. Das Problem kann man auch ohne Traits und ohne Codeduplikation loesen.

    Ronald Kirschler

    6 Mrz 12 at 16:41

  30. Die Klasse verändert nicht DIE Konfiguration. Die Klasse besitzt eine Konfiguration. Das betrift Formulare, Filter, Validatoren, eigentlich alle möglichen Library-Klassen, Services, usw. Wenn meine gesamte Library ein einheitliches (!= überall vorhandenes) Interface für die Konfiguration hat, ist das sehr angenehm.

    Und zu deiner Antwort an Martin: Wenn du den DI-Container umherschiebst, landest du bei einem Service Locator. Das will man eigentlich nicht, denn dann ist die Klasse für ihre Abhängingkeiten wieder selbst verantwortlich (sie muss den SL nach bestimmten Dingen fragen, bei DI sind diese Dinge von aussen übergeben). Weiter können ja mit Traits auch nur „Contracts“ eingebunden werden. Traits müssen keine (Business-)Logik enthalten, wenn man das nicht wünscht.

    Phil

    6 Mrz 12 at 18:13

  31. @phil: Anders als bei GOTO, sehe ich in Traits durchaus positives Potential. Anders als bei GOTO sehe ich aber auch ein sehr großes Problempotential. Ich gehe auch davon aus, dass eben deswegen Traits nicht in groesseren Projekten zum Einsatz kommen werden.

    Entwicklung:
    Stand heute sind IDEs noch nicht in der Lage, alles 100%ig korrekt aufzuschluesseln (mein ZendStudio Update auf 9.0.2 fuehrt dazu, dass ZS wieder Warnings fuer private Eigenschaften wirft, obwohl alles korrekt ist, typehinting und foreach, etc). Traits machen die Entwicklung noch etwas trueber, weil jetzt noch ein Layer hinzukommt, den der Interpreter zwar problemlos durchlaeuft. Der Entwickler aber auch? 6 Monate, nachdem er den Code geschreiben hat? Oder gar den Code eines anderen? Beim initialen Erstellen eine Anwendung sollte das noch kein Problem sein. Aber Refactoring macht auch ohne Traits schon nur wenig Spass in PHP.

    Unittesting:
    Traits lassen sich nur mit Hilfe einer Wirtsklasse testen. Damit kann man dann auch nur das Zusammenspiel der Wirtsklasse und den zugeordneten Traits testen. Das Problem ist nur, dass Traits die Hierachiestruktur von Methoden in Klassen beeinflussen und dabei leicht Querschlaege verursachen koennen. Wenn man eine neue Methode in einer Basisklasse einfuehrt und diese dann erbt, dann fuehrt das erstmal zu keinem Problem. Fuehrt man aber eine neue Methode in einem Trait ein, laeuft man immer Gefahr, dass man damit unbeabsichtigt eine bereits vorhandene Methode eines Interfaces ueberlaed und damit wahrscheinlich auch dessen Zweck veraendert. Das kann zu schwer testbaren Verhaltensaenderungen fuehren, die es bei klassischer Vererbung so nicht gibt. Jetzt kann man fragen, wo das Problem liegt. Man sollte doch eh jede Klasse testen. Denn ungtesteter Code ist ja defekter Code. Super: Dann habe ich die Lines, die ich mir durch die Traits gespart habe in den Unittests stehen. Oder erweitere ich meine Unittests dann auch wieder durch Traits, die die Traits testen? Angenommen, die Methoden, die die Traits so mitbringen bewirken immer das gleiche, geht das. Im Falle des Konfigurationsexamples ist das wohl nicht so.

    Zu dem anderen:
    Was die Konfiguration betrifft fallen mir gerade nur wenige Beispiele ein, bei denen es Sinn macht, einerseits formfreie Daten zu uebergeben (ein generisches Konfigurationsinterface wirft keine Exception, wenn man einen Wert falsch setzt (Schreibfehler), oder einen Wert falsch uebergibt (Datenfehler)), andererseits die Konfiguration nach Initialisieren des Objekts vrzunehmen. Man kann so arbeiten, dass man nie nachtraeglich konfigurieren muss. Ich lesen haeufig, dass nachtraegliche Konfiguration ohnehin haeufig zu Fehlern fuehrt und vermieden werden sollte.

    Validatoren sind eigentlich immer sehr Datenbezogen. Beispiel UI-Elemente. Nehmen wir an, wir haben ein Eingabefeld fuer Dezimalzahlen und wollen jetzt ein Feld für Ganzzahlen und Geldbetraege (ich habe jetzt Absichtlich nicht „Waehrungen“ geschrieben) einzufuehren. Wenn das Dezimalzahlelement eine geschuetzte Methode „setDecimalPrecision“ hat, kann man die beiden anderen Klassen davon Ableiten lassen und Ihre Dezimalgenauigkeit durchreichen (0 und 2). Gerade bei Validierung wuerde vertikale Vererbung immer mehr Sinn machen, als Horizontale. Es mag Faelle von Validierung geben, an die ich gerade nicht denke und die besser zu Traits passen.

    Ich bin ueberzeugt, wenn man durch Traits Codeduplikation verringern kann, dann sollte man die Struktur der Applikation generell ueberdenken.

    Ronald Kirschler

    6 Mrz 12 at 20:46

  32. Zum Konfigurationsbeispiel: Man kann die Keys eine Config-Arrays z.b. auf Methoden mappen (wie dies das Zend Framework an einigen Stellen macht). Also für die Config array('decimalPrecision' => 6) könnte die Methode setDecimalPrecision(6) aufgerufen werden. Wenn die Methode nicht existiert, könnte der Trait eine Exception werfen. Es gibt da also durchaus Wege.

    Bezüglich Testing sind das keine neuen Probleme. Auch abstrakte Klassen müssen gemockt werden. Das der Aufwand natürlich grösser ist und man sich grosse Probleme machen kann, ist klar, aber das bringt jedes genutzte Sprachelement mit sich. Im Grossteil der Fälle wird es ausreichen nur den Trait zu testen *denk*. Wenn man da Angst hat, kann man sich ja selbst die Richtlinie setzen, dass Traits nicht „überladen“ werden dürfen.

    Ich denke wir werden uns hier nicht einig, was auch völlig ok ist. Jeder soll die Features (und die Sprache) nutzen, die er für brauchbar hält. Schlussendlich werden die grösseren Frameworks auch hier eine Richtung vorgeben, in die sich hoffentlich die meisten Entwickler ebenfalls bewegen werden. Mal gucken wie die wird.

    PS: PhpStorm 4 EAP hat schon ein bisschen Traits-Support [1].

    [1] http://blog.jetbrains.com/webide/2012/02/phpstorm-webstorm-4-0-eap-114-282/

    Phil

    6 Mrz 12 at 21:08

  33. @Ronald: Trenne dich von den Namen „Modul“ und „Datenbank“. Meinetwegen kannst du diese gerne durch „Controller“ und „Repository“ ersetzen. Wenn du jetzt in mehreren Controllern dein Repository nutzt, schreibst du jedes mal die gleichen – je nach DI-Container – Konstruktor oder Setter-Methoden. Und die Setter inkl. Property und dann auch gerne mit Getter-Methode kannst du schön in einen Trait packen und jedem Controller den Trait „HasRepository“ hinzufügen.

    Haltet mich auf, wenn ich falsch liege, aber ich finde das durchaus praktisch. Natürlich kannst du Traits auch falsch nutzen und dir deine Vererbung kaputt machen. Richtig verwendet kann es dir deine Vererbung aus Gründen der Code-Wiederverwendbarkeit aber auch aufräumen.

    Ich schiele da zum Beispiel in Richtung Doctrine 1 und die Klasse Doctrine_Configurable. Die Klasse stellt der Table-, Manager- und Connection-Klasse Methoden wie setAttribute, getParams, etc. zur Verfügung. Die Beziehung „Eine Tabelle ist ein konfigurierbares Etwas“ ist unschön. Wie Michael schon sagte, dann doch eher „Eine Tabelle kann folgendes: konfiguriert werden“.

    @Phil: Dass die IDEs keine Traits unterstützen darf aber doch nicht der Grund sein, diese nicht zu verwenden. Warte ein wenig und die nächste Version unterstützt diese sicher.

    Martin Kuckert

    7 Mrz 12 at 07:37

  34. @Martin: Da hast du dich wohl verlesen. 🙂 Ich hab nur angemerkt, dass PhpStorm bereits Traits unterstützt.

    Phil

    7 Mrz 12 at 09:58

  35. @Phil: Huppala, das kam auch von Ronald und bezog sich aufs Zend Studio.

    Martin Kuckert

    7 Mrz 12 at 10:00

  36. […] PHP 5.4.0 released! Neue Funktionen | PHP Gangsta – Der PHP Blog mit Praxisbezug [Tags: release php 5 4 0 php ] […]

  37. […] Ansonsten gibt es nun Traits, short_open_tag (z.B. <?=$output?> statt <?php echo $output; ?>) ist nun immer verfügbar, callable ist ein neuer Typehint und Binärzahlen können direkt zugewiesen werden. Und das ist noch nicht alles. Weiterführende Infos dazu findet ihr bei PHP Gangsta und codenaschereien.de. […]

Leave a Reply

You can add images to your comment by clicking here.