2026年5月20日
2026年5月20日
WordPressのマストユースプラグイン(mu-plugins)とは?仕組み・作り方・注意点
マストユースプラグイン(Must-Use Plugins、略して mu-plugins)は、wp-content/mu-plugins に PHP ファイルを置くだけで常に読み込まれ、管理画面から停止できない特別なプラグインです。テーマを切り替えても動き続け、誤って無効化される心配もないため、サイトに欠かせない処理を置く場所として使われます。この記事では、通常のプラグインとの違い、読み込み順、サブディレクトリが自動では読み込まれない問題、有効化フックが動かない問題とその対処を、2026年10月現在の WordPress の仕様に沿って解説します。
なお「マストユース」は「導入必須のおすすめプラグイン」という意味ではなく、WordPress コアの仕組みの名前です。管理画面の「プラグイン」一覧に「マストユース」というタブが出ていれば、そこに表示されているのがこの仕組みで読み込まれているファイルです。
通常のプラグインとの違い
mu-plugins の性質は、通常のプラグインと比べると理解しやすくなります。
| 項目 | 通常のプラグイン | マストユースプラグイン |
|---|---|---|
| 置き場所 | wp-content/plugins/ |
wp-content/mu-plugins/ |
| 有効化・停止 | 管理画面から操作 | 置くと常に有効。停止はファイルの移動・削除 |
| 読み込み時期 | mu-plugins の後 | 通常のプラグインより先 |
| 有効化・停止フック | 動作する | 動作しない |
| 管理画面からの更新 | 可能(配布元による) | 更新通知も自動更新もない |
| サブディレクトリ | 1階層下まで自動で探す | 直下の PHP ファイルだけ |
マルチサイトでは、mu-plugins はネットワーク内のすべてのサイトで読み込まれます。サイトごとに有効・無効を切り替える仕組みはないため、サイトによって処理を変えたい場合はコード内で条件分岐します。
mu-plugins を作る手順
mu-plugins フォルダーは初期状態では存在しないことが多いので、wp-content の直下に自分で作成します。その中に PHP ファイルを1つ置きます。
<?php
/**
* Plugin Name: Site Core Functions
* Description: このサイト固有の基本処理(テーマに依存しないもの)。
* Version: 1.0.0
*/
defined( 'ABSPATH' ) || exit;
// 例: wp_head に WordPress のバージョン表記(generator)を出力しない
remove_action( 'wp_head', 'wp_generator' );
ファイル名は site-core.php のように分かりやすいものにします。保存したら管理画面の「プラグイン」を開き、「マストユース」のタブにプラグイン名が表示されているかを確認します。ヘッダーコメントがなくても読み込みは行われますが、一覧での表示名がファイル名になり、何のためのファイルか分かりにくくなるので、ヘッダーは書いておくことをおすすめします。
置き場所のパスは定数 WPMU_PLUGIN_DIR、URL は WPMU_PLUGIN_URL で参照できます。wp-config.php でこれらを定義すれば場所を変更できますが、ホスティング会社が独自のファイルを置いている環境もあるため、特別な理由がなければ標準の場所を使います。
読み込み順とタイミング
mu-plugins は wp-settings.php の処理の中で、通常のプラグインより先に読み込まれます。大まかな順番は次のとおりです。
- mu-plugins の PHP ファイルを読み込む(ファイル名のアルファベット順)
muplugins_loadedアクションが実行される- 通常のプラグインを読み込む
plugins_loadedアクションが実行される- テーマの
functions.phpを読み込み、after_setup_theme、initへと進む
ここから分かる注意点が2つあります。
1つ目は、mu-plugins 同士の順序がファイル名で決まることです。あるファイルで定義した関数を別のファイルで使うなら、00-helpers.php のように接頭辞を付けて順序を制御するか、後述のローダーで明示的に読み込む順を決めます。
2つ目は、ファイルが読み込まれた瞬間にはまだ使えない機能が多いことです。通常のプラグインの関数やクラスはまだ存在せず、ログインユーザーの判定に関わる wp_get_current_user() などの差し替え可能な関数(pluggable.php)も読み込まれていません。そのため、ファイルの直下で処理を実行するのではなく、plugins_loaded や init などのフックに登録して、必要な機能がそろってから動かすのが基本です。
add_action( 'init', function () {
if ( ! is_user_logged_in() ) {
return;
}
// ログイン中のユーザーにだけ行いたい処理
} );
逆に「通常のプラグインより先に何かを仕掛けたい」場合、たとえば特定のプラグインの読み込み前にフィルターを登録しておきたい場合は、mu-plugins の早さが役に立ちます。
サブディレクトリは自動で読み込まれない
通常のプラグインは plugins/my-plugin/my-plugin.php のようにフォルダーに入れて管理しますが、mu-plugins では mu-plugins/my-plugin/my-plugin.php に置いても読み込まれません。WordPress が探すのは mu-plugins 直下の .php ファイルだけだからです。配布されているプラグインを mu-plugins として使いたい場合や、複数ファイルで構成したい場合は、直下にローダー用のファイルを置き、そこから読み込みます。
<?php
/**
* Plugin Name: MU Loader
* Description: mu-plugins 配下のサブディレクトリにあるプラグインを読み込む。
*/
defined( 'ABSPATH' ) || exit;
$mu_loader_files = array(
'site-functions/site-functions.php',
'security-tweaks/security-tweaks.php',
);
foreach ( $mu_loader_files as $mu_loader_file ) {
$mu_loader_path = WPMU_PLUGIN_DIR . '/' . $mu_loader_file;
if ( is_readable( $mu_loader_path ) ) {
require_once $mu_loader_path;
}
}
unset( $mu_loader_files, $mu_loader_file, $mu_loader_path );
フォルダーを自動で走査する書き方もできますが、読み込むファイルを配列で明示しておくと、意図しないファイル(テスト用ファイルやバックアップのコピー)を読み込む事故を防げます。is_readable() で存在を確認しているのは、ファイルを移動しただけでサイト全体が致命的エラーになるのを避けるためです。
通常のプラグインを mu-plugins に移すと、そのプラグインのアクティベーション処理(後述)や管理画面からの更新は動かなくなります。移す前に、そのプラグインが有効化時にテーブル作成やオプション登録をしていないかを確認してください。
有効化フックが動かない問題と対処
register_activation_hook() と register_deactivation_hook() は、管理画面でプラグインを有効化・停止したときに呼ばれる仕組みです。mu-plugins には有効化という操作がないため、これらに登録した処理は実行されません。アンインストール時の処理も同様です。
初回だけ行いたい処理(オプションの初期値登録、独自テーブルの作成など)は、保存しておいたバージョン番号と比較して、違うときだけ実行する方法で代用します。
add_action( 'init', function () {
$current_version = '1.1.0';
if ( get_option( 'site_core_version' ) === $current_version ) {
return;
}
// 初回またはバージョンが上がったときだけ行う処理
if ( false === get_option( 'site_core_settings' ) ) {
add_option( 'site_core_settings', array( 'notice' => '' ) );
}
update_option( 'site_core_version', $current_version );
} );
毎回のリクエストで実行されるのはオプションの比較だけなので、負荷はほとんどかかりません。重い処理を入れる場合は、管理画面のみ(admin_init)に限定するとさらに安全です。
よくある使い道
mu-plugins に向いているのは「テーマにもプラグインの有効・無効にも左右されてはいけない処理」です。
- サイト固有の基本機能: カスタム投稿タイプの登録など、テーマを変えても失いたくないもの
- セキュリティ・運用の設定: XML-RPC の無効化、ログイン関連の制御、ヘッダーの調整など
- 環境ごとの切り替え:
wp_get_environment_type()を使い、開発環境ではメール送信を止める、外部連携プラグインを読み込ませないといった制御
環境によってプラグインの読み込みを止める場合、option_active_plugins フィルターで有効なプラグインの一覧から除外する方法が知られています。ただし管理画面でこのフィルターが効いたまま別のプラグインを有効化すると、除外された一覧がそのまま保存されてしまうことがあります。管理画面と WP-CLI の実行時は対象外にするなど、適用範囲を絞ってください。
add_filter( 'option_active_plugins', function ( $plugins ) {
if ( is_admin() || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
return $plugins;
}
if ( 'production' === wp_get_environment_type() ) {
return $plugins;
}
// 本番以外では外部配信用のプラグインを読み込まない
return array_values( array_diff( (array) $plugins, array( 'example-cdn/example-cdn.php' ) ) );
} );
トラブル時の対処
mu-plugins で致命的エラーが起きると、管理画面からは停止できません。サイトが表示されなくなったら、FTP やファイルマネージャー、SSH で mu-plugins 内の該当ファイルの名前を site-core.php.off のように変えると読み込みが止まります(.php で終わらないファイルは読み込まれないため)。原因の特定には wp-config.php で WP_DEBUG と WP_DEBUG_LOG を有効にし、wp-content/debug.log を確認します。
また、更新通知が出ないため、外部から入手したコードを mu-plugins に置いた場合は、脆弱性の修正が出ていないかを自分で追う必要があります。WP-CLI では wp plugin list --status=must-use で一覧を確認できるので、定期的な棚卸しに使えます。ファイルを編集・削除する前には、サイトのバックアップを取っておきます。
まとめ
- マストユースプラグインは
wp-content/mu-plugins直下の PHP ファイルで、常に有効・管理画面から停止不可です。 - 通常のプラグインより先に、ファイル名順で読み込まれます。他プラグインの機能やログイン判定は
initなどのフック内で使います。 - サブディレクトリは自動で読み込まれないので、直下のローダーから
require_onceします。 - 有効化・停止フックは動かないため、バージョン番号を比較する方法で初回処理を代用します。
- 更新通知がなく、エラー時は管理画面から止められない点を踏まえ、置くコードは自分で管理できる範囲にとどめます。