プラグインで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の1人は、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でオートロードを行う最良の方法ですか?
ジョニー2014

いいえそうではありません。最速の方法は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自己クラスからメソッドを呼び出しています。このメソッドの最初の2行は次のとおりです。

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

かなりまっすぐです。WPCSに準拠している場合は、単語クラスとクラス名の接頭辞が付いたクラス命名規則に従うことをお勧めします。もちろん、アンダースコア(_)は(-)ダッシュに置き換えられます。

そのクラスのファイル名は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 2017

1
プラグインはシステム内の唯一のプラグインではないため、最初に自分のものであることを確認せずにクラスをロードするだけのコードは、別のプラグインで宣言されたクラスに誤ったファイルをロードしようとすることで、遅かれ早かれ問題を引き起こします。
Mark Kaplun、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.