ฉันควรใช้ 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

ฉันอ่านและพบการแก้ไขต่าง ๆ หนึ่งในนั้นบอกว่าจะไม่ใช้ spl_autoload_register กับ WordPress

ถูกต้องหรือไม่

ฉันแน่ใจว่าฉันสามารถหา "แก้ไข" สำหรับข้อผิดพลาด แต่ฉันไม่แน่ใจว่าฉันต้องการทำเช่นนั้นกับการเปิดตัว WP แต่ละครั้ง

หากฉันไม่ได้ใช้ฟังก์ชั่น autoload ฉันจะโหลดคลาสได้อย่างไร? นี่คือสิ่งที่แบ่งตอนนี้:

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 หรือไม่?
johnny

ไม่มันไม่ใช่. วิธีที่เร็วที่สุดคือการไดเรกทอรีครั้งเดียวแล้วส่งเรียนเมื่อพวกเขามีความจำเป็นต่อglob() spl_autoload_register()
fuxia

1
ฉันจะเขียนคำตอบในภายหลังโดยแสดงโซลูชันปัจจุบัน (ยังไม่เผยแพร่) ของเราจาก Multilingual Press
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();

เพื่อแบ่งคลาสแบบง่าย ๆ เป็นส่วน ๆ ตามที่คุณเห็นว่าฉันใช้รูปแบบซิงเกิล Constructorเป็นส่วนตัวและinstance()& $_instanceเป็นของรูปแบบ ตัวสร้างมีspl_autoload_registerฟังก์ชัน

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

ซึ่งเป็นloadวิธีการโทรจากระดับตัวเอง สองบรรทัดแรกจากวิธีนี้คือ:

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

ซึ่งค่อนข้างตรง ถ้าคุณติดตามWPCSจะเป็นการกระตุ้นให้คุณทำตามแบบแผนการตั้งชื่อคลาสที่ขึ้นต้นด้วยคำว่าclassและชื่อ class ofcourse เครื่องหมายขีดล่าง (_) ใด ๆ จะถูกแทนที่ด้วยเครื่องหมายขีด (-)

ดังนั้นชื่อไฟล์ของคลาส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
ถึงแม้ว่าการโพสต์รหัสจะดี แต่คุณควรอธิบายว่าทำไมตอบคำถามนี้ได้อย่างไร
Laxmana

1
เนื่องจากปลั๊กอินของคุณไม่ใช่ปลั๊กอินเดียวในระบบรหัสที่โหลดคลาสโดยไม่ต้องตรวจสอบก่อนว่าเป็นของคุณจะสร้างปัญหาไม่ช้าก็เร็วโดยพยายามโหลดไฟล์ผิดสำหรับคลาสที่ประกาศในปลั๊กอินอื่น
Mark Kaplun
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.