2026年9月19日
2026年9月19日
WordPressのプラグイン競合を特定・解決する方法
はじめに
WordPressのプラグイン競合は、プラグイン同士が同じ変数名・フック・JavaScriptライブラリを使うときに発生します。プラグインを1つずつ無効化する代わりに「二分探索法」で効率よく原因を特定できます。
症状・原因
- プラグインを追加した直後からサイトが壊れた・管理画面が白くなった
- 特定のページだけでJavaScriptエラーが出る
- 2つのプラグインを同時に有効にすると機能しなくなる
- フォームや決済機能が特定の組み合わせで動かなくなった
解決手順
ステップ1:WP_DEBUG でエラーを確認する
// wp-config.php: デバッグモードを有効化
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true); // /wp-content/debug.log に記録
define('WP_DEBUG_DISPLAY', false); // 画面には表示しない(本番環境)
define('SCRIPT_DEBUG', true); // 圧縮されていないスクリプトを使用
# エラーログをリアルタイムで監視
tail -f /var/www/html/wp-content/debug.log
# WP-CLI でエラーログを確認
wp eval "echo file_get_contents(WP_CONTENT_DIR . '/debug.log');" | tail -50
# プラグイン一覧を確認
wp plugin list --format=table
wp plugin list --status=active --format=count
ステップ2:二分探索法でプラグインを特定する
# 有効なプラグイン数を確認
wp plugin list --status=active --field=name
# ステップ①:全プラグインを無効化してサイトの動作を確認
wp plugin deactivate --all
# ステップ②:半分のプラグインを有効化(例: 10個中5個)
wp plugin activate plugin-a plugin-b plugin-c plugin-d plugin-e
# サイトを確認 → 問題が出ない場合: 残り5個に原因がある
# サイトを確認 → 問題が出る場合: 最初の5個に原因がある
# ステップ③:問題のある半分をさらに半分に絞る
# この手順を繰り返すことで log2(N) 回で特定できる
# 20個 → 最大5回で特定可能
# WP-CLI で自動的に二分探索するスクリプト
active_plugins=($(wp plugin list --status=active --field=name))
echo "Active plugins: ${#active_plugins[@]}"
# 全て無効化
wp plugin deactivate --all
echo "All deactivated. Test the site now."
ステップ3:JavaScriptの競合を解決する
# ブラウザのコンソールでJSエラーを確認
# よくあるエラー:
# "$ is not defined" → jQuery の読み込みタイミング問題
# "Cannot read property of undefined" → 依存関係の問題
# "Uncaught TypeError" → 同名関数の上書き
# 読み込まれているスクリプトを確認
wp eval "
global \$wp_scripts;
wp_print_scripts(); // スクリプトをキューに追加させる
foreach (\$wp_scripts->registered as \$handle => \$script) {
if (!empty(\$script->src)) {
error_log('[script] ' . \$handle . ': ' . \$script->src);
}
}
" 2>&1 | grep '\[script\]'
// functions.php: 競合するスクリプトを特定のプラグインのものに差し替える
// ❌ 2つのプラグインが同じスクリプトを異なるバージョンで登録している
// プラグインA: wp_enqueue_script('jquery', ..., '1.12.4');
// プラグインB: wp_enqueue_script('jquery', ..., '3.6.0');
// ✅ WordPressのコアjQueryを使うよう統一
add_action('wp_enqueue_scripts', function(): void {
// プラグインが登録した独自 jQuery を除去してコアのものを使う
wp_deregister_script('jquery');
wp_register_script('jquery', false, [], null, false);
wp_enqueue_script('jquery');
}, 100);
ステップ4:PHP 関数名・クラス名の競合を解決する
// ❌ 競合例: 2つのプラグインが同じ関数名を定義している
// Fatal error: Cannot redeclare my_helper_function()
// ✅ 解決方法1: function_exists() でチェックする
if (!function_exists('my_helper_function')) {
function my_helper_function(): string {
return 'result';
}
}
// ✅ 解決方法2: クラスに包む(名前空間の衝突を避ける)
namespace MyPlugin;
class Helper {
public static function myHelperFunction(): string {
return 'result';
}
}
// ✅ 解決方法3: 名前空間を使う
namespace MyPlugin\Utils;
function my_helper_function(): string {
return 'result';
}
ステップ5:フック競合を診断・解決する
// functions.php: 同じフックに登録されているコールバックを一覧表示
add_action('init', function(): void {
if (!isset($_GET['debug_hooks']) || !current_user_can('administrator')) {
return;
}
global $wp_filter;
$hook_name = $_GET['debug_hooks']; // ?debug_hooks=wp_footer
if (isset($wp_filter[$hook_name])) {
foreach ($wp_filter[$hook_name]->callbacks as $priority => $callbacks) {
foreach ($callbacks as $callback) {
$func = $callback['function'];
if (is_array($func)) {
$name = (is_object($func[0]) ? get_class($func[0]) : $func[0]) . '::' . $func[1];
} else {
$name = is_string($func) ? $func : '{closure}';
}
error_log(sprintf('[hook] %s @ priority %d: %s', $hook_name, $priority, $name));
}
}
}
exit;
});
// アクセス: https://example.com/?debug_hooks=wp_footer
注意事項
- 本番環境で
WP_DEBUG_DISPLAY=trueを設定するとPHPエラーがサイト訪問者に表示されます。必ずWP_DEBUG_DISPLAY=falseにした上でdebug.logを確認してください - プラグインの競合が解消できない場合は、どちらかのプラグインの開発者にissueを報告してください。多くの場合、プラグイン側でフックの優先度を調整することで解決できます
wp_deregister_script('jquery')でjQueryを上書きする際は、依存しているプラグインが壊れないか十分にテストしてください
まとめ
プラグイン競合の解決は①WP_DEBUG=true / WP_DEBUG_LOG=trueでdebug.logのPHPエラーを確認、②wp plugin deactivate --allから二分探索で半分ずつ有効化して原因を log2(N) 回で特定、③ブラウザコンソールのJSエラーと$wp_scriptsログでスクリプト競合を確認しwp_dequeue_scriptで除去、④PHP関数名の衝突はfunction_exists()チェックまたは名前空間で解消、⑤?debug_hooks=フック名で特定フックに登録されたコールバックを一覧表示して優先度の競合を特定します。