Verbesserung des WordPress-Codes mit modernem PHP
Veröffentlicht: 2022-03-10WordPress wurde vor fünfzehn Jahren geboren, und da es historisch gesehen die Abwärtskompatibilität bewahrt hat, konnten neuere Versionen seines Codes die neuesten Funktionen, die von den neueren Versionen von PHP angeboten werden, nicht vollständig nutzen. Während die neueste Version von PHP 7.3.2 ist, bietet WordPress immer noch Unterstützung bis PHP 5.2.4.
Doch diese Zeiten sind bald vorbei! WordPress wird seine Mindestunterstützung für PHP-Versionen aktualisieren und im April 2019 auf PHP 5.6 und im Dezember 2019 auf PHP 7 aufsteigen (wenn alles nach Plan läuft). Wir können dann endlich damit beginnen, die imperativen Programmierfähigkeiten von PHP zu nutzen, ohne befürchten zu müssen, die Websites unserer Kunden zu beschädigen. Hurra!
Da die fünfzehn Jahre funktionalen Codes von WordPress beeinflusst haben, wie Entwickler mit WordPress gebaut haben, sind unsere Websites, Themen und Plugins möglicherweise mit nicht optimalem Code übersät, der gerne ein Upgrade erhalten kann.
Dieser Artikel besteht aus zwei Teilen:
- Die wichtigsten neuen Funktionen
Weitere Funktionen wurden den PHP-Versionen 5.3, 5.4, 5.5, 5.6 und 7.0 hinzugefügt (beachten Sie, dass es kein PHP 6 gibt) und wir werden die relevantesten untersuchen. - Bessere Software entwickeln
Wir werden uns diese Funktionen genauer ansehen und wie sie uns helfen können, bessere Software zu entwickeln.
Beginnen wir damit, die „neuen“ Funktionen von PHP zu erkunden.
Klassen, OOP, SOLID und Design Patterns
Klassen und Objekte wurden zu PHP 5 hinzugefügt, sodass WordPress diese Funktionen bereits nutzt, jedoch nicht sehr umfangreich oder umfassend: Das Paradigma der Codierung in WordPress ist hauptsächlich funktionale Programmierung (Durchführen von Berechnungen durch Aufrufen von Funktionen ohne Anwendungsstatus) anstelle von Objekten -orientierte Programmierung (OOP) (Durchführen von Berechnungen durch Manipulieren des Zustands von Objekten). Daher beschreibe ich auch Klassen und Objekte und wie man sie durch OOP verwendet.
OOP ist ideal für die Erstellung modularer Anwendungen: Klassen ermöglichen die Erstellung von Komponenten, von denen jede eine bestimmte Funktionalität implementieren und mit anderen Komponenten interagieren kann, und durch ihre gekapselten Eigenschaften und Vererbung eine Anpassung bieten kann, wodurch ein hohes Maß an Wiederverwendbarkeit des Codes ermöglicht wird. Infolgedessen ist die Anwendung billiger zu testen und zu warten, da einzelne Funktionen von der Anwendung isoliert und eigenständig behandelt werden können; Auch die Produktivität steigt, da der Entwickler auf bereits entwickelte Komponenten zurückgreifen kann und nicht für jede Anwendung das Rad neu erfinden muss.
Eine Klasse hat Eigenschaften und Funktionen, die sichtbar gemacht werden können, indem private
(nur innerhalb der definierenden Klasse zugänglich), protected
(innerhalb der definierenden Klasse und ihrer Vorfahren- und erbenden Klassen zugänglich) und public
(von überall zugänglich) verwendet werden. Innerhalb einer Funktion können wir auf die Eigenschaften der Klasse zugreifen, indem wir ihren Namen $this->
:
class Person { protected $name; public function __construct($name) { $this->name = $name; } public function getIntroduction() { return sprintf( __('My name is %s'), $this->name ); } }
Eine Klasse wird durch das Schlüsselwort new
in ein Objekt instanziiert, wonach wir über ->
auf ihre Eigenschaften und Funktionen zugreifen können:
$person = new Person('Pedro'); echo $person->getIntroduction(); // This prints "My name is Pedro"
Eine erbende Klasse kann die public
und protected
Funktionen ihrer Vorfahrenklassen überschreiben und auf die Vorfahrenfunktionen zugreifen, indem sie ihnen parent::
voranstellt:
class WorkerPerson extends Person { protected $occupation; public function __construct($name, $occupation) { parent::__construct($name); $this->occupation = $occupation; } public function getIntroduction() { return sprintf( __('%s and my occupation is %s'), parent::getIntroduction(), $this->occupation ); } } $worker = new WorkerPerson('Pedro', 'web development'); echo $worker->getIntroduction(); // This prints "My name is Pedro and my occupation is web development"
Eine Methode kann abstract
gemacht werden, was bedeutet, dass sie von einer erbenden Klasse implementiert werden muss. Eine Klasse, die eine abstract
Methode enthält, muss selbst abstract
gemacht werden, was bedeutet, dass sie nicht instanziiert werden kann; nur die Klasse, die die abstrakte Methode implementiert, kann instanziiert werden:
abstract class Person { abstract public function getName(); public function getIntroduction() { return sprintf( __('My name is %s'), $this->getName() ); } } // Person cannot be instantiated class Manuel extends Person { public function getName() { return 'Manuel'; } } // Manuel can be instantiated $manuel = new Manuel();
Klassen können auch static
Methoden und Eigenschaften definieren, die unter der Klasse selbst leben und nicht unter einer Instanziierung der Klasse als Objekt. Auf diese wird über self::
innerhalb der Klasse und über den Namen der Klasse + ::
von außerhalb zugegriffen:
class Factory { protected static $instances = []; public static function registerInstance($handle, $instance) { self::$instances[$handle] = $instance; } public static function getInstance($handle) { return self::$instances[$handle]; } } $engine = Factory::getInstance('Engine');
Um das Beste aus OOP herauszuholen, können wir die SOLID-Prinzipien verwenden, um eine solide und dennoch leicht anpassbare Grundlage für die Anwendung zu schaffen, und Muster entwerfen, um spezifische Probleme auf erprobte Weise zu lösen. Entwurfsmuster sind standardisiert und gut dokumentiert, sodass Entwickler verstehen können, wie verschiedene Komponenten in der Anwendung miteinander in Beziehung stehen, und eine Möglichkeit bieten, die Anwendung in einer geordneten Weise zu strukturieren, wodurch die Verwendung globaler Variablen (z. B. global $wpdb
) vermieden wird. die die globale Umwelt verschmutzen.
Namensräume
Namespaces wurden zu PHP 5.3 hinzugefügt, daher fehlen sie derzeit vollständig im WordPress-Kern.
Namespaces ermöglichen es, die Codebasis strukturell zu organisieren, um Konflikte zu vermeiden, wenn verschiedene Elemente denselben Namen haben – ähnlich wie Betriebssystemverzeichnisse, die es ermöglichen, verschiedene Dateien mit demselben Namen zu haben, solange sie in verschiedenen Verzeichnissen gespeichert sind. Namensräume machen den gleichen Kapselungstrick für PHP-Elemente (wie Klassen, Merkmale und Schnittstellen), um Kollisionen zu vermeiden, wenn verschiedene Elemente denselben Namen haben, indem sie in verschiedenen Namensräumen platziert werden.
Namespaces sind ein Muss bei der Interaktion mit Bibliotheken von Drittanbietern, da wir nicht kontrollieren können, wie ihre Elemente benannt werden, was zu potenziellen Kollisionen führt, wenn Standardnamen wie „Datei“, „Logger“ oder „Uploader“ für unsere Elemente verwendet werden. Darüber hinaus verhindern Namespaces auch innerhalb eines einzelnen Projekts, dass Klassennamen extrem lang werden, um Konflikte mit anderen Klassen zu vermeiden, die zu Namen wie „MyProject_Controller_FileUpload“ führen könnten.
Namensräume werden mit dem Schlüsselwort namespace
definiert (das unmittelbar nach dem öffnenden <?php
in die Zeile eingefügt wird) und können sich über mehrere Ebenen oder Unternamensräume erstrecken (ähnlich wie mehrere Unterverzeichnisse, in denen eine Datei abgelegt wird), die durch ein \
getrennt sind:
<?php namespace CoolSoft\ImageResizer\Controllers; class ImageUpload { }
Um auf die obige Klasse zuzugreifen, müssen wir ihren Namen vollständig qualifizieren, einschließlich ihres Namensraums (und beginnend mit \
):
$imageUpload = new \CoolSoft\ImageResizer\Controllers\ImageUpload();
Oder wir können die Klasse auch in den aktuellen Kontext importieren, wonach wir die Klasse direkt über ihren Namen referenzieren können:
use CoolSoft\ImageResizer\Controllers\ImageUpload; $imageUpload = new ImageUpload();
Durch die Benennung von Namespaces nach etablierten Konventionen können wir zusätzliche Vorteile erzielen. Durch Befolgen der PHP-Standardempfehlung PSR-4 kann die Anwendung beispielsweise den automatischen Lademechanismus von Composer zum Laden von Dateien verwenden, wodurch die Komplexität verringert und eine reibungslose Interoperabilität zwischen Abhängigkeiten hinzugefügt wird. Diese Konvention sieht vor, den Herstellernamen (z. B. den Namen der Firma) als obersten Subnamensraum aufzunehmen, optional gefolgt vom Paketnamen und erst dann gefolgt von einer internen Struktur, in der jeder Subnamensraum einem gleichnamigen Verzeichnis entspricht. Das Ergebnis bildet 1 zu 1 den physischen Speicherort der Datei auf dem Laufwerk mit dem Namespace des in der Datei definierten Elements ab.
Züge
Traits wurden zu PHP 5.4 hinzugefügt, daher fehlen sie derzeit vollständig im WordPress-Kern.
PHP unterstützt die einfache Vererbung, sodass eine Unterklasse von einer einzelnen Elternklasse abgeleitet wird und nicht von mehreren. Daher können Klassen, die sich nicht voneinander erweitern, Code nicht durch Klassenvererbung wiederverwenden. Traits ist ein Mechanismus, der eine horizontale Verhaltenskomposition ermöglicht und es ermöglicht, Code zwischen Klassen wiederzuverwenden, die in verschiedenen Klassenhierarchien leben.
Ein Merkmal ähnelt einer Klasse, kann jedoch nicht alleine instanziiert werden. Stattdessen kann man sich den in einem Merkmal definierten Code als „kopiert und eingefügt“ in die Kompositionsklasse zur Kompilierzeit vorstellen.
Eine Eigenschaft wird mit dem Schlüsselwort trait
definiert, danach kann sie mit dem Schlüsselwort use
in jede Klasse importiert werden. Im folgenden Beispiel können zwei völlig unabhängige Klassen Person
und Shop
denselben Code über eine Eigenschaft Addressable
wiederverwenden:
trait Addressable { protected $address; public function getAddress() { return $this->address; } public function setAddress($address) { $this->address = $address; } } class Person { use Addressable; } class Shop { use Addressable; } $person = new Person('Juan Carlos'); $person->setAddress('Obelisco, Buenos Aires');
Eine Klasse kann auch aus mehr als einem Merkmal bestehen:
trait Exportable { public class exportToCSV($filename) { // Iterate all properties and export them to a CSV file } } class Person { use Addressable, Exportable; }
Merkmale können unter anderem auch aus anderen Merkmalen zusammengesetzt sein, abstrakte Methoden definieren und einen Konfliktlösungsmechanismus bieten, wenn zwei oder mehr zusammengesetzte Merkmale denselben Funktionsnamen haben.
Schnittstellen
Schnittstellen wurden PHP 5 hinzugefügt, sodass WordPress bereits von diesem Feature Gebrauch macht, allerdings äußerst sparsam: Der Kern umfasst insgesamt weniger als zehn Schnittstellen!
Schnittstellen ermöglichen das Erstellen von Code, der angibt, welche Methoden implementiert werden müssen, ohne jedoch definieren zu müssen, wie diese Methoden tatsächlich implementiert werden. Sie sind nützlich, um Verträge zwischen Komponenten zu definieren, was zu einer besseren Modularität und Wartbarkeit der Anwendung führt: Eine Klasse, die eine Schnittstelle implementiert, kann eine Blackbox mit Code sein, und solange sich die Signaturen der Funktionen in der Schnittstelle nicht ändern, die Code kann nach Belieben aktualisiert werden, ohne dass Breaking Changes erzeugt werden, was dazu beitragen kann, die Anhäufung technischer Schulden zu verhindern. Darüber hinaus können sie dazu beitragen, die Herstellerabhängigkeit zu verringern, indem sie es ermöglichen, die Implementierung einiger Schnittstellen auf die eines anderen Anbieters auszutauschen. Folglich ist es zwingend erforderlich, die Anwendung anhand von Schnittstellen anstelle von Implementierungen zu codieren (und durch Abhängigkeitsinjektion zu definieren, welche die tatsächlichen Implementierungen sind).
Schnittstellen werden mit dem Schlüsselwort interface
definiert und müssen nur die Signatur ihrer Methoden auflisten (d. h. ohne dass ihr Inhalt definiert ist), die public
sichtbar sein müssen (standardmäßig wird es auch öffentlich, wenn kein Schlüsselwort für die Sichtbarkeit hinzugefügt wird):
interface FileStorage { function save($filename, $contents); function readContents($filename); }
Eine Klasse definiert, dass sie die Schnittstelle durch das Schlüsselwort implements
:
class LocalDriveFileStorage implements FileStorage { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } }
Eine Klasse kann mehr als eine Schnittstelle implementieren, die durch , getrennt ,
:
interface AWSService { function getRegion(); } class S3FileStorage implements FileStorage, AWSService { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } function getRegion() { return 'us-east-1'; } }
Da eine Schnittstelle die Absicht erklärt, was eine Komponente tun soll, ist es äußerst wichtig, Schnittstellen angemessen zu benennen.
Schließungen
Closures wurden zu PHP 5.3 hinzugefügt, daher fehlen sie derzeit vollständig im WordPress-Kern.
Closures ist ein Mechanismus zum Implementieren anonymer Funktionen, der dabei hilft, den globalen Namensraum von einmalig verwendeten (oder selten verwendeten) Funktionen zu befreien. Technisch gesehen sind Closures Instanzen der Klasse Closure
, aber in der Praxis können wir uns dieser Tatsache höchstwahrscheinlich ohne Schaden glücklicherweise nicht bewusst sein.
Vor Closures mussten wir immer, wenn wir eine Funktion als Argument an eine andere Funktion übergeben, die Funktion im Voraus definieren und ihren Namen als Argument übergeben:
function duplicate($price) { return $price*2; } $touristPrices = array_map('duplicate', $localPrices);
Bei Closures kann bereits eine anonyme (also ohne Namen) Funktion direkt als Parameter übergeben werden:
$touristPrices = array_map(function($price) { return $price*2; }, $localPrices);
Closures können Variablen über das Schlüsselwort use
in ihren Kontext importieren:
$factor = 2; $touristPrices = array_map(function($price) use($factor) { return $price*$factor; }, $localPrices);
Generatoren
Generatoren wurden zu PHP 5.5 hinzugefügt, daher fehlen sie derzeit vollständig im WordPress-Kern.
Generatoren bieten eine einfache Möglichkeit, einfache Iteratoren zu implementieren. Ein Generator ermöglicht das Schreiben von Code, der foreach
verwendet, um über einen Datensatz zu iterieren, ohne dass ein Array im Speicher erstellt werden muss. Eine Generatorfunktion ist dasselbe wie eine normale Funktion, mit der Ausnahme, dass sie, anstatt einmal yield
, so oft zurückgeben kann, wie es nötig ist, um die Werte bereitzustellen, über die iteriert werden soll.
function xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } foreach (xrange(1, 9, 2) as $number) { echo "$number "; } // This prints: 1 3 5 7 9
Deklarationen von Argument- und Rückgabetypen
Verschiedene Argumenttyp-Deklarationen wurden in verschiedenen Versionen von PHP eingeführt: WordPress kann bereits Schnittstellen und Arrays deklarieren (was es nicht tut: Ich habe kaum eine Instanz einer Funktion gefunden, die ein Array als Parameter im Kern deklariert, und keine Schnittstellen), und wird es tun bald in der Lage sein, Callables (hinzugefügt in PHP 5.4) und skalare Typen zu deklarieren: bool, float, int und string (hinzugefügt in PHP 7.0). Rückgabetypdeklarationen wurden PHP 7.0 hinzugefügt.
Argumenttypdeklarationen ermöglichen es Funktionen, zu deklarieren, welchen spezifischen Typ ein Argument haben muss. Die Validierung wird zum Zeitpunkt des Aufrufs ausgeführt und löst eine Ausnahme aus, wenn der Typ des Arguments nicht dem deklarierten entspricht. Rückgabetypdeklarationen sind dasselbe Konzept, sie geben jedoch den Werttyp an, der von der Funktion zurückgegeben wird. Typdeklarationen sind nützlich, um die Absicht der Funktion verständlicher zu machen und Laufzeitfehler durch Empfangen oder Zurückgeben eines unerwarteten Typs zu vermeiden.
Der Argumenttyp wird vor dem Argumentvariablennamen deklariert, und der Rückgabetyp wird nach den Argumenten deklariert, wobei :
:
function foo(boolean $bar): int { }
Typdeklarationen für skalare Argumente haben zwei Optionen: zwingend und streng. Wenn im Zwangsmodus der falsche Typ als Parameter übergeben wird, wird er in den richtigen Typ konvertiert. Beispielsweise erhält eine Funktion, die eine Ganzzahl für einen Parameter erhält, der eine Zeichenfolge erwartet, eine Variable vom Typ Zeichenfolge. Im strikten Modus wird nur eine Variable des genauen Deklarationstyps akzeptiert.
Der Zwangsmodus ist die Standardeinstellung. Um den strikten Modus zu aktivieren, müssen wir eine Declare-Anweisung hinzufügen declare
die mit der strict_types
Deklaration verwendet wird:
declare(strict_types=1); function foo(boolean $bar) { }
Neue Syntax und Operatoren
WordPress kann bereits Argumentlisten mit variabler Länge durch die Funktion func_num_args
. Ab PHP 5.6 können wir das Token ...
verwenden, um anzugeben, dass die Funktion eine variable Anzahl von Argumenten akzeptiert und diese Argumente als Array an die angegebene Variable übergeben werden:
function sum(...$numbers) { $sum = 0; foreach ($numbers as $number) { $sum += $number; } return $sum; }
Ab PHP 5.6 können Konstanten skalare Ausdrücke mit numerischen und Zeichenfolgenliteralen statt nur statischen Werten und auch Arrays beinhalten:
const SUM = 37 + 2; // A scalar expression const LETTERS = ['a', 'b', 'c']; // An array
Ab PHP 7.0 können Arrays auch mit define
definiert werden:
define('LETTERS', ['a', 'b', 'c']);
PHP 7.0 hat ein paar neue Operatoren hinzugefügt: den Null-Coalescing-Operator ( ??
) und den Spaceship-Operator ( <=>
).
Der Null-Coalescing-Operator ??
ist syntaktischer Zucker für den häufigen Fall, dass ein Ternär in Verbindung mit isset() verwendet werden muss. Es gibt seinen ersten Operanden zurück, falls er existiert und nicht NULL ist; andernfalls gibt es seinen zweiten Operanden zurück.
$username = $_GET['user'] ?? 'nobody'; // This is equivalent to: // $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
Der Spaceship-Operator <=>
wird zum Vergleichen zweier Ausdrücke verwendet und gibt -1, 0 oder 1 zurück, wenn der erste Operand kleiner, gleich oder größer als der zweite Operand ist.
echo 1 <=> 2; // returns -1 echo 1 <=> 1; // returns 0 echo 2 <=> 1; // returns 1
Dies sind die wichtigsten neuen Funktionen, die PHP in den Versionen 5.3 bis 7.0 hinzugefügt wurden. Die Liste der zusätzlichen neuen Funktionen, die in diesem Artikel nicht aufgeführt sind, finden Sie in der PHP-Dokumentation zur Migration von Version zu Version.
Als Nächstes analysieren wir, wie wir das Beste aus all diesen neuen Funktionen und den neuesten Trends in der Webentwicklung machen können, um bessere Software zu produzieren.
Empfehlungen für PHP-Standards
Die PHP-Standardempfehlungen wurden von einer Gruppe von PHP-Entwicklern aus gängigen Frameworks und Bibliotheken erstellt, die versuchten, Konventionen festzulegen, damit verschiedene Projekte nahtloser integriert werden können und verschiedene Teams besser zusammenarbeiten können. Die Empfehlungen sind nicht statisch: Bestehende Empfehlungen können verworfen und durch neue ersetzt werden, und es werden laufend neue veröffentlicht.
Die aktuellen Empfehlungen lauten wie folgt:
Gruppe | Empfehlung | Beschreibung |
---|---|---|
Codierungsstile Eine standardisierte Formatierung reduziert die kognitive Reibung beim Lesen von Code anderer Autoren | PSR-1 | Grundlegender Codierungsstandard |
PSR-2 | Coding-Styleguide | |
Automatisches Laden Autoloader beseitigen die Komplexität des Einschließens von Dateien, indem sie Namespaces Dateisystempfaden zuordnen | PSR-4 | Verbessertes automatisches Laden |
Schnittstellen Schnittstellen vereinfachen die gemeinsame Nutzung von Code zwischen Projekten, indem sie den erwarteten Verträgen folgen | PSR-3 | Logger-Schnittstelle |
PSR-6 | Caching-Schnittstelle | |
PSR-11 | Container-Schnittstelle | |
PSR-13 | Hypermedia-Links | |
PSR-16 | Einfacher Cache | |
HTTP Interoperable Standards und Schnittstellen für einen agnostischen Ansatz zur Handhabung von HTTP-Anforderungen und -Antworten, sowohl auf Client- als auch auf Serverseite | PSR-7 | HTTP-Nachrichtenschnittstellen |
PSR-15 | HTTP-Handler | |
PSR-17 | HTTP-Factories | |
PSR-18 | HTTP-Client |
Denken und programmieren Sie in Komponenten
Komponenten ermöglichen es, die besten Funktionen eines Frameworks zu nutzen, ohne an das Framework selbst gebunden zu sein. Beispielsweise wurde Symfony als Satz wiederverwendbarer PHP-Komponenten veröffentlicht, die unabhängig vom Symfony-Framework installiert werden können; Laravel, ein weiteres PHP-Framework, nutzt mehrere Symfony-Komponenten und hat einen eigenen Satz wiederverwendbarer Komponenten veröffentlicht, die von jedem PHP-Projekt verwendet werden können.
Alle diese Komponenten werden in Packagist, einem Repository öffentlicher PHP-Pakete, veröffentlicht und können über Composer, einen äußerst beliebten Abhängigkeitsmanager für PHP, problemlos zu jedem PHP-Projekt hinzugefügt werden.
WordPress sollte Teil eines solchen virtuosen Entwicklungszyklus sein. Leider ist der WordPress-Kern selbst nicht aus Komponenten aufgebaut (was durch das fast vollständige Fehlen von Schnittstellen belegt wird) und außerdem verfügt er nicht einmal über die Datei composer.json , die erforderlich ist, um die Installation von WordPress über Composer zu ermöglichen. Dies liegt daran, dass sich die WordPress-Community nicht geeinigt hat, ob WordPress die Abhängigkeit einer Website ist (in diesem Fall wäre die Installation über Composer gerechtfertigt) oder ob es die Website selbst ist (in diesem Fall ist Composer möglicherweise nicht das richtige Tool für den Job). .
Wenn WordPress meiner Meinung nach die nächsten fünfzehn Jahre relevant bleiben soll (zumindest WordPress als Backend -CMS), muss WordPress als Abhängigkeit einer Website erkannt und über Composer zur Installation bereitgestellt werden . Der Grund ist sehr einfach: Mit kaum einem einzigen Befehl im Terminal ermöglicht Composer, die Abhängigkeiten eines Projekts aus den Tausenden von Paketen zu deklarieren und zu installieren, die in Packagist veröffentlicht sind, wodurch es möglich wird, in kürzester Zeit extrem leistungsfähige PHP-Anwendungen zu erstellen, die von Entwicklern geliebt werden so arbeiten. Wenn sich WordPress nicht an dieses Modell anpasst, kann es die Unterstützung der Entwicklergemeinschaft verlieren und in Vergessenheit geraten, so wie FTP nach der Einführung von Git-basierten Bereitstellungen in Ungnade gefallen ist.
Ich würde argumentieren, dass die Veröffentlichung von Gutenberg bereits zeigt, dass WordPress eine Site-Abhängigkeit ist und nicht die Site selbst: Gutenberg behandelt WordPress als Headless-CMS und kann auch mit anderen Backend-Systemen arbeiten, wie Drupal Gutenberg beispielhaft zeigt. Daher macht Gutenberg deutlich, dass das CMS, das eine Website antreibt, austauschbar sein kann, daher sollte es als Abhängigkeit behandelt werden. Darüber hinaus soll Gutenberg selbst auf JavaScript-Komponenten basieren, die über npm veröffentlicht wurden (wie von Kern-Committer Adam Silverstein erklärt). Wenn also erwartet wird, dass der WordPress-Client seine JavaScript-Pakete über den npm-Paketmanager verwaltet, warum dann nicht diese Logik erweitern? das Backend, um PHP-Abhängigkeiten über Composer zu verwalten?
Nun die gute Nachricht: Sie müssen nicht warten, bis dieses Problem behoben ist, da es bereits möglich ist, WordPress als Abhängigkeit einer Website zu behandeln und über Composer zu installieren. John P. Bloch hat den WordPress-Kern in Git gespiegelt, eine composer.json-Datei hinzugefügt und in Packagist veröffentlicht, und Roots' Bedrock bietet ein Paket zur Installation von WordPress mit einer angepassten Ordnerstruktur mit Unterstützung für moderne Entwicklungstools und einer verbesserten Sicherheit. Und Themen und Plugins werden ebenfalls abgedeckt; Solange sie in den WordPress-Theme- und Plugin-Verzeichnissen aufgeführt sind, sind sie unter WordPress Packagist verfügbar.
Infolgedessen ist es eine sinnvolle Option, WordPress-Code zu erstellen, der nicht in Themen und Plugins, sondern in Komponenten denkt, ihn über Packagist für die Verwendung durch jedes PHP-Projekt verfügbar macht und zusätzlich als Themen verpackt und veröffentlicht Plugins für die spezifische Nutzung von WordPress. Wenn die Komponente mit WordPress-APIs interagieren muss, können diese APIs hinter einer Schnittstelle abstrahiert werden, die bei Bedarf auch für andere CMS implementiert werden kann.
Hinzufügen einer Template-Engine zur Verbesserung der Ansichtsebene
Wenn wir der Empfehlung folgen, in Komponenten zu denken und zu codieren, und WordPress als eine andere Abhängigkeit einer Website als die Website selbst behandeln, können unsere Projekte die von WordPress auferlegten Grenzen überwinden und Ideen und Tools aus anderen Frameworks importieren.
Das Rendern von HTML-Inhalten auf der Serverseite ist ein typisches Beispiel, das über einfache PHP-Vorlagen erfolgt. Diese Ansichtsebene kann durch die Template-Engines Twig (von Symfony) und Blade (von Laravel) erweitert werden, die eine sehr prägnante Syntax und leistungsstarke Funktionen bieten, die ihr einen Vorteil gegenüber einfachen PHP-Templates verschaffen. Insbesondere die dynamischen Blöcke von Gutenberg können leicht von diesen Template-Engines profitieren, da ihr Prozess zum Rendern des HTML des Blocks auf der Serverseite von der Template-Hierarchie-Architektur von WordPress entkoppelt ist.
Architekt Die Anwendung für den allgemeinen Gebrauch
Das Codieren anhand von Schnittstellen und das Denken in Komponenten ermöglicht es uns, eine Anwendung für den allgemeinen Gebrauch zu entwickeln und sie für die spezifische Verwendung anzupassen, die wir liefern müssen, anstatt nur für die spezifische Verwendung für jedes Projekt, das wir haben, zu codieren. Auch wenn dieser Ansatz kurzfristig kostspieliger ist (er erfordert zusätzliche Arbeit), zahlt er sich langfristig aus, wenn zusätzliche Projekte mit geringerem Aufwand geliefert werden können, indem nur eine allgemeine Anwendung angepasst wird.
Damit dieser Ansatz effektiv ist, müssen die folgenden Überlegungen berücksichtigt werden:
Vermeiden Sie feste Abhängigkeiten (so weit wie möglich)
jQuery und Bootstrap (oder Foundation oder <–fügen Sie hier Ihre Lieblingsbibliothek ein–> ) hätten vor ein paar Jahren als Must-Haves angesehen werden können, aber sie haben gegenüber Vanilla JS und neueren nativen CSS-Funktionen stetig an Boden verloren. Daher ist ein vor fünf Jahren codiertes allgemeines Projekt, das von diesen Bibliotheken abhängig war, heutzutage möglicherweise nicht mehr geeignet. Als Faustregel gilt also: Je geringer die festen Abhängigkeiten zu Drittbibliotheken, desto aktueller ist sie langfristig.
Progressive Erweiterung der Funktionalitäten
WordPress ist ein vollwertiges CMS-System, das eine Benutzerverwaltung enthält, daher ist die Unterstützung für die Benutzerverwaltung standardmäßig enthalten. Allerdings erfordert nicht jede WordPress-Site eine Benutzerverwaltung. Daher sollte unsere Anwendung dies berücksichtigen und in jedem Szenario optimal funktionieren: Benutzerverwaltung unterstützen, wann immer es erforderlich ist, aber die entsprechenden Assets nicht laden, wenn dies nicht der Fall ist. Dieser Ansatz kann auch schrittweise funktionieren: Angenommen, ein Kunde muss ein Kontaktformular implementieren, hat aber kein Budget, also codieren wir es mit einem kostenlosen Plugin mit eingeschränkten Funktionen, und ein anderer Kunde hat das Budget, um die Lizenz von einem kommerziellen Plugin-Angebot zu kaufen bessere Eigenschaften. Dann können wir unsere Funktionalität so codieren, dass sie standardmäßig auf eine sehr grundlegende Funktionalität zurückgreift, und zunehmend die Funktionen des leistungsfähigsten Plugins verwenden, das im System verfügbar ist.
Kontinuierliche Überprüfung von Code und Dokumentation
Indem wir unseren zuvor geschriebenen Code und seine Dokumentation regelmäßig überprüfen, können wir überprüfen, ob er hinsichtlich neuer Konventionen und Technologien auf dem neuesten Stand ist, und, falls dies nicht der Fall ist, Maßnahmen ergreifen, um ihn zu aktualisieren, bevor die Überwindung der technischen Schulden zu teuer wird und wir müssen alles von Grund auf neu codieren.
Empfohlene Lektüre : Seien Sie wachsam: PHP- und WordPress-Funktionen, die Ihre Website unsicher machen können
Versuchen Sie, Probleme zu minimieren, aber seien Sie vorbereitet, wenn sie auftreten
Keine Software ist jemals 100 % perfekt: Die Fehler sind immer da, wir haben sie nur noch nicht gefunden. Daher müssen wir sicherstellen, dass auftretende Probleme einfach zu beheben sind.
Mach es einfach
Komplexe Software lässt sich nicht langfristig warten: Nicht nur, weil andere Teammitglieder sie vielleicht nicht verstehen, sondern auch, weil die Person, die sie programmiert hat, ihren eigenen komplexen Code in ein paar Jahren vielleicht nicht mehr versteht. Daher muss die Erstellung einfacher Software Priorität haben, zumal nur einfache Software korrekt und schnell sein kann.
Fehler bei der Kompilierung sind besser als bei der Laufzeit
Wenn ein Codeabschnitt entweder zur Kompilierzeit oder zur Laufzeit gegen Fehler validiert werden kann, sollten wir die Lösung zur Kompilierzeit priorisieren, damit der Fehler in der Entwicklungsphase auftreten und behoben werden kann, bevor die Anwendung die Produktion erreicht. Zum Beispiel werden sowohl const
als auch define
zum Definieren von Konstanten verwendet, während const
jedoch zur Kompilierzeit validiert wird, wird define
zur Laufzeit validiert. Daher ist die Verwendung von const
nach Möglichkeit der Verwendung von define
vorzuziehen.
Dieser Empfehlung folgend, können in Klassen enthaltene Hooking-WordPress-Funktionen verbessert werden, indem die eigentliche Klasse als Parameter anstelle eines Strings mit dem Klassennamen übergeben wird. Wenn im folgenden Beispiel die Klasse Foo
umbenannt wird, während der zweite Hook einen Kompilierungsfehler erzeugt, schlägt der erste Hook zur Laufzeit fehl, daher ist der zweite Hook besser:
class Foo { public static function bar() { } } add_action('init', ['Foo', 'bar']); // Not so good add_action('init', [Foo::class, 'bar']); // Much better
Aus dem gleichen Grund wie oben sollten wir die Verwendung globaler Variablen (wie global $wpdb
) vermeiden: Diese verschmutzen nicht nur den globalen Kontext und sind nicht leicht nachzuvollziehen, woher sie stammen, sondern auch, wenn sie umbenannt werden, wird der Fehler auftreten zur Laufzeit produziert werden. Als Lösung können wir einen Dependency Injection Container verwenden, um eine Instanz des erforderlichen Objekts zu erhalten.
Umgang mit Fehlern/Ausnahmen
Wir können eine Architektur von Exception
-Objekten erstellen, sodass die Anwendung gemäß jedem einzelnen Problem angemessen reagieren kann, um sich entweder davon zu erholen, wann immer möglich, oder dem Benutzer eine hilfreiche Fehlermeldung anzuzeigen, wenn dies nicht der Fall ist, und im Allgemeinen den Fehler für das zu protokollieren Administrator, um das Problem zu beheben. Und schützen Sie Ihre Benutzer immer vor dem weißen Bildschirm des Todes: Alle nicht erfassten Error
und Exception
können durch die Funktion set_exception_handler
abgefangen werden, um eine nicht beängstigende Fehlermeldung auf dem Bildschirm auszugeben.
Übernehmen Sie Build-Tools
Build-Tools können viel Zeit sparen, indem sie Aufgaben automatisieren, deren manuelle Ausführung sehr mühsam ist. WordPress bietet keine Integration mit einem bestimmten Build-Tool, daher liegt die Aufgabe, diese in das Projekt zu integrieren, vollständig beim Entwickler.
Es gibt verschiedene Werkzeuge, um verschiedene Zwecke zu erfüllen. Beispielsweise gibt es Build-Tools zum Ausführen von Aufgaben zum Komprimieren und Ändern der Größe von Bildern, Minimieren von JS- und CSS-Dateien und Kopieren von Dateien in ein Verzeichnis zum Erstellen einer Version, wie Webpack, Grunt und Gulp; Andere Tools helfen beim Erstellen des Gerüsts eines Projekts, was hilfreich ist, um die Ordnerstruktur für unsere Themen oder Plugins wie Yeoman zu erstellen. Bei so vielen Tools hilft das Durchsuchen von Artikeln, die die verschiedenen verfügbaren Tools vergleichen, tatsächlich dabei, das für unsere Bedürfnisse am besten geeignete zu finden.
In einigen Fällen gibt es jedoch keine Build-Tools, die genau das erreichen können, was unser Projekt benötigt, sodass wir möglicherweise unser eigenes Build-Tool als Erweiterung des Projekts selbst programmieren müssen. Zum Beispiel habe ich dies getan, um die Datei service-worker.js zu generieren, um Unterstützung für Service Worker in WordPress hinzuzufügen.
Fazit
Aufgrund seiner starken Betonung der Aufrechterhaltung der Abwärtskompatibilität, die sogar bis PHP 5.2.4 erweitert wurde, konnte WordPress nicht von den neuesten Funktionen profitieren, die PHP hinzugefügt wurden, und diese Tatsache hat WordPress zu einer nicht sehr aufregenden Plattform zum Programmieren gemacht für unter vielen Entwicklern.
Glücklicherweise könnten diese düsteren Zeiten bald vorbei sein und WordPress könnte wieder zu einer glänzenden und aufregenden Plattform zum Programmieren werden: Die Anforderung von PHP 7.0+ ab Dezember 2019 wird zahlreiche PHP-Funktionen verfügbar machen, die es Entwicklern ermöglichen, leistungsfähiger und leistungsfähiger zu produzieren leistungsfähigere Software. In diesem Artikel haben wir die wichtigsten neu verfügbaren PHP-Funktionen besprochen und erklärt, wie Sie sie optimal nutzen können.
Die jüngste Veröffentlichung von Gutenberg könnte ein Zeichen für die kommenden guten Zeiten sein: Auch wenn Gutenberg selbst von der Community nicht vollständig akzeptiert wurde, zeigt es zumindest die Bereitschaft, die neuesten Technologien (wie React und Webpack) in den Kern zu integrieren . Diese Wendung der Ereignisse lässt mich fragen: Wenn das Frontend so umgestaltet werden kann, warum es dann nicht auf das Backend ausdehnen? Sobald WordPress mindestens PHP 7.0 erfordert, kann sich das Upgrade auf moderne Tools und Methoden beschleunigen: So sehr npm zum JavaScript-Paketmanager der Wahl wurde, warum sollte man Composer nicht zum offiziellen PHP-Abhängigkeitsmanager machen? Wenn Blöcke im Frontend die neue Einheit zum Bauen von Websites sind, warum dann nicht PHP-Komponenten als Einheit zum Einbringen von Funktionalitäten in das Backend verwenden? Und schließlich, wenn Gutenberg WordPress als austauschbares Backend-CMS behandelt, warum nicht bereits erkennen, dass WordPress eine Site-Abhängigkeit und nicht die Site selbst ist? Diese offenen Fragen überlasse ich Ihnen zum Nachdenken und Nachdenken.