Devo usar spl_autoload_register () no meu plugin?

11

Quando uso spl_autoload_register no meu plug-in, recebo:

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

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

Eu li e encontrei várias correções. Um dos SO disse que não deve usar spl_autoload_register com o WordPress.

Isso é preciso?

Tenho certeza de que posso encontrar uma "correção" para o erro, mas não tenho certeza se quero fazer isso em cada versão do WP.

Se eu não usar a função de carregamento automático, como devo carregar minhas aulas? Aqui está o que quebra agora:

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

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

No aluno:

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

        }

    }
}

Esse design funciona bem fora do WordPress.

johnny
fonte
4
Eu atualizei minha resposta . Se você fizer certo - com uma função de retorno de chamada -, poderá usar spl_autoload_register()sem efeitos colaterais negativos.
fuxia
1
@toscho Seu código ainda é a melhor maneira de fazer o carregamento automático no WP?
precisa saber é
Não não é. A maneira mais rápida é acessar glob()o diretório uma vez e entregar as classes quando elas forem necessárias spl_autoload_register().
fuxia
1
Escreverei uma resposta posteriormente, mostrando nossa solução atual (ainda não publicada) da Multilingual Press.
fuxia

Respostas:

1

Eu realmente não tenho certeza se é uma boa ou má prática carregar automaticamente classes no plug-in WP. Para mim, não vejo efeitos colaterais do uso spl_autoload_register(desempenho não testado)

Então, para responder à sua pergunta, gostaria de compartilhar uma classe do meu próximo plug-in que estou usando para carregar automaticamente classes de um único diretório sem problemas e isso faz bem a mim até agora.

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

Para quebrar essa classe simples em partes, como você vê, estou usando o padrão Singleton. Constructoré privado e instance()& $_instancepertence ao padrão. Construtor tem spl_autoload_registerfunção.

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

que está chamando o loadmétodo da auto-classe. As duas primeiras linhas desse método são:

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

o que é bem direto. se você seguir o WPCS , o incentivará a seguir uma convenção de nomenclatura de classe prefixada com a palavra classe e depois o nome da classe. é claro que qualquer sublinhado (_) é substituído por (-) traço.

então um nome de arquivo da classe WPSE_Postseriaclass-wpse-post.php

Nomes de classes de caixa inferior com strtolowere usando str_replacepara substituir sublinhados por traços. então WPSE_Postagora se torna wpse-post. finalmente adicionando um prefixo class-na próxima linha.

Eu estou usando is_readablena declaração condicional que é permutável com file_exists. assumindo que YOUR_PLUGIN_PATHé o caminho base do plug-in e classes-direstá sob o diretório principal do plug-in, mantendo todas as suas classes que precisam de carregamento automático.

include_once é usado para carregar o arquivo real de plantão.

Uso:

você só precisa incluir a classe auto loader acima no arquivo base do seu plugin

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

e depois ligue para suas aulas sob demanda.

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

Nota: Não estou usando o método de espaço para nome na minha solução, para que ele possa ou não se adequar às suas necessidades, mas publicado aqui na esperança de que alguém pelo menos obtenha benefícios de carregar classes dinamicamente.

Anwer AR
fonte
-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
fonte
2
Embora o código de postagem seja bom, você deve explicar como e por que isso responde à pergunta.
Laxmana 22/02
1
como seu plug-in não é o único plug-in no sistema, o código que apenas carrega as classes sem verificar primeiro se são seus, criará problemas mais cedo ou mais tarde, tentando carregar o arquivo errado para uma classe declarada em outro plug-in.
precisa saber é o seguinte