it-swarm.com.de

Der beste Weg, um eine Klasse in einem zu initiieren WP Plugin?

Ich habe ein Plugin erstellt und natürlich wollte ich als ich mit einem Nice-Ansatz OO weitermachen. Was ich jetzt gemacht habe, ist, diese Klasse zu erstellen und dann direkt darunter eine Instanz dieser Klasse zu erstellen:

class ClassName {

    public function __construct(){

    }
}

$class_instance = new ClassName();  

Ich gehe davon aus, dass es mehr WP Möglichkeiten gibt, diese Klasse zu initiieren, und dann bin ich auf Leute gestoßen, die sagten, sie hätten lieber eine init()-Funktion als eine __construct()-Funktion. Und in ähnlicher Weise fand ich die ein paar Leute mit folgenden Haken:

class ClassName {

    public function init(){

    }
}
add_action( 'load-plugins.php', array( 'ClassName', 'init' ) );

Was wird im Allgemeinen als die beste Methode zum Erstellen einer WP - Klasseninstanz beim Laden angesehen, und welche als global zugreifbare Variable?

HINWEIS: Als interessanter Nebeneffekt ist mir aufgefallen, dass register_activation_hook() zwar aus dem __construct aufgerufen werden kann, aber nicht aus dem init() mit dem zweiten Beispiel. Vielleicht könnte mich jemand in diesem Punkt aufklären.

Bearbeiten: Vielen Dank für alle Antworten, es gibt natürlich einiges an Debatte darüber, wie die Initialisierung innerhalb der Klasse selbst gehandhabt wird, aber ich denke, es besteht im Allgemeinen ein ziemlich guter Konsens darüber, dass add_action( 'plugins_loaded', ...); der beste Weg ist, um sie tatsächlich zu kicken aus...

Bearbeiten: Nur um die Sache zu verwirren, habe ich auch gesehen, dass dies verwendet wird (obwohl ich diese Methode selbst nicht verwenden würde, weil das Umwandeln einer netten OO -Klasse in eine Funktion den Sinn zu verlieren scheint):

// Start up this plugin
add_action( 'init', 'ClassName' );
function ClassName() {
    global $class_name;
    $class_name = new ClassName();
}
85
kalpaitch

Gute Frage, es gibt eine Reihe von Ansätzen und es kommt darauf an, was Sie erreichen wollen.

Das tue ich oft;

add_action( 'plugins_loaded', array( 'someClassy', 'init' ));

class someClassy {

    public static function init() {
        $class = __CLASS__;
        new $class;
    }

    public function __construct() {
           //construct what you see fit here...
    }

    //etc...
}

Ein ausführlicheres Beispiel, das sich aus jüngsten Diskussionen zu genau diesem Thema im Chatroom ergab, ist in this Gist von WPSE-Mitglied toscho zu sehen.

Der leere Konstruktor-Ansatz.

Hier finden Sie einen Auszug der Vor- und Nachteile aus dem obigen Abschnitt, der den vollständigen Ansatz des leeren Konstruktors veranschaulicht.

  • Vorteile:

    • Unit-Tests können neue Instanzen erstellen, ohne dass automatisch Hooks aktiviert werden. Kein Singleton.

    • Keine globale Variable erforderlich.

    • Wer mit der Plugin-Instanz arbeiten möchte, kann einfach T5_Plugin_Class_Demo :: get_instance () aufrufen.

    • Einfach zu deaktivieren.

    • Immer noch echtes OOP: Keine Arbeitsmethode ist statisch.

  • Nachteil:

    • Vielleicht schwerer zu lesen?

Der Nachteil ist meiner Meinung nach ein schwacher, weshalb es mein bevorzugter Ansatz sein müsste, aber nicht der einzige, den ich benutze. Tatsächlich werden ohne Zweifel einige andere Schwergewichte in Kürze zu diesem Thema Stellung nehmen, da es einige gute Meinungen zu diesem Thema gibt, die geäußert werden sollten.


anmerkung: Ich muss das Gist-Beispiel aus toscho finden, das 3 oder 4 Vergleiche zum Instanziieren einer Klasse in einem Plugin durchlief, das die Vor- und Nachteile der einzelnen Plugins untersuchte, zu denen der obige Link der bevorzugte Weg war tun Sie es, aber die anderen Beispiele bieten einen guten Kontrast zu diesem Thema. Hoffentlich hat toscho das noch in der Akte.

Hinweis: Die WPSE-Antwort auf dieses Thema mit relevanten Beispielen und Vergleichen. Auch die beste Lösung zum Beispiel eine Klasse in WordPress.

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );
class My_Plugin {

    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance() {

        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo() {

        return $this->var; // never echo or print in a shortcode!
    }
}
57
userabuser

Ich benutze folgende Struktur:

Prefix_Example_Plugin::on_load();

/**
 * Example of initial class-based plugin load.
 */
class Prefix_Example_Plugin {

    /**
     * Hooks init (nothing else) and calls things that need to run right away.
     */
    static function on_load() {

        // if needed kill switch goes here (if disable constant defined then return)

        add_action( 'init', array( __CLASS__, 'init' ) );
    }

    /**
     * Further hooks setup, loading files, etc.
     *
     * Note that for hooked methods name equals hook (when possible).
     */
    static function init(  ) {


    }
}

Anmerkungen:

  • hat einen Platz für Dinge definiert, die sofort laufen müssen
  • deaktivieren/Überschreiben für Optimierungen ist einfach (eine init Methode aushängen)
  • Ich glaube nicht, dass ich jemals ein Objekt der Plugin-Klasse verwendet/benötigt habe - es erfordert, dass ich den Überblick behalte usw .; Dies ist wirklich ein gefälschter Namensraum, nicht OOP (meistens)

Haftungsausschluss Ich benutze noch keine Komponententests ( so viele Dinge auf meinem Schild ) und ich höre, dass statische Aufladung für sie weniger vorzuziehen ist. Recherchieren Sie hierüber, wenn Sie einen Komponententest durchführen müssen.

10
Rarst

Alles hängt von der Funktionalität ab.

Ich habe einmal ein Plugin erstellt, das Skripte registriert, als der Konstruktor aufgerufen wurde, also musste ich es am Hook wp_enqueue_scripts einhängen.

Wenn Sie es aufrufen möchten, wenn Ihre functions.php -Datei geladen wird, können Sie genauso gut selbst eine Instanz erstellen $class_instance = new ClassName();, wie Sie es erwähnt haben.

Möglicherweise möchten Sie die Geschwindigkeit und Speichernutzung berücksichtigen. Mir sind keine bekannt, aber ich kann mir vorstellen, dass es in einigen Fällen unangemeldete Haken gibt. Indem Sie Ihre Instanz an diesem Hook erstellen, sparen Sie möglicherweise einige Serverressourcen.

3
Tim S.

Ich weiß, dass dies ein paar Jahre alt ist, aber in der Zwischenzeit unterstützt PHP 5.3 anonyme Methoden , also habe ich mir Folgendes ausgedacht:

add_action( 'plugins_loaded', function() { new My_Plugin(); } );

und irgendwie mag ich es am meisten. Ich kann reguläre Konstruktoren verwenden und muss keine "init" - oder "on_load" -Methoden definieren, die meine OOP -Strukturen durcheinander bringen.

0
Basti