German (Deutsch) translation by Wei Zhang (you can also view the original English article)
Wenn dies das erste Tutorial ist, das Sie in dieser Serie lesen, dann empfehle ich sehr, das, was wir bisher besprochen haben, nachzuholen.
Im Wesentlichen kommst du am Ende der Show rein. An dieser Stelle haben wir den Grundstein für unser Plugin gelegt, das Plugin geschrieben und Namespaces und Autoloader definiert und erkundet. Alles was übrig bleibt, ist anzuwenden, was wir gelernt haben.
In diesem Tutorial werden wir alle Teile zusammenfügen. Insbesondere werden wir den Quellcode unseres Plugins erneut aufrufen, alle relevanten Klassen benennen und einen Autoloader schreiben, so dass wir alle unsere include-Anweisungen entfernen können.
Ich werde alles ausführlich besprechen, während wir den Code durcharbeiten. Auch wenn dies das erste Tutorial ist, das Sie in dieser Serie lesen, sollten Sie sich mit dem, was wir bisher besprochen haben, befassen und dann zu diesem Tutorial zurückkehren.
Bevor wir irgendeinen Code schreiben
Zu diesem Zeitpunkt sollten Sie wissen, wie wir unsere Entwicklungsumgebung eingerichtet haben. Zur Erinnerung, hier ist eine kurze Übersicht über die Software, die wir verwenden:
- mindestens PHP 5.6.20
- der Apache-Webserver
- ein MySQL-Datenbankserver
- WordPress 4.6.1
- Kenntnisse der WordPress Plugin API
Sie werden auch eine Kopie des Quellcodes des Plugins benötigen, mit dem wir arbeiten. Sie können eine Kopie davon hier abholen. Angenommen, es ist installiert, aktiviert, und Sie haben Ihre IDE ausgeführt, fangen wir an.
Namespacing des Codes
Erinnern Sie sich an das vorherige Tutorial, ich bin ein Fan davon, sicherzustellen, dass unsere Namespaces der Organisation der Dateien auf der Festplatte folgen. Wenn Sie sich die Verzeichnisstruktur unseres Plugins anschauen oder wenn Sie der bisherigen Serie folgen, sollten Sie folgendes sehen:

Beachten Sie, dass, wenn Sie Ihr Plugin anders eingerichtet haben, das in Ordnung ist. Ihre Namespaces werden wahrscheinlich anders sein, aber das sollte nichts beeinflussen, was in dieser Serie behandelt wird.
Anhand der Verzeichnisstruktur als Richtlinie gehen wir alle PHP-Dateien durch, aus denen unser Plugin besteht, und definieren deren Namespaces. Dies ist ganz einfach: Sie müssen nur das Schlüsselwort namespace verwenden und oben in jeder Datei einen qualifizierten Namen eingeben.
Ich werde jeden unten auflisten.
tutsplus-namespace-demo.php
<?php /** * The plugin bootstrap file * * This file is read by WordPress to generate the plugin information in the * plugin admin area. This file also includes all of the dependencies used by * the plugin, registers the activation and deactivation functions, and defines * a function that starts the plugin. * * @link https://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1 * @since 0.1.0 * @package tutsplus_namespace_demo * * @wordpress-plugin * Plugin Name: Tuts+ Namespace Demo * Plugin URI: http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1 * Description: Learn how to use Namespaces and Autoloading in WordPress. * Version: 0.2.0 * Author: Tom McFarlin * Author URI: https://tommcfarlin.com/ * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ namespace Tutsplus_Namespace_Demo; // If this file is accessed directory, then abort. if ( ! defined( 'WPINC' ) ) { die; }
class-meta-box.php
<?php /** * Represents a meta box to be displayed within the 'Add New Post' page. */ namespace Tutsplus_Namespace_Demo\Admin;
class-meta-box-display.php
<?php /** * Defines the functionality required to render the content within the Meta Box * to which this display belongs. */ namespace Tutsplus_Namespace_Demo\Admin;
interface-assets.php
<?php namespace Tutsplus_Namespace_Demo\Admin\Util;
class-css-loader.php
<?php /** * Provides a consistent way to enqueue all administrative-related stylesheets. */ namespace Tutsplus_Namespace_Demo\Admin\Util;
class-question-reader.php
<?php /** * Reads the contents of a specified file and returns a random line from the * file. */ namespace Tutsplus_Namespace_Demo\Admin\Util;
Es gibt ein paar Dinge, die ich bezüglich der Konventionen beachten muss, die ich oben verwendet habe:
- Der Stammnamespace ist
Tutsplus_Namespace_Demo
, der dem Verzeichnisnamen des Plugins entspricht. - Der Rest der Namespaces wie
Tutsplus_Namespace_Demo\Admin
undTutsplus_Namespace_Demo\Admin\Util
entsprechen auch ihren jeweiligen Verzeichnissen; Die Verzeichnisnamen sind jedoch verkapselt (im Gegensatz zu Kleinbuchstaben).
Schließlich, wenn Sie versucht haben, die Seite zu aktualisieren, oder Sie versucht haben, in WordPress zu navigieren, seit die Namespace-Anweisungen eingeführt wurden, dann sehen Sie wahrscheinlich einen Fehler in Ihrer Konsole, der ungefähr so aussieht:

