考えたくない人向けのWordPressプラグインのベース

WordPress

プラグインをゼロから作りたくなどない。

なので、
いつもプラグインを作る際に使うざっくりベースを作って使っていたのだけどね…

久々にイジっていたら、ちょっと問題ありなので、作り直すことにした。
※最新版をすぐ見たい人は、目次から即とんでください。

元々のベース

何でもインスタンス化

インスタンス化とかもう忘れたから、もう最初から使えるようにしておいたやつ。
とりあえず作りたいだけならコレでもいいくらいだけど、まじでシンプル機能にはちょっと重い。

class BaseTemplate{

    public function __construct() {
        add_filter('the_content', [$this, 'filter_content']);
    }

    // コンテンツを加工するパターン
    public function filter_content($content) {
        global $post;
        /* なんやかんや */
        return $content;
    }
}
new BaseTemplate();

管理画面までセット

管理画面も作るちょっと複雑化したものは、これでいいやしてた。

class Base_template
{
    public static $package = "Base_template";
    public static $version = "1.0.0";
    public static $title   = "Base template";

    /// 処理追加の呼び出し
    public static function register_hooks()
    {
        add_action('admin_menu', array(__CLASS__, 'register_admin_hooks'));
        add_action('init', array(__CLASS__, 'register_action_hooks'));
    }

    /// 管理ページへのリンク
    public static function register_admin_hooks() {
        /* Admin bits */
        add_options_page(
            __("Configure ".self::$title, self::$package), // page title.
            __(self::$title, self::$package),              // menu title.
            'manage_options',                              // priv/capability
            self::$package.'-settings',                    // slug
            array(__CLASS__, 'settings_page'));            // 設定メニューに追加
    }

    /// 追加される管理ページ
    public static function settings_page($text) {
?>
なんたらかんたら
<?php
    }

    /// 実際の処理
    // rapper : init hook
    public static function register_action_hooks( $atts, $content = null )
    {
        add_shortcode('inside', array(__CLASS__, 'register_shortcode_hooks'));
    }

    // ショートコードの作成
    public static function register_shortcode_hooks( $atts, $content = null )
    {
        // パラメータ初期化
        $atts = shortcode_atts( array(
            'parameter1'      =&amp;amp;amp;gt; '',    // 入力内容
            'parameter1'  =&amp;amp;amp;gt; '',    // 変換対象ファイル(全部内部で処理)
        ),$atts, 'inside' );    
        $return = '';

        ob_start();
        /* なんやかんや */
        $return.= ob_get_clean();
        // 他のショートコードを処理する
        return do_shortcode($return);
    }
}
Base_template::register_hooks();

ただこの書き方だと、「インスタンス化(new)」がない。
複雑化なのか、シンプル化なのかー。

最新版

最終的に選んだ方法。

自分、何度勉強してもインスタンス化しない・するの分ける意味がよくわからんのよ。

「インスタンス化しない・するを分ける」のは、本来「メモリ効率」や「コードの再利用性」という、多人数開発で超大規模システムを作る時のための話。
からの結論としてこうなった。

迷うのめんどくさい用「ベース型」テンプレート

もう全部インスタンス化じゃああ

class Plugin_Base_Template
{
    // インスタンスを保持する箱
    private static $instance = null;

    // 1. フックの登録はここから始まる
    public static function boot()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 2. コンストラクタでフックを仕掛ける(ここが入り口)
    private function __construct()
    {
        // initとかより先に動かしたいフィルターはここで直書き
        add_filter('the_content', [$this, 'filter_content'],1);
        add_action('init', [$this, 'register_hooks']);
    }

    // 3. 実際の処理をここで書く
    public function register_hooks()
    {
        // 処理を書く。$this->変数名 で情報も保持できる
        add_shortcode('my_shortcode', [$this, 'do_something']);
    }

    public function do_something($atts)
    {
        return "動いてるよ!";
    }
}
// 固定
Plugin_Base_Template::boot();

この型の推しポイント

  1. 「new」はboot()の中だけ
    new をあちこちに書かなくていいから、プラグインの入り口が1つに確定する。
  2. private __construct
    他の場所から間違って new Plugin_Base_Template() されるのを防ぐ。
    必ず boot() を通るようになるから、二重起動も起きない。
  3. $this が使える
    処理の途中で「あ、この値後で使いたいな」と思っても、$this->key = 'value' でクラス内に保持できる。

可変型テンプレート

インスタンス化するか自分で都度決めたい版。

class Plugin_Base_Template
{
    // フック登録の入り口(static)
    public static function register_hooks()
    {
        // まずは静的に登録
        add_action('init', [__CLASS__, 'init_action']);
    }

    // 必要に応じてインスタンス化(new)
    public static function init_action()
    {
        // インスタンスが必要になったらここで生成
        $instance = new self();
        
        // インスタンスメソッドをフック
        add_shortcode('my_plugin', [$instance, 'render_content']);
    }

    // インスタンスメソッド($thisが使える)
    public function render_content()
    {
        return "インスタンス化してるよ!";
    }
}
Plugin_Base_Template::register_hooks();

さて

【WordPressプラグイン開発】静的メソッドか、インスタンスか?使い分け問題

プラグイン開発をしていると必ずぶつかる「new でインスタンス化するべきか、static で済ませるべきか」という問題。

結論から言えば、「処理の寿命」と「データの重さ」で使い分けるのが正解らしい。

静的メソッド(static)でいくべきとき

「使い切り」の処理。

向いているケース

  • フックの登録だけを行う「目次」のようなクラス。

  • 特定の値を渡すと加工して返すだけの「関数に近い」クラス。

  • データベースへの保存や、状態の保持が不要なもの。

メリット

インスタンスを作らない分、メモリを消費せず、コードがスッキリする。

インスタンス(new)でいくべきとき

「状態を保持」が必要なとき。

向いているケース

  • データベース連携
    get_option で取得した設定値を、クラス内で繰り返し参照したい場合。

  • 情報の蓄積
    複数のフックをまたいで「今のユーザーの状態」や「計算結果」を保持・共有したい場合。

  • 複雑な設定
    外部パラメータを受け取って、その内容によって処理を切り替える場合。

メリット

$this を使ってクラス内のプロパティに自由に値を保存できるから、デバッグや拡張が格段に楽になる。

まとめ:どっちから始める?

迷うなら全部インスタンス化しちまえばいいんじゃああああああ。

そんなことに脳みそ使うより、作ってまえばいいんじゃああああ。

迷っている間に非エンジニアに作ろうと思ってたやつ作られてるんじゃああああああ!!!

 

コメント

タイトルとURLをコピーしました