플러그인에서 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에있는 사람 은 WordPress와 함께 spl_autoload_register를 사용하지 말라고 말했습니다.

정확합니까?

오류에 대한 "수정"을 찾을 수 있다고 확신하지만 각 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에서 자동 로딩을 수행하는 가장 좋은 방법입니까?
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();

이 간단한 클래스를 부분적으로 나누려면 Singleton 패턴을 사용하고 있습니다. Constructor은 비공개이며 instance()& $_instance는 패턴에 속합니다. 생성자는 spl_autoload_register기능 이 있습니다.

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

load자체 클래스에서 메소드를 호출 합니다. 이 방법의 첫 두 줄은 다음과 같습니다.

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

꽤 똑바로입니다. WPCS 를 따르는 경우 단어 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
코드를 게시하는 것이 좋지만 이것이 어떻게 그리고 왜 질문에 대답하는지 설명해야합니다.
Laxmana

1
플러그인이 시스템의 유일한 플러그인이 아니기 때문에 먼저 자신의 클래스인지 확인하지 않고 클래스를로드하는 코드는 다른 플러그인에서 선언 된 클래스에 대해 잘못된 파일을로드하여 조만간 문제를 일으킬 것입니다.
Mark Kaplun
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.