web-dev-qa-db-ja.com

私のプラグインでspl_autoload_register()を使うべきですか?

私のプラグインで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つに、ワードプレスで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の外でうまく機能します。

10
johnny

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' ) );

これはselfクラスからloadメソッドを呼び出しています。このメソッドの最初の2行は、

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

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

そのため、クラスWPSE_Postのファイル名はclass-wpse-post.phpになります。

strtolowerを使用し、str_replaceを使用してアンダースコアをダッシュ​​に置き換えると、大文字と小文字が区別されないクラス名になります。だからWPSE_Postwpse-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
Anwer AR