Haruskah saya menggunakan spl_autoload_register () di plugin saya?

11

Ketika saya menggunakan spl_autoload_register di plugin saya, saya mendapatkan:

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

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

Saya membaca dan menemukan berbagai perbaikan. Satu di SO mengatakan untuk tidak menggunakan spl_autoload_register dengan WordPress.

Apakah itu akurat?

Saya yakin saya dapat menemukan "perbaikan" untuk kesalahan, tetapi saya tidak yakin saya ingin melakukan itu dengan setiap rilis WP.

Jika saya tidak menggunakan fungsi autoload, bagaimana saya harus memuat kelas saya? Inilah yang istirahat sekarang:

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

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

Dalam siswa:

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

        }

    }
}

Desain ini berfungsi dengan baik di luar WordPress.

johnny
sumber
4
Saya telah memperbarui jawaban saya . Jika Anda melakukannya dengan benar - dengan fungsi panggilan balik - Anda dapat menggunakannya spl_autoload_register()tanpa efek samping negatif.
fuxia
1
@toscho Apakah kode Anda masih merupakan cara terbaik untuk melakukan autoloading di WP?
johnny
Tidak, bukan. Cara tercepat adalah ke glob()direktori sekali, lalu mengirimkan kelas ketika mereka diperlukan per spl_autoload_register().
fuxia
1
Saya akan menulis jawaban nanti, menunjukkan solusi kami saat ini (belum dipublikasikan) dari Multilingual Press.
fuxia

Jawaban:

1

Saya benar-benar tidak yakin apakah itu praktik yang baik atau buruk untuk memuat kelas secara otomatis di plugin WP. Bagi saya, saya tidak melihat efek samping dari penggunaan spl_autoload_register(kinerja tidak diuji)

Jadi untuk menjawab pertanyaan Anda, saya ingin membagikan kelas dari plugin saya yang akan datang yang saya gunakan untuk memuat kelas secara otomatis dari satu direktori tanpa masalah dan sejauh ini tidak ada gunanya bagi saya.

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

Untuk memecah kelas sederhana ini di bagian seperti yang Anda lihat saya menggunakan pola Singleton. Constructorbersifat pribadi dan instance()& $_instancemilik pola. Konstruktor memiliki spl_autoload_registerfungsi.

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

yang memanggil loadmetode dari kelas diri. Dua baris pertama dari metode ini adalah:

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

yang cukup lurus. jika Anda mengikuti WPCS itu mendorong Anda untuk mengikuti konvensi penamaan kelas yang diawali dengan kelas kata dan kemudian nama kelas. ofcourse setiap garis bawah (_) diganti dengan tanda hubung (-).

jadi nama file kelas WPSE_Postakan menjadiclass-wpse-post.php

Nama kelas casing bawah dengan strtolowerdan gunakan str_replaceuntuk mengganti garis bawah dengan garis putus-putus. jadi WPSE_Postsekarang menjadi wpse-post. akhirnya menambahkan awalan class-pada baris berikutnya.

Saya menggunakan is_readablepernyataan bersyarat yang dapat ditukar dengan file_exists. dengan asumsi YOUR_PLUGIN_PATHadalah jalur dasar plugin dan classes-dirberada di bawah dir plugin utama yang menahan semua kelas Anda yang membutuhkan autoloading.

include_once digunakan untuk memuat file aktual saat panggilan.

Pemakaian:

Anda hanya perlu memasukkan kelas pemuat otomatis di atas dalam file dasar plugin Anda

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

dan kemudian panggil kelas Anda sesuai permintaan.

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

Catatan: Saya tidak menggunakan metode namespace dalam solusi saya sehingga mungkin cocok atau tidak sesuai dengan kebutuhan Anda, tetapi diposting di sini dengan harapan bahwa seseorang setidaknya mendapatkan manfaat dari memuat kelas secara dinamis.

Anwer AR
sumber
-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
sumber
2
Meskipun memposting kode baik, Anda harus menjelaskan bagaimana dan mengapa ini menjawab pertanyaan.
Laxmana
1
karena plugin Anda bukan satu-satunya plugin dalam sistem, kode yang hanya memuat kelas tanpa memverifikasi dulu bahwa itu milik Anda, cepat atau lambat akan membuat masalah dengan mencoba memuat file yang salah untuk kelas yang dinyatakan dalam plugin lain.
Mark Kaplun