結論から。プラグインファイルから pluggable.php の関数を少しでも早く使用したい場合、__construct では早すぎるので、”plugins_loaded”というアクションフックに引っ掛けましょう。

プラグインのファイルを作成してWordPressをカスタマイズする際、さまざまな処理を実行させるタイミングをいかにコントロールするかってのがかなり肝であると言うことに最近ようやく気づいたのですが、全体像を掌握することはとても骨の折れる作業なので、今日もこうして断片的な知識をメモします。

さて、さっき一つ気づいたことをメモ。

プラグインを開発するときに重宝する関数がまとめられた pluggable.php というWordPressが提供するファイルがあります。

たとえばログイン中のユーザー情報を知りたい場合などは、ここで定義された

function get_currentuserinfo()

を使うととても便利。

だけど、これをプラグインのコンストラクタで使うことは出来ない。というのも、このファイルのロードはプラグインファイルのロードの直後に行われているからです(/wp-settings.php)

// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin )
    include_once( $plugin );
unset( $plugin );

// Load pluggable functions.
require( ABSPATH . WPINC . '/pluggable.php' );
require( ABSPATH . WPINC . '/pluggable-deprecated.php' );

// Set internal encoding.
wp_set_internal_encoding();

// Run wp_cache_postload() if object cache is enabled and the function exists.
if ( WP_CACHE && function_exists( 'wp_cache_postload' ) )
    wp_cache_postload();

do_action( 'plugins_loaded' );

なので、プラグインの処理において、なるべく早くこのファイルの関数を用いたいと思ったとしても、コンストラクタでは使用できないので、何らかのフックに引っ掛けるしかありません。

そこで、そのような目的にぴったりのアクションフックが上記の引用の最後に登場してます。

plugins_loaded

です。名前のまんま。

つまり、

class MyInvalidPluginClass
{
    var $user_id;

    function __construct()
    {
        global $userinfo;
        get_currentuserinfo();    // called undefined function エラーが発生します。
        $this -> user_id = $userinfo -> ID;
    }
}

ではダメなのですが、

class MyValidPluginClass
{
    var $user_id;

    function __construct()
    {
        // plugins_loaded のタイミングなら、 pluggable.php はロードされているのでOK
        add_action( 'plugins_loaded', array( &$this, 'initialize' ) );
    }

    function initialize()
    {
        global $userinfo;
        get_currentuserinfo();
        $this -> user_id = $userinfo -> ID;
    }
}}

のようにすれば大丈夫。