PHP 7: Typsichere Arrays von Objekten

Mit PHP 7 kann man sich dazu entscheiden, typsichereren Code zu schreiben als zuvor, dank skalaren Type Hints und Rückgabetypen.

function repeat(string $text, int $times) : string;

Aber was ist mit Arrays? Es gibt immer noch nur den generischen “array” Type Hint, man kann nicht spezifizieren was das Array enthält. Für die IDE kann man PhpDoc Kommentare hinzufügen:

/**
 * @return User[]
 */
function allUsers() : array;

Jetzt können IDEs wie PhpStorm mit Code-Vervollständigung für Elemente des zurückgegebenen Arrays helfen. Aber wir können nicht von Prüfungen zur Laufzeit profitieren, wie mit echten Type Hints.

Für Argumente gibt es einen partiellen Workaround mit variadischen Argumenten. Nehmen wir die folgende Funktion:

/**
 * @param User[] $users
 */
function deleteUsers(array $users);

Mit variadischen Argumenten können wir sie umschreiben zu:

function deleteUsers(User ...$users);

Die Benutzung ändert sich auch, zu deleteUsers(...$users); Bei diesem Aufruf wird das Argument $users in einzelne Variablen “unpacked”, und in der Methode selbst wieder in ein Array $users “packed”. Jedes Element wird dabei auf den Typ User validiert. $users kann auch ein Iterator sein, er wird dann beim Aufruf in ein Array konvertiert.

Leider gibt es keinen entsprechenden Workaround für Rückgabetypen, und es funktioniert nur mit dem letzten Argument.

Siehe auch: Type hinting in PHP 7 – array of objects

Ich nutze diese Technik oft in PHP 7 Code, aber es gibt noch eine andere, die die genannten Schwächen nicht hat:
Continue reading “PHP 7: Typsichere Arrays von Objekten”

Sinnvolle Namespaces in PHP

Eine übliche Konvention für Namespaces in PHP ist es, mit Vendor\Package zu beginnen, groß geschrieben (CamelCase StudlyCaps) mit “vendor” und “package” analog zum Composer Package Namen.

Es gibt allerdings eine schlechte Angewohnheit, die ich häufig sehe, vermutlich aus alten ZF1 und Pear Tagen, wo jedes Wort im Klassennamen ein neuer Sub-Namespace ist (und ein neues Unterverzeichnis), oder Kind-Klassen in einen Namespace mit dem Namen der Elternklasse platziert werden. All das führt zu tief geschachtelten Namespaces und Klassennamen, die keine Bedeutung ohne ihren Namespace haben.

Beispiele aus Zend Framework 1 (Pseudo Namespaces):

  • Zend_Db_Table_Row_Abstract ist eine abstrakte Basis-Klasse für Zend_Db_Table_Row, und repräsentiert eine Zeile in einer Datenbanktabelle. Es gibt auch noch Zend_Db_Table und Zend_Db.
  • Zend_Pdf_FileParser_Font_OpenType_TrueType ist ein Parser für True Type Schriftdateien. Die Klasse erbt von Zend_Pdf_FileParser_Font_OpenType, die wiederum von Zend_Pdf_FileParser_Font erbt, die von Zend_Pdf_FileParser erbt.

Und ein aktuelles Beispiel aus Magento 2:

  • Magento\Catalog\Model\Product\Option\Type\File\Validator – Ein Validator für Produkt-Optionen vom Typ “File”

Continue reading “Sinnvolle Namespaces in PHP”

PDF Generierung in Magento 2

magento-pdf-layout

Die Core Methoden zum Generieren von PDF Dateien sind auch in Magento 2 eher unflexibel. Eine Alternative sind Tools zum Konvertieren von HTML zu PDF.

In unserem aktuellen Magento 2 Projekt, das wir (integer_net) gemeinsam mit der Stämpfli AG entwickeln, gibt es die Anforderung, aus ausgewählten Produkten dynamisch einen PDF Katalog zu erstellen, der im Prinzip das gleiche Layout hat wie die Produktlisten im Shop. Die PDF aufgrund von HTML zu generieren lag also nahe.

In diesem Beitrag stelle ich unsere Lösung vor, die wkhtmltopdf mit dem Magento Layout integriert. Am Ende gibt es auch einen Link zum Basismodul auf Github.

Weiterlesen auf webguys.de

PHP: class_alias verwenden um Klassen rückwärtskompatibel zu verschieben/umzubenennen

Manchmal möchte man eine Klasse umbenennen oder sie in einen anderen Namespace verschieben. Aber sobald sie irgendwo außerhalb des Packages verwendet wurde, ist das eine nicht abwärtskompatible Änderung und sollte nicht leichtfertig vorgenommen werden.

Zum Glück gibt es in PHP eine Möglichkeit, beide Klassen gleichzeitig zu nutzen, die alte und die neue, um die alte als “deprecated” zu markieren aber weiterhin nutzen zu können: class_alias().

Wie man class_alias() nutzt, ohne Probleme mit dem Autoloading zu bekommen

Sagen wir, die alte Klasse ist OldClass und wir wollen sie zu NewClass umbenennen.

Als erstes benennen wir die Klasse um und schieben sie von OldClass.php in eine neue Datei NewClass.php.
Continue reading “PHP: class_alias verwenden um Klassen rückwärtskompatibel zu verschieben/umzubenennen”