DevTips – Namespaces in PHP

Veröffentlicht: 2020-03-06

Vor etwa einem Jahr hat WordPress beschlossen, die erforderliche PHP-Mindestversion von 5.2 (wird seit 2010 verwendet) auf etwas aktuelleres zu aktualisieren. Tatsächlich ist heute die von WordPress empfohlene Mindestversion von PHP eine der neuesten: PHP 7.3.

Wenn Sie ein einfacher WordPress-Benutzer sind, wird Sie dies wahrscheinlich nicht allzu sehr beeinträchtigen (abgesehen von der Tatsache, dass diese neuen Versionen eine bessere Leistung bieten).

Aber wenn Sie ein Entwickler sind, haben diese neuen PHP-Versionen einige großartige Funktionen, die Sie in Ihren Plugins und Designs verwenden können. Und heute möchte ich speziell über eines sprechen, das uns schon lange begleitet, aber: Namespaces.

WordPress und Code-Präfixe

Eine der ersten Regeln, die Sie als WordPress-Entwickler lernen, lautet: „Bei allem, was wir tun, Präfixe zu verwenden“, um „Namenskollisionen“ zu vermeiden. Wie wir in WordPress Best Practices lesen können:

Eine Namenskollision tritt auf, wenn Ihr Plugin denselben Namen für eine Variable, Funktion oder Klasse verwendet wie ein anderes Plugin.

[Um Namenskollisionen zu vermeiden] sollte allen Variablen, Funktionen und Klassen ein eindeutiger Bezeichner vorangestellt werden. Präfixe verhindern, dass andere Plugins Ihre Variablen überschreiben und versehentlich Ihre Funktionen und Klassen aufrufen. Es wird Sie auch daran hindern, dasselbe zu tun.

Best Practices für die Entwicklung von WordPress-Plugins

Anstatt also beispielsweise eine Funktion wie get_site_id zu erstellen, ist es besser, sie nelio_content_get_site_id zu nennen. Auf diese Weise können wir schnell das Plugin ( nelio_content ) oder das Thema identifizieren, zu dem eine bestimmte Funktion ( get_site_id ) gehört, und fatale Fehler vermeiden, wenn mehrere Plugins versuchen, dieselbe Funktion zu definieren.

Die Verwendung von Präfixen ist eine rudimentäre Möglichkeit, einen „Namespace“ zu erstellen; eine Problemumgehung, die wir implementieren mussten, als wir keine bessere Alternative hatten. Alle diese Elemente, die dasselbe Präfix verwenden, sind Teil desselben Satzes oder Namensraums. Dies führt jedoch zu unnötig komplexerem Code: Namen sind länger wegen Präfixen, die keinem anderen Zweck als der Emulation von Namespaces dienen.

PHP-Namespaces

PHP-Version 5.3 führte das Konzept des Namensraums ein. Die Definition, die sie in der Dokumentation davon geben, scheint mir ausgezeichnet, also reproduziere ich sie hier:

Im weitesten Sinne sind Namensräume eine Möglichkeit, Elemente zu kapseln. Dies kann vielerorts als abstraktes Konzept angesehen werden. Beispielsweise dienen Verzeichnisse in jedem Betriebssystem dazu, zusammengehörige Dateien zu gruppieren und als Namensraum für die darin enthaltenen Dateien zu fungieren. Als konkretes Beispiel kann die Datei foo.txt sowohl im Verzeichnis /home/greg als auch in /home/other existieren, aber zwei Kopien von foo.txt können nicht gleichzeitig im selben Verzeichnis existieren.

In der PHP-Welt sollen Namespaces zwei Probleme lösen, auf die Autoren von Bibliotheken und Anwendungen stoßen, wenn sie wiederverwendbare Codeelemente wie Klassen oder Funktionen erstellen:

1. Nennen Sie Kollisionen zwischen von Ihnen erstelltem Code und internem PHP-Code oder Code von Drittanbietern.

2. Fähigkeit, Extra_Long_Names zu aliasieren (oder zu verkürzen), wodurch die Lesbarkeit des Quellcodes verbessert wird.

PHP-Dokumente

So erstellen Sie einen Namensraum

Das Erstellen eines Namensraums in PHP ist extrem einfach. Fügen Sie am Anfang der PHP-Datei, die Sie erstellen, eine namespace -Direktive mit dem Namen hinzu, den Sie verwenden möchten, und „alles“, was Sie in dieser Datei definieren, gehört zu diesem Namespace:

 <?php namespace Nelio_Content;

Ja, es ist so einfach! Jetzt befindet sich „alles“, was wir dort erstellen, im Namensraum Nelio_Content . Wenn ich zum Beispiel eine Funktion wie die eingangs erwähnte definiere:

 <?php namespace Nelio_Content; function get_site_id() { // ... }

wir wissen jetzt, dass sich get_site_id im Namespace Nelio_Content befindet. Auf diese Weise müssen wir beim Definieren der Funktion nicht mehr das Präfix nelio_content_ verwenden. Toll!

Ausnahmen von Namespaces

Wenn Sie sich das bisher Gesagte genau ansehen, werden Sie feststellen, dass ich „alles“ in Anführungszeichen geschrieben habe: „‚alles‘, was wir dort hinzufügen, gehört zum angegebenen Namensraum.“ Warum habe ich das getan? Da Namespaces nicht für absolut den gesamten Code gelten, den wir schreiben, gibt es einige Ausnahmen.

PHP-Namespaces decken nur die folgenden PHP-Elemente ab:

  • Klassen
  • Schnittstellen
  • Züge
  • Funktionen
  • Mit const deklarierte Konstanten, aber nicht mit define

Darüber hinaus gibt es einige zusätzliche Dinge in WordPress, die ebenfalls eigene Namensräume benötigen und die PHP-Namensräume leider nicht abdecken: Ihre Skript -Handles , Datenbankoptionen oder benutzerdefinierte Inhaltstypen und deren Metadaten usw. In all diesen Fällen müssen Sie Verwenden Sie weiterhin Präfixe.

So importieren Sie Elemente von einem Namensraum in einen anderen

Wenn Sie ein Element verwenden müssen, das sich in Ihrem eigenen Namensraum befindet, müssen Sie nichts Besonderes tun: Nennen Sie es einfach bei seinem Namen. Beispielsweise im folgenden Code-Snippet:

 <?php namespace Nelio_Content; function get_site_id() { // ... } function get_auth_token() { $site_id = get_site_id(); // ... }

Sie können sehen, dass wir zwei Funktionen definiert haben: get_site_id und get_auth_token , beide innerhalb des Nelio_Content Namespace. Wenn get_auth_token get_site_id , wird es einfach wie gewohnt aufgerufen.

Wenn Sie hingegen get_site_id in einem anderen Namensraum verwenden müssen, müssen Sie die Funktion mit ihrem vollständigen Bezeichner aufrufen:

 <?php namespace Something_Else; function do_some_action() { $site_id = Nelio_Content\get_site_id(); // ... }

oder Sie müssen die Funktion mit dem Schlüsselwort use importieren:

 <?php namespace Something_Else; use Nelio_Content\get_site_id; function do_some_action() { $site_id = get_site_id(); // ... }

Mir persönlich gefällt die zweite Option sehr gut: Mit dem Schlüsselwort use zum Importieren von Funktionen aus anderen Namensräumen können Sie einen kurzen Blick auf den Header Ihrer Datei werfen und deren Abhängigkeiten identifizieren.

WordPress-Filter und -Aktionen mit PHP-Namespaces

Es gibt ein wichtiges Detail, das Sie bei der Verwendung von Namespaces neben WordPress-Filtern und -Aktionen beachten sollten. Wenn Sie Filter- und Aktionsrückrufe angeben, tun Sie dies normalerweise, indem Sie den Rückrufnamen als Zeichenfolge angeben:

 <?php // ... add_action( 'init', 'do_some_action' );

Das Problem besteht darin, dass der vorherige Hook nicht wie erwartet funktioniert, wenn sich diese Funktion in einem Namensraum befindet. Sie müssen WordPress den vollständigen Namen der Funktion mitteilen. Mit anderen Worten, Sie müssen seinen Namensraum einschließen (falls vorhanden).

Fügen Sie den Haken in der Datei hinzu, in der Sie den Namespace selbst definieren? Es spielt keine Rolle, verwenden Sie den vollständigen Namen:

 <?php namespace Nelio_Content; function do_some_action() { // ... } add_action( 'init', 'Nelio_Content\do_some_action' );

Befinden Sie sich in einem anderen Namensraum, haben die Funktion jedoch mit use importiert? Es spielt auch keine Rolle, verwenden Sie den vollständigen Namen:

 <?php namespace Something_Else; use Nelio_Content\do_some_action; // ... add_action( 'init', 'Nelio_Content\do_some_action' );

Verwendung von Aliassen mit unseren Namespaces

Eine weitere sehr interessante Funktionalität von Namensräumen ist das Aliasing. Stellen Sie sich folgendes Szenario vor:

 <?php namespace Nelio_Content; function get_site_id() { // ... }

Wenn ich diese Funktion in einem anderen Namensraum verwenden möchte, haben wir bereits gesehen, dass ich dies mit use tun kann. Aber wie würde ich diese Funktion verwenden, wenn das Modul, in dem ich sie verwenden möchte, bereits eine Funktion namens get_site_id hat?

Nun, zu meinem Glück können wir unsere Importe in neue Namen umwandeln:

 <?php namespace Something_Else; use Nelio_Content\get_site_id as get_nc_site_id(); function get_site_id() { // ... } function do_some_action() { $nc_site_idd = get_nc_site_id(); // ... }

Beginnen Sie noch heute mit der Verwendung von Namespaces!

Namensräume sind ein fantastisches Werkzeug, um Namenskollisionen zu vermeiden und unseren Code zu organisieren. Tatsächlich, und obwohl ich diesen Beitrag nicht kommentiert habe, gibt es Standards wie PSR-4, die es PHP ermöglichen, Klassen automatisch zu laden, basierend auf der Struktur der von Ihnen verwendeten Namespaces und wie Sie den Code in Verzeichnisse und Dateien organisieren.

Wenn Sie in Ihren Projekten noch keine Namensräume verwenden, empfehlen wir Ihnen, ab sofort damit zu beginnen. Erzähl uns von deinen Erfahrungen in den Kommentaren!

Vorgestelltes Bild von Chaitanya Tvs auf Unsplash.