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=フック名で特定フックに登録されたコールバックを一覧表示して優先度の競合を特定します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