Soll ich spl_autoload_register () in meinem Plugin verwenden?

11

Wenn ich spl_autoload_register in meinem Plugin verwende, erhalte ich:

    Fatal error: Uncaught exception 'LogicException' with message
   'Class wp_atom_server could not be loaded'

    wp-includes\pluggable-deprecated.php on line 182

Ich habe etwas gelesen und verschiedene Korrekturen gefunden. Einer auf SO sagte, spl_autoload_register nicht mit WordPress zu verwenden.

Ist das richtig?

Ich bin sicher, dass ich eine "Lösung" für den Fehler finden kann, aber ich bin nicht sicher, ob ich das mit jeder WP-Version tun möchte.

Wie soll ich meine Klassen laden, wenn ich die Autoload-Funktion nicht verwende? Folgendes bricht jetzt zusammen:

spl_autoload_extensions(".php");
spl_autoload_register();

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

Im Schüler:

<?PHP
namespace MyPluginClasses\Student
{
    class Student{
        public function __Construct(){
            echo "Hello Johnny";
        }
        public function sayHello(){
            echo "Hello Johnny's Method";

        }

    }
}

Dieses Design funktioniert gut außerhalb von WordPress.

Johnny
quelle
4
Ich habe meine Antwort aktualisiert . Wenn Sie es richtig machen - mit einer Rückruffunktion - können Sie spl_autoload_register()ohne negative Nebenwirkungen verwenden.
Fuxia
1
@toscho Ist Ihr Code immer noch der beste Weg, um das automatische Laden in WP durchzuführen?
Johnny
Nein ist es nicht. Der schnellste Weg ist, glob()einmal in das Verzeichnis zu gehen und dann die Klassen zu liefern, wenn sie pro benötigt werden spl_autoload_register().
Fuxia
1
Ich werde später eine Antwort schreiben, die unsere aktuelle (noch nicht veröffentlichte) Lösung von Multilingual Press zeigt.
Fuxia

Antworten:

1

Ich bin mir wirklich nicht sicher, ob es eine gute oder schlechte Praxis ist, Klassen im WP-Plugin automatisch zu laden. Für mich sehe ich keine Nebenwirkungen bei der Verwendung spl_autoload_register(nicht getestete Leistung)

Um Ihre Frage zu beantworten, möchte ich eine Klasse aus meinem kommenden Plugin freigeben, mit der ich Klassen ohne Probleme automatisch aus einem einzelnen Verzeichnis lade, und das tut mir bisher gut.

/**
 * Annframe Class Autoloader.
 *
 * @package Annframe
 * @since 0.1.0
 */
class Annframe_Autoloader {
    /**
     * Singleton.
     *
     * @since 0.1.0
     * @var Annframe_Autoloader - Single instance.
     */
    private static $_instance = null;

    /**
     * Private Construct.
     *
     * @package Annframe
     * @since 0.1.0
     */
    private function __construct() {
        spl_autoload_register( array( $this, 'load' ) );
    }

    /**
     * Singleton method.
     *
     * @package Annframe
     * @since 0.1.0
     */
    public static function _instance() {
        if ( ! self::$_instance ) {
            self::$_instance = new Annframe_Autoloader();
        }
        return self::$_instance;
    }

    /**
     * Class Loader.
     *
     * @package Annframe
     * @since 0.1.0
     *
     * @param string $class_name - Class name to load.
     * @return null - Do not return anything.
     */
    public function load( $class_name ) {
        $file = str_replace( '_', '-', strtolower( $class_name ) );
        $file = 'class-' . $file;
        if ( is_readable( trailingslashit( YOUR_PLUGIN_PATH. '/classes-dir' ) . $file . '.php' ) ) {
            include_once trailingslashit( YOUR_PLUGIN_PATH. '/classes-dir' ) . $file . '.php';
        }
        return;
    }
}

Annframe_Autoloader::_instance();

Um diese einfache Klasse in Teile zu zerlegen, wie Sie sehen, verwende ich Singleton-Muster. Constructorist privat und instance()& $_instancegehört zum Muster. Konstruktor hat spl_autoload_registerFunktion.

spl_autoload_register( array( $this, 'load' ) );

Das ruft die loadMethode aus der Selbstklasse auf. Die ersten beiden Zeilen dieser Methode lauten:

$file = str_replace( '_', '-', strtolower( $class_name ) );
$file = 'class-' . $file;

das ist ziemlich gerade. wenn Sie folgen WPCS es fordert Sie dazu auf, eine Klasse Namenskonvention zu folgen mit Wort Präfix Klasse und dann Klassennamen. Natürlich wird jeder Unterstrich (_) durch einen (-) Bindestrich ersetzt.

so ein Dateiname der Klasse WPSE_Postwäreclass-wpse-post.php

Namen der unteren Gehäuseklassen mit strtolowerund verwenden str_replace, um Unterstriche durch Bindestriche zu ersetzen. so wird WPSE_Postjetzt wpse-post. Endlich ein Präfix class-in der nächsten Zeile hinzufügen .

Ich verwende is_readablein bedingten Anweisung, die mit austauschbar ist file_exists. Angenommen, der YOUR_PLUGIN_PATHBasispfad des Plugins classes-dirbefindet sich im Haupt-Plugin-Verzeichnis und enthält alle Klassen, die automatisch geladen werden müssen.

include_once wird verwendet, um die eigentliche Datei beim Aufruf zu laden.

Verwendung:

Sie müssen nur die obige Auto Loader-Klasse in die Basisdatei Ihres Plugins aufnehmen

/**
 * Class autoloader.
 */
if ( ! class_exists( 'Annframe_Autoloader' ) ) {
    include_once YOUR_PLUGIN_PATH/class-annframe-autoloader.php';
}

und rufen Sie dann Ihre Klassen auf Anfrage an.

new XYX_Class();
Another_Class::instance(); // etc

Hinweis: Ich verwende in meiner Lösung keine Namespace-Methode, sodass sie möglicherweise Ihren Anforderungen entspricht oder nicht, aber hier veröffentlicht in der Hoffnung, dass zumindest jemand die Vorteile des dynamischen Ladens von Klassen erhält.

Anwer AR
quelle
-1
    function MyPluginClasses_autoloader( $class_name ) {
  if ( false !== strpos( $class_name, 'MyPluginClasses' ) ) {
    $parts = explode('\\', $class_name);
    require_once RoothPath . DIRECTORY_SEPARATOR .'lib'.DIRECTORY_SEPARATOR.end($parts) . '.php';
  }
}
spl_autoload_register( 'MyPluginClasses_autoloader' );
use MyPluginClasses\Student as MS;
$student = new MS\Student();
echo $student->sayHello();
Meldin Xavier
quelle
2
Obwohl der Postleitzahl gut ist, sollten Sie erklären, wie und warum dies die Frage beantwortet.
Laxmana
1
Da Ihr Plugin nicht das einzige Plugin im System ist, wird Code, der nur Klassen lädt, ohne vorher zu überprüfen, ob sie Ihnen gehören, früher oder später Probleme verursachen, wenn Sie versuchen, die falsche Datei für eine in einem anderen Plugin deklarierte Klasse zu laden.
Mark Kaplun