Чи варто використовувати spl_autoload_register () у своєму плагіні?


11

Коли я використовую spl_autoload_register у своєму плагіні, я отримую:

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

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

Я почитав і знайшов різні виправлення. Один на SO сказав, що не використовувати spl_autoload_register з WordPress.

Це точно?

Я впевнений, що можу знайти «виправлення» помилки, але я не впевнений, що хочу це робити з кожним випуском WP.

Якщо я не використовую функцію автозавантаження, як мені завантажувати свої класи? Ось що зараз перерва:

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

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

У студента:

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

        }

    }
}

Цей дизайн прекрасно працює поза WordPress.


4
Я оновив свою відповідь . Якщо ви зробите це правильно - з функцією зворотного дзвінка - ви можете використовувати spl_autoload_register()без негативних побічних ефектів.
fuxia

1
@toscho Ваш код все ще найкращий спосіб зробити автоматичне завантаження в WP?
Джоні

Ні, це не так. Найшвидший спосіб - glob()один раз потрапити в каталог, а потім доставити класи, коли вони потрібні spl_autoload_register().
fuxia

1
Відповідь я напишу пізніше, показуючи наше поточне (поки що не опубліковане) рішення від багатомовної преси.
fuxia

Відповіді:


1

Я дійсно не впевнений, чи є хорошою чи поганою практикою автоматичне завантаження класів у плагіні WP. Для мене я не бачу побічних ефектів використання spl_autoload_register(не перевірена продуктивність)

Тож, щоб відповісти на ваше запитання, я хотів би поділитися класом з мого майбутнього плагіна, який я використовую для автоматичного завантаження класів з одного каталогу без жодних проблем, і це добре для мене поки що.

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

Щоб зламати цей простий клас на частини, як ви бачите, я використовую шаблон Singleton. Constructorє приватним і instance()& $_instanceвідноситься до зразка. Конструктор має spl_autoload_registerфункцію.

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

який викликає loadметод із самокласу. Перші два рядки цього методу:

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

що досить прямо. якщо ви дотримуєтеся WPCS, це рекомендує вам дотримуватися конвенції іменування класу з префіксом word class, а потім іменем класу. Звичайно, будь-яке підкреслення (_) замінюється тире (-).

тому ім'я файлу класу WPSE_Postбуло бclass-wpse-post.php

Назви класів нижнього корпусу з strtolowerта за допомогою str_replaceзаміни підкреслювальних знаків штрихами. так WPSE_Postтепер стає wpse-post. нарешті додавання префікса class-у наступному рядку.

Я використовую is_readableв умовному заяві, з яким можна обмінятись file_exists. припустимо, що YOUR_PLUGIN_PATHце базовий шлях плагіна та classes-dirзнаходиться під основним режимом плагіна, у якому містяться всі ваші класи, які потребують автоматичного завантаження.

include_once використовується для завантаження фактичного файлу під час виклику.

Використання:

Вам просто потрібно включити вищевказаний клас автоматичного завантаження у базовий файл додатка

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

а потім зателефонуйте на заняття.

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

Примітка: я не використовую метод простору імен у своєму рішенні, тому він може або не може відповідати вашим потребам, але розміщений тут, сподіваючись, що хтось якнайменше отримає переваги завантаження класів динамічно.


-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
Хоча розміщення коду добре, ви повинні пояснити, як і чому це відповісти на питання.
Лаксмана

1
оскільки ваш плагін - не єдиний плагін у системі, код, який просто завантажує класи, не перевіряючи спочатку, що вони ваші, збирається створити проблеми рано чи пізно, намагаючись завантажити неправильний файл для класу, оголошеного в іншому плагіні.
Марк Каплун
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.