Okay, ich hatte zwei große Projekte, bei denen ich die Kontrolle über den Server hatte und mich auf das automatische Laden verlassen konnte.
Zuerst. Autoloading ist großartig. Sich keine Sorgen zu machen, ist eine relativ gute Sache.
Hier ist ein Loader, den ich für einige Projekte verwendet habe. Überprüft, ob sich die Klasse zuerst im aktuellen Namespace befindet. Andernfalls wird der Fehler behoben. Von dort aus ist es nur eine Art Zeichenkettenmanipulation, um die Klasse zu finden.
<?php
spl_autoload_register(__NAMESPACE__ . '\\autoload');
function autoload($cls)
{
$cls = ltrim($cls, '\\');
if(strpos($cls, __NAMESPACE__) !== 0)
return;
$cls = str_replace(__NAMESPACE__, '', $cls);
$path = PLUGIN_PATH_PATH . 'inc' .
str_replace('\\', DIRECTORY_SEPARATOR, $cls) . '.php';
require_once($path);
}
Man könnte dies leicht für die Verwendung ohne Namespaces anpassen. Unter der Annahme, dass Sie die Klassen Ihres Plugins / Themas einheitlich voranstellen, können Sie nur auf dieses Präfix testen. Verwenden Sie dann Unterstriche im Klassennamen als Platzhalter für Verzeichnisseparatoren. Wenn Sie viele Klassen verwenden, möchten Sie wahrscheinlich eine Art Classmap-Autoloader verwenden.
Namespaces und Hooks
Das Hooks-System von WordPress verwendet call_user_func
(und call_user_func_array
), wobei Funktionsnamen als Zeichenfolgen verwendet werden und diese aufgerufen werden, wenn der Funktionsaufruf do_action
(und anschließend call_user_func
) erfolgt.
Bei Namespaces müssen Sie also vollständig qualifizierte Funktionsnamen, die den Namespace enthalten, in Hooks übergeben.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
Es wäre wahrscheinlich besser, die __NAMESPACE__
magische Konstante liberal zu nutzen, wenn Sie dies tun möchten.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
Wenn Sie immer Ihre Haken in Klassen setzen, ist es einfacher. Die standardmäßige create-Instanz einer Klasse und alle Hooks im Konstruktor mit $this
funktionieren einwandfrei.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Wenn Sie statische Methoden wie ich verwenden möchten, müssen Sie den vollständig qualifizierten Klassennamen als erstes Argument des Arrays übergeben. Das ist viel Arbeit, man kann also einfach die magische __CLASS__
Konstante oder verwenden get_class
.
<?php
namespace WPSE\SomeNameSpace;
Plugin::init();
class Plugin
{
public static function init()
{
add_action('plugins_loaded', array(__CLASS__, 'loaded'));
// OR: add_action('plugins_loaded', array(get_class(), 'loaded'));
}
public static function loaded()
{
// this works!
}
}
Core-Klassen verwenden
PHPs Klassennamenauflösung ist ein bisschen wackelig. Wenn Sie Kern-WP-Klassen verwenden möchten ( WP_Widget
im folgenden Beispiel), müssen Sie use
Anweisungen bereitstellen .
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
Oder Sie können den vollständig qualifizierten Klassennamen verwenden, indem Sie ihm einen Backslash voranstellen.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Definiert
Dies ist allgemeineres PHP, aber es hat mich gebissen, also hier ist es.
Vielleicht möchten Sie Dinge definieren, die Sie häufig verwenden, wie den Pfad zu Ihrem Plugin. Mit der define-Anweisung werden Dinge in den Root-Namespace eingefügt, es sei denn, Sie übergeben den Namespace explizit an das erste Argument von define.
<?php
namespace WPSE\SomeNameSpace;
// root namespace
define('WPSE_63668_PATH', plugin_dir_path(__FILE__));
// in the current namespace
define(__NAMESPACE__ . '\\PATH', plugin_dir_path(__FILE__));
Sie können das const
Schlüsselwort on auch im Stammverzeichnis einer Datei mit PHP 5.3 plus verwenden. consts
s befinden sich immer im aktuellen Namespace, sind jedoch weniger flexibel als ein define
Aufruf.
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
Sie können gerne weitere Tipps hinzufügen!
Ich verwende Autoloading (da mein Plugin viele Klassen hat - auch weil es Twig enthält), habe nie auf ein Problem aufmerksam gemacht (Plugin> 20.000-mal installiert).
Wenn Sie sicher sind, dass Sie niemals eine PHP-Installation benötigen werden, die keine Namespaces unterstützt, sind Sie wieder in Ordnung (~ 70% der aktuellen WordPress-Blogs unterstützen keine Namespaces). Ein paar Dinge zu beachten:
Ich scheine mich daran zu erinnern, dass Namespaces in regulärem PHP nicht zwischen Groß- und Kleinschreibung unterscheiden, aber wenn Sie FastCGI-PHP unter iis verwenden - dies verursacht Kopfschmerzen, wenn Sie unter Linux testen und keinen falschen Kleinbuchstaben erkennen.
Auch wenn Sie sicher sind, dass der Code, den Sie gerade entwickeln, nur für> 5.3.0 verwendet wird, können Sie keinen Code für Projekte wiederverwenden, die nicht über diesen Luxus verfügen - das ist der Hauptgrund, warum ich dies nicht getan habe verwendete Namespaces für interne Projekte. Ich habe festgestellt, dass Namespaces im Vergleich zu den möglichen Kopfschmerzen, die durch das Entfernen der Abhängigkeit von ihnen entstehen können, nicht so viel hinzufügen .
quelle