Und es enthält die folgende Nachricht:
PHP Warnung: call_user_func_array () erwartet, dass Parameter 1 ein gültiger Callback ist, Funktion 'tutsplus_namespace_demo' nicht gefunden oder ungültiger Funktionsname in /Users/tommcfarlin/Dropbox/Projects/tutsplus/wp-includes/plugin.php in Zeile 524
Oder vielleicht zeigt es:
PHP Fataler Fehler: Die Klasse 'Meta_Box' wurde nicht in /Users/tommcfarlin/Dropbox/Projects/utsplus/wp-content/plugins/utsplus-namespace-demo/tutsplus-namespace-demo.php in Zeile 48 gefunden
Oder Sie können eine beliebige Anzahl anderer ähnlicher Fehlermeldungen sehen. Das ist okay. Es ist normal.
Aber es wirft die Frage auf: Was ist mit unserem Plugin los? Zum Glück nichts. Dies ist das erwartete Verhalten.
Die erste Nachricht, die Sie sehen, kann ein Ergebnis eines anderen Plugins sein, das Sie installiert haben. Ich konnte es nicht selbst reproduzieren; Wenn ich jedoch ein paar der anderen Plugins deaktiviere, die ich ausgeführt habe, hat das Plugin die zweite Nachricht generiert (was die Nachricht ist, die ich demonstrieren wollte).
Wenn Sie Namespace-Code verwenden, erwartet PHP, eine Klasse in einem bestimmten Namespace zu lokalisieren. Konzeptionell können Sie sich vorstellen, dass Ihre Klassen jetzt zu ihrem eigenen Paket (oder Unterpaket) gehören oder wie Sie es auch definieren. Und damit eine Funktion auf eine Klasse innerhalb eines Pakets zugreifen kann, muss sie auf die vorhandenen Pakete aufmerksam gemacht werden.
Hier kommt zusätzliche Namespace-Funktionalität und Autoloading ins Spiel. Bevor wir also versuchen, über ihren Namespace auf unseren Code zuzugreifen, arbeiten wir an einem Autoloader.
Alles über Autoloading
Das Schreiben eines Autoloaders erfordert Folgendes:
- Verständnis einer PHP-Funktion namens
spl_autoload_register
- Schreiben einer Funktion, die automatisch unsere Namespaced-Dateien lädt
- einschließlich unserer benutzerdefinierten Autoloading-Funktion
Lassen Sie sich nicht vom Namen spl_autoload_register
einschüchtern. Es bedeutet einfach, dass dies eine Funktion ist, die Teil der "Standard PHP Library" ist und es ist, wie wir eine "Autoload" -Funktion "registrieren". Es ist ein Mund voll zu sagen und viele Zeichen zu schreiben, aber es ist nur eine Funktion, die wir benutzen werden, um PHP mitzuteilen, wie man Namespaces und Klassennamen analysiert und wo es unsere Dateien finden kann.
Diese Funktion ermöglicht es uns, unseren eigenen benutzerdefinierten Code zum automatischen Laden von Dateien zu schreiben und dann diese Funktion in PHP einzubinden. Das heißt, wir teilen PHP mit, wo unsere Dateien zu finden sind und wie Namespaces, Dateinamen usw. analysiert werden, damit sie die Dateien enthalten.
Nach all dem sind wir bereit, einen Autoloader zu schreiben.
Einen Autoloader schreiben
Wenn Sie einen Autoloader schreiben, sollten Sie nicht vergessen, wie unsere Dateien organisiert sind. Das heißt, wir möchten wissen, wie unsere Namespaces unseren Verzeichnissen zugeordnet werden.
Im Beispiel, das wir verwenden, ist es einfach: Die Namespaces sind verkleinerte Versionen der Verzeichnisstruktur. Dies gilt nicht immer für andere Projekte. Es ist jedoch ein weiterer Grund, warum ich meine Dateien logisch basierend auf ihrem physischen Standort organisieren möchte.
Wenn PHP versucht, eine Klasse zu laden, muss unser Autoloader Folgendes tun:
- Teilen Sie den Namensraum basierend auf den Schrägstrichen auf.
- Teilen Sie das Paket und die Unterpakete basierend auf Unterstrichen auf und ersetzen Sie sie (falls erforderlich) durch Bindestriche.
- Erfahren Sie, wie Sie Klassennamen, Schnittstellen usw. Dateinamen zuordnen.
- Erstellen Sie eine Zeichenfolgendarstellung des Dateinamens basierend auf den obigen Informationen.
- Fügen Sie die Datei ein.
Mit all diesen Punkten haben wir unsere Arbeit für uns erledigt. Erstellen Sie im Verzeichnis plugin ein Unterverzeichnis namens inc
, und erstellen Sie im Verzeichnis inc
eine Datei namens autoload.php
.
Lassen Sie uns in dieser Datei weitermachen und die Funktion ausstellen, mit der wir unsere Dateien automatisch laden. Es sollte ungefähr so aussehen:
<?php /** * Dynamically loads the class attempting to be instantiated elsewhere in the * plugin. * * @package Tutsplus_Namespace_Demo\Inc */ spl_autoload_register( 'tutsplus_namespace_demo_autoload' ); /** * Dynamically loads the class attempting to be instantiated elsewhere in the * plugin by looking at the $class_name parameter being passed as an argument. * * The argument should be in the form: TutsPlus_Namespace_Demo\Namespace. The * function will then break the fully-qualified class name into its pieces and * will then build a file to the path based on the namespace. * * The namespaces in this plugin map to the paths in the directory structure. * * @param string $class_name The fully-qualified name of the class to load. */ function tutsplus_namespace_demo_autoload( $class_name ) { // If the specified $class_name does not include our namespace, duck out. if ( false === strpos( $class_name, 'Tutsplus_Namespace_Demo' ) ) { return; } // More to come... }
Offensichtlich tut dies noch nichts.
A Side Note zum Schreiben eines Autoloaders
Beachten Sie, dass ich den Code und die Kommentare schreiben werde, um zu erklären, was wir tun. Wenn Sie sich zum ersten Mal selbst darauf einlassen, ist es vielleicht frustrierend, einen Autoloader zusammen mit Namespaces zu schreiben und mit Dateien zu arbeiten. Hier können ein Debugger und die Verwendung von Protokolldateien nützlich sein.
Dies liegt außerhalb des Rahmens dieses Tutorials, aber Sie sollten wissen, dass das Schreiben eines Autoloaders nicht das Richtige für Sie ist, wenn Sie das erste Mal tun.
Komplettierung des Autoloaders
Beginnen wir mit dem Hinzufügen einiger Funktionen, indem Sie die am Anfang dieses Abschnitts aufgeführten Schritte ausführen.
Zuerst müssen wir eine Schleife einrichten, die rückwärts durch die Teile des Dateinamens läuft, die an die Autoloading-Funktion übergeben werden. Wir machen das, weil es einfacher ist, einen Pfad zu der Datei zu erstellen, die automatisch geladen wird.
<?php function tutsplus_namespace_demo_autoload( $class_name ) { // If the specified $class_name does not include our namespace, duck out. if ( false === strpos( $class_name, 'Tutsplus_Namespace_Demo' ) ) { return; } // Split the class name into an array to read the namespace and class. $file_parts = explode( '\\', $class_name ); // Do a reverse loop through $file_parts to build the path to the file. $namespace = ''; for ( $i = count( $file_parts ) - 1; $i > 0; $i-- ) { // More to come... } }
Danach müssen wir uns die $file_parts
ansehen und alle Vorkommen des Unterstrichs durch einen Bindestrich ersetzen, da alle unsere Klassennamen und Schnittstellen Unterstriche verwenden, während unsere Dateinamen Bindestriche verwenden.
Die folgenden zwei Zeilen sind die ersten zwei Zeilen innerhalb der Schleife, die wir oben ausgegeben haben:
<?php // Read the current component of the file part. $current = strtolower( $file_parts[ $i ] ); $current = str_ireplace( '_', '-', $current );
Als nächstes brauchen wir eine Bedingung, die ein paar Dinge tut.
- Es muss überprüft werden, welcher Eintrag des Pfads des Dateinamens, den wir gerade lesen.
- Wenn wir beim ersten Eintrag sind, dann haben wir den Dateinamen; Ansonsten sind wir in seinem Namensraum.
- Als nächstes, wenn wir den ersten Eintrag lesen, müssen wir feststellen, ob wir versuchen, eine Schnittstelle automatisch zu laden oder wir laden eine Klasse.
- Wenn es ersteres ist, dann müssen wir den Namen der Schnittstelle anpassen, damit wir sie basierend auf ihrem Dateinamen richtig laden; Andernfalls laden wir die Klasse basierend auf dem Wert in der Variablen
$current
.
Es liest sich wie eine Menge, aber es sollte nicht schrecklich kompliziert zu lesen sein. Sehen Sie den kommentierten Code unten:
<?php // If we're at the first entry, then we're at the filename. if ( count( $file_parts ) - 1 === $i ) { /* If 'interface' is contained in the parts of the file name, then * define the $file_name differently so that it's properly loaded. * Otherwise, just set the $file_name equal to that of the class * filename structure. */ if ( strpos( strtolower( $file_parts[ count( $file_parts ) - 1 ] ), 'interface' ) ) { // Grab the name of the interface from its qualified name. $interface_name = explode( '_', $file_parts[ count( $file_parts ) - 1 ] ); $interface_name = $interface_name[0]; $file_name = "interface-$interface_name.php"; } else { $file_name = "class-$current.php"; } } else { $namespace = '/' . $current . $namespace; }
Danach ist es an der Zeit, einen vollständig qualifizierten Pfad zur Datei zu erstellen. Glücklicherweise ist das wenig mehr als eine einfache Kettenverkettung:
<?php // Now build a path to the file using mapping to the file location. $filepath = trailingslashit( dirname( dirname( __FILE__ ) ) . $namespace ); $filepath .= $file_name;
Zuletzt müssen wir sicherstellen, dass die Datei existiert. Wenn nicht, zeigen wir eine Standard-WordPress-Fehlermeldung an:
<?php // If the file exists in the specified path, then include it. if ( file_exists( $filepath ) ) { include_once( $filepath ); } else { wp_die( esc_html( "The file attempting to be loaded at $filepath does not exist." ) ); }
Und an dieser Stelle haben wir einen vollständigen Autoloader (der durch Herunterladen der Dateien von dem Link in der Seitenleiste dieses Posts abgerufen werden kann, da der Quellcode hier im Tutorial ein wenig zu lang wäre).
Schließlich ist es wichtig zu beachten, dass diese spezielle Funktion als Klasse umgeschrieben werden kann (oder sollte). Außerdem sollte die Klasse aus mehreren kleineren Funktionen bestehen, von denen geprüft werden kann, die eine einzige Verantwortung tragen und die klarer gelesen werden als die obigen. Vielleicht werde ich in einem Bonus-Tutorial durch den Prozess gehen, wie das aussehen würde.
Aber wir schließen immer noch Dateien ein
Wenn Sie am oberen Rand der Haupt-Plugin-Datei (oder der Bootstrap-Datei, die wir oft aufgerufen haben) sehen, werden Sie mehrere Include
-Anweisungen bemerken, die wie folgt aussehen:
<?php // Include the files for rendering the display. include_once( 'admin/class-meta-box.php' ); include_once( 'admin/class-meta-box-display.php' ); include_once( 'admin/util/class-question-reader.php' ); // Include the files for loading the assets include_once( 'admin/util/interface-assets.php' ); include_once( 'admin/util/class-css-loader.php' );
Angesichts der Arbeit, die wir bis zu diesem Punkt geleistet haben, können wir diese Aussagen endlich entfernen und durch nur eine ersetzen:
<?php // Include the autoloader so we can dynamically include the rest of the classes. require_once( trailingslashit( dirname( __FILE__ ) ) . 'inc/autoloader.php' );
Um es klar zu sagen, wir ersetzen es durch unseren Autoloader. An dieser Stelle sollten wir mit unserem Plugin fertig sein.
Alles zusammenfügen
Jetzt, da wir unseren Code namespaced haben, um eine logische Organisation verwandter Klassen bereitzustellen, und einen Autoloader geschrieben haben, um automatisch Dateien basierend auf dem Namespace und dem Dateispeicherort jeder Klasse einzuschließen, sollten wir in der Lage sein, unser Plugin zu starten und es genau so laufen zu lassen während der ersten erfolgreichen Iteration.
Als letztes müssen wir sicherstellen, dass wir die Bootstrap-Datei aktualisieren, sodass wir PHP anweisen, die Namespaces für die Meta_Box
, das Meta_Box_Display
, den Question_Reader
und den CSS_Loader
zu verwenden.
<?php use Tutsplus_Namespace_Demo\Admin; use Tutsplus_Namespace_Demo\Admin\Util; // If this file is accessed directory, then abort. if ( ! defined( 'WPINC' ) ) { die; } // Include the autoloader so we can dynamically include the rest of the classes. require_once( trailingslashit( dirname( __FILE__ ) ) . 'inc/autoloader.php' ); add_action( 'plugins_loaded', 'tutsplus_namespace_demo' ); /** * Starts the plugin by initializing the meta box, its display, and then * sets the plugin in motion. */ function tutsplus_namespace_demo() { $meta_box = new Admin\Meta_Box( new Admin\Meta_Box_Display( new Util\Question_Reader() ) ); $css_loader = new Util\CSS_Loader(); $css_loader->init(); $meta_box->init(); }
Beachten Sie, dass wir im obigen Code das use
-Schlüsselwort von PHP verwenden und unseren Klassennamen ihre unmittelbaren Unterpakete voranstellen. Sie können mehr über die Verwendung im Handbuch lesen, aber kurz gesagt:
Das use-Schlüsselwort muss im äußersten Bereich einer Datei (der globale Bereich) oder innerhalb von Namespace-Deklarationen deklariert sein. Dies liegt daran, dass das Importieren zur Kompilierzeit und nicht zur Laufzeit durchgeführt wird, daher kann es nicht im Blockbereich ausgeführt werden.
Wenn Sie davon ausgehen, dass alles ordnungsgemäß funktioniert, sollten Sie in der Lage sein, zur Seite "Neuen Beitrag hinzufügen" (oder "Beitrag bearbeiten") zu navigieren, unser Metabox anzuzeigen und am oberen Rand der Seitenleiste eine Frageaufforderung zu sehen:

Wenn ja, dann herzlichen Glückwunsch. Sie haben Ihr Plugin erfolgreich für Ihre Namespaces und das automatische Laden eingerichtet. Ist dies nicht der Fall, überprüfen Sie den Code anhand dessen, was wir hier geteilt haben, überprüfen Sie Ihre Fehlerprotokolle und stellen Sie sicher, dass nichts auf dem WordPress-Administrationsbildschirm auffällt.
Wenn Sie etwas sehen, ist die Wahrscheinlichkeit gering, dass es etwas zu tun hat. Überprüfen Sie den Code, den wir behandelt haben, vergleichen Sie ihn mit dem, was hier an diesem Post angehängt ist (in der Seitenleiste mit dem großen blauen Button), und prüfen Sie, ob Sie das Problem eingrenzen können.
Fazit
An diesem Punkt haben wir das Ende unserer Serie erreicht. In den letzten vier Tutorials haben wir sehr viel gelernt:
- Wir haben ein Plugin entwickelt, das Benutzer mit Fragen dazu auffordert, ihr Bloggen zu starten.
- Wir haben PHP-Funktionen zum Lesen von Dateien aus dem Dateisystem und zum Rendern in der Anzeige verwendet.
- Wir haben Namespaces und Autoloading definiert und einen Blick darauf geworfen, wie sie angewendet werden können.
- Wir haben unseren Code organisiert und unseren eigenen Autoloader geschrieben, der den Code lesbarer, organisierter und weniger überladen macht.
Letztendlich kann viel von dem Material, das in dieser Serie behandelt wird, in bestehenden und zukünftigen Projekten verwendet werden, an denen Sie arbeiten.
Denken Sie daran, dass Sie auch andere WordPress-Produkte in unserem Marktplatz finden können. Und wenn Sie mehr über die Entwicklung von Lösungen für WordPress erfahren möchten, finden Sie alle meine Tutorials und Serien auf meiner Profilseite. Zögere nicht, mir auf meinem Blog oder Twitter zu folgen, während ich fast täglich über Softwareentwicklung im Kontext von WordPress diskutiere.
Und denken Sie daran, der Link zum Herunterladen des finalen Quellcodes befindet sich in der Seitenleiste unter einem Button mit dem Titel Download Attachment. Natürlich zögern Sie nicht, Fragen in den Kommentaren zu stellen!
Ressourcen
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post