Dovrei usare spl_autoload_register () nel mio plugin?


11

Quando uso spl_autoload_register nel mio plugin, ottengo:

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

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

Ho letto e trovato varie soluzioni. Uno su SO ha detto di non usare spl_autoload_register con WordPress.

È preciso?

Sono sicuro di poter trovare una "correzione" per l'errore, ma non sono sicuro di voler farlo con ogni versione di WP.

Se non utilizzo la funzione di caricamento automatico, come devo caricare le mie lezioni? Ecco cosa si rompe ora:

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

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

Nello studente:

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

        }

    }
}

Questo design funziona benissimo al di fuori di WordPress.


4
Ho aggiornato la mia risposta . Se lo fai bene - con una funzione di richiamata - puoi usare spl_autoload_register()senza effetti collaterali negativi.
fuxia

1
@toscho Il tuo codice è ancora il modo migliore per eseguire il caricamento automatico in WP?
johnny,

No non lo è. Il modo più veloce è di glob()accedere alla directory una volta, quindi consegnare le classi quando sono necessarie per spl_autoload_register().
fuxia

1
Scriverò una risposta in seguito, mostrando la nostra attuale (non ancora pubblicata) soluzione dalla Multilingual Press.
fuxia

Risposte:


1

Non sono davvero sicuro se sia buona o cattiva pratica caricare automaticamente le classi nel plugin WP. Per me, non vedo effetti collaterali dell'uso spl_autoload_register(prestazioni non testate)

Quindi, per rispondere alla tua domanda, vorrei condividere una classe dal mio plug-in imminente che sto usando per caricare automaticamente le classi da una singola directory senza problemi e per me va bene finora.

/**
 * 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();

Per spezzare questa semplice classe in parti come vedi sto usando il modello Singleton. Constructorè privata e instance()& $_instanceappartiene al modello. Il costruttore ha una spl_autoload_registerfunzione.

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

che sta chiamando il loadmetodo dall'auto-classe. Le prime due righe di questo metodo sono:

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

che è piuttosto dritto. se segui WPCS ti incoraggia a seguire una convenzione di denominazione di classe preceduta da word class e quindi dal nome della classe. ofcourse qualsiasi carattere di sottolineatura (_) viene sostituito con un trattino (-).

quindi WPSE_Postsarebbe un nome file della classeclass-wpse-post.php

Abbassa i nomi delle classi di case con strtolowere usando str_replaceper sostituire i trattini bassi con trattini. così WPSE_Postora diventa wpse-post. aggiungendo infine un prefisso class-alla riga successiva.

sto usando is_readablein una dichiarazione condizionale che è scambiabile con file_exists. supponendo che YOUR_PLUGIN_PATHsia il percorso di base del plugin ed classes-dirè sotto la directory principale del plugin che contiene tutte le tue classi che richiedono il caricamento automatico.

include_once viene utilizzato per caricare il file effettivo su chiamata.

Uso:

devi solo includere la classe di caricamento automatico sopra nel file di base del tuo plugin

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

e poi chiama le tue lezioni su richiesta.

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

Nota: non sto usando il metodo dello spazio dei nomi nella mia soluzione, quindi potrebbe adattarsi o meno alle tue esigenze, ma pubblicato qui nella speranza che qualcuno possa ottenere benefici dal caricamento dinamico delle classi.


-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();

2
Sebbene pubblicare il codice sia buono, dovresti spiegare come e perché questo risponde alla domanda.
Laxmana,

1
poiché il plug-in non è l'unico plug-in nel sistema, il codice che carica solo le classi senza verificare prima che siano le tue, prima o poi creerà problemi provando a caricare il file sbagliato per una classe dichiarata in un altro plug-in.
Mark Kaplun,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.