Dois-je utiliser spl_autoload_register () dans mon plugin?


11

Lorsque j'utilise spl_autoload_register dans mon plugin, j'obtiens:

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

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

J'ai fait quelques lectures et trouvé diverses corrections. Un sur SO a dit de ne pas utiliser spl_autoload_register avec WordPress.

Est-ce exact?

Je suis sûr que je peux trouver un "correctif" pour l'erreur, mais je ne suis pas sûr de vouloir le faire avec chaque version de WP.

Si je n'utilise pas la fonction de chargement automatique, comment dois-je charger mes classes? Voici ce qui se casse maintenant:

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

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

En étudiant:

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

        }

    }
}

Cette conception fonctionne bien en dehors de WordPress.


4
J'ai mis à jour ma réponse . Si vous le faites correctement - avec une fonction de rappel - vous pouvez l'utiliser spl_autoload_register()sans effets secondaires négatifs.
fuxia

1
@toscho Votre code est-il toujours le meilleur moyen d'effectuer le chargement automatique dans WP?
johnny

Non, ça ne l'est pas. Le moyen le plus rapide consiste à glob()accéder au répertoire une fois, puis à livrer les classes quand elles sont nécessaires spl_autoload_register().
fuxia

1
J'écrirai une réponse plus tard, montrant notre solution actuelle (non encore publiée) de Multilingual Press.
fuxia

Réponses:


1

Je ne sais vraiment pas si c'est une bonne ou une mauvaise pratique de charger automatiquement des classes dans le plugin WP. Pour moi, je ne vois aucun effet secondaire de l'utilisation spl_autoload_register(performances non testées)

Donc, pour répondre à votre question, je voudrais partager une classe de mon prochain plugin que j'utilise pour charger automatiquement les classes à partir d'un seul répertoire sans aucun problème et cela me convient jusqu'à présent.

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

Pour briser cette classe simple en plusieurs parties comme vous le voyez, j'utilise le modèle Singleton. Constructorest privé et instance()et $_instanceappartient au modèle. Le constructeur a une spl_autoload_registerfonction.

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

qui appelle la loadméthode de l'auto-classe. Les deux premières lignes de cette méthode sont:

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

ce qui est assez simple. si vous suivez WPCS, il vous encourage à suivre une convention de dénomination de classe précédée du mot classe et du nom de classe. bien entendu, tout trait de soulignement (_) est remplacé par un tiret (-).

donc un nom de fichier de classe WPSE_Postseraitclass-wpse-post.php

Diminuez les noms de classe de casse avec strtoloweret en utilisant str_replacepour remplacer les tirets bas par des tirets. donc WPSE_Postdevient maintenant wpse-post. enfin ajouter un préfixe class-sur la ligne suivante.

j'utilise is_readabledans une déclaration conditionnelle qui est échangeable avec file_exists. en supposant que YOUR_PLUGIN_PATHle chemin de base du plugin classes-direst sous le répertoire principal du plugin contenant toutes vos classes qui nécessitent un chargement automatique.

include_once est utilisé pour charger le fichier réel sur appel.

Usage:

il vous suffit d'inclure la classe de chargeur automatique ci-dessus dans le fichier de base de votre plugin

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

puis appelez vos cours sur demande.

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

Remarque: Je n'utilise pas la méthode namespace dans ma solution, elle peut donc ou non correspondre à vos besoins, mais publiée ici dans l'espoir que quelqu'un profite au moins des avantages du chargement dynamique des classes.


-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
Bien que le code de publication soit bon, vous devez expliquer comment et pourquoi cela répond à la question.
Laxmana

1
comme votre plugin n'est pas le seul plugin du système, le code qui charge juste les classes sans vérifier d'abord qu'elles sont à vous, va créer des problèmes tôt ou tard en essayant de charger le mauvais fichier pour une classe déclarée dans un autre plugin.
Mark Kaplun
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.