2026年6月27日
2026年6月27日
Redirectionプラグインのエラーを解決する方法
はじめに
Redirectionでリダイレクトを設定しても302や301が正しく返らない・アクセスログが記録されない・.htaccessへの書き込みができない・設定したリダイレクトが無限ループを起こすといった問題は、REST APIの疎通・パーミッション・リダイレクト条件の設定ミスが原因です。
症状・原因
- リダイレクトを追加しても元のURLにアクセスすると404になる
- 「REST APIの接続テスト失敗」というエラーが管理画面に表示される
.htaccessを選択しても「ファイルへの書き込み権限がありません」とエラーになる- リダイレクト設定後にサイトが無限ループで表示できなくなった
解決手順
ステップ1:Redirectionの状態を確認する
# Redirectionのバージョンとリダイレクト一覧を確認
wp eval "
if (class_exists('Red_Plugin')) {
echo 'Redirection version: ' . REDIRECTION_VERSION . PHP_EOL;
}
// リダイレクト一覧を確認
\$items = Red_Item::get_all();
echo 'Total redirects: ' . count(\$items) . PHP_EOL;
foreach (array_slice(\$items, 0, 5) as \$item) {
printf(' [%s] %s → %s (hits: %d)' . PHP_EOL,
\$item->is_enabled() ? 'ON' : 'OFF',
\$item->get_url(),
\$item->get_action_data(),
\$item->get_hits()
);
}
"
# REST APIの疎通確認
wp eval "
\$response = wp_remote_get(rest_url('redirection/v1/redirect'), [
'headers' => ['X-WP-Nonce' => wp_create_nonce('wp_rest')],
]);
if (is_wp_error(\$response)) {
echo 'REST API error: ' . \$response->get_error_message() . PHP_EOL;
} else {
echo 'REST API status: ' . wp_remote_retrieve_response_code(\$response) . PHP_EOL;
}
"
ステップ2:リダイレクトをプログラムで管理する
// functions.php: Redirectionのプログラム管理
// ① リダイレクトをコードで追加
function add_redirect(string $source, string $target, int $code = 301): bool {
if (!class_exists('Red_Item')) return false;
$data = [
'url' => $source,
'action_type' => 'url',
'action_data' => ['url' => $target],
'match_type' => 'url',
'status' => 'enabled',
'group_id' => 1,
'action_code' => $code,
];
$item = Red_Item::create($data);
return !is_wp_error($item);
}
// ② 投稿スラッグ変更時に自動でリダイレクトを追加
add_action('post_updated', function(int $post_id, \WP_Post $post_after, \WP_Post $post_before): void {
if ($post_before->post_name === $post_after->post_name) return;
if ($post_after->post_status !== 'publish') return;
$old_url = get_permalink($post_before);
$new_url = get_permalink($post_after);
if ($old_url && $new_url && $old_url !== $new_url) {
add_redirect(
wp_make_link_relative($old_url),
wp_make_link_relative($new_url),
301
);
error_log(sprintf('[Redirection] Auto-redirect: %s → %s', $old_url, $new_url));
}
}, 10, 3);
// ③ 条件付きリダイレクト(モバイル端末の場合)
add_action('template_redirect', function(): void {
if (!is_singular('product')) return;
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$is_mobile = preg_match('/Mobile|Android|iPhone/i', $user_agent);
if ($is_mobile) {
$mobile_url = add_query_arg('view', 'mobile', get_permalink());
// wp_redirect($mobile_url, 302); // 必要に応じてコメント解除
}
});
ステップ3:REST APIと.htaccessの問題を解決する
// functions.php: REST API・.htaccess設定の修正
// ① REST APIへのアクセスを許可
add_filter('rest_authentication_errors', function($result) {
// Redirectionが使用するREST APIを認証エラーから除外
if (!empty($result)) {
$route = $GLOBALS['wp']->query_vars['rest_route'] ?? '';
if (str_starts_with($route, '/redirection/')) {
return null; // 認証エラーを無視
}
}
return $result;
});
// ② セキュリティプラグインによるREST API制限を解除
add_filter('rest_namespace_index', function(array $data): array {
// REST APIが正常に応答していることを確認するためのデバッグ用
$data['redirection_check'] = true;
return $data;
});
# .htaccessのパーミッションを確認・修正
ls -la /var/www/html/.htaccess
# .htaccessに書き込み権限を付与
chmod 644 /var/www/html/.htaccess
# Redirectionが生成するhtaccessルールを確認
wp eval "
\$groups = Red_Group::get_all();
foreach (\$groups as \$group) {
if (\$group->get_module_id() === 2) { // Apache module
echo 'Apache group: ' . \$group->get_name() . PHP_EOL;
\$items = Red_Item::get_for_group(\$group->get_id());
echo 'Redirects in group: ' . count(\$items) . PHP_EOL;
}
}
"
ステップ4:リダイレクトループを診断・修正する
// functions.php: リダイレクトループ防止
// ① リダイレクト前に循環チェック
add_filter('redirection_redirect_url', function(string $url, \Red_Item $item): string {
$source = $item->get_url();
// ソースとターゲットが同じ場合はリダイレクトをスキップ
if (parse_url($url, PHP_URL_PATH) === parse_url($source, PHP_URL_PATH)) {
error_log(sprintf('[Redirection] Loop detected: %s → %s', $source, $url));
return ''; // 空文字を返してリダイレクトをキャンセル
}
return $url;
}, 10, 2);
// ② 無限ループ発生時の緊急解除用コード
// wp-config.phpまたはfunctions.phpに一時的に追加して使用
// define('REDIRECTION_DISABLE', true);
# ループしているリダイレクトを特定・削除
wp eval "
\$items = Red_Item::get_all();
foreach (\$items as \$item) {
\$source = \$item->get_url();
\$target = \$item->get_action_data();
// ソース = ターゲット の場合
if (\$source === \$target || rtrim(\$source, '/') === rtrim(\$target, '/')) {
printf('Loop redirect found: ID=%d %s → %s' . PHP_EOL,
\$item->get_id(), \$source, \$target);
// \$item->delete(); // コメント解除で削除
}
}
"
ステップ5:リダイレクトのインポートとパフォーマンス
// functions.php: Redirectionのパフォーマンス最適化
// ① リダイレクトログを最適化
add_filter('redirection_log_days', function(int $days): int {
return 30; // ログ保持期間を30日に設定
});
// ② 高トラフィックページのリダイレクト確認をキャッシュ
add_filter('redirection_can_redirect', function(bool $can, string $url): bool {
$cache_key = 'redir_check_' . md5($url);
$cached = wp_cache_get($cache_key, 'redirection');
if ($cached !== false) {
return (bool)$cached;
}
wp_cache_set($cache_key, $can, 'redirection', 300); // 5分キャッシュ
return $can;
}, 10, 2);
# CSVからリダイレクトを一括インポート
wp eval "
// CSVフォーマット: old_url,new_url,status_code
\$csv_data = file_get_contents('/tmp/redirects.csv');
\$lines = explode(PHP_EOL, trim(\$csv_data));
\$count = 0;
foreach (\$lines as \$line) {
\$parts = str_getcsv(\$line);
if (count(\$parts) < 2) continue;
[\$source, \$target, \$code] = array_pad(\$parts, 3, '301');
\$data = [
'url' => trim(\$source),
'action_type' => 'url',
'action_data' => ['url' => trim(\$target)],
'match_type' => 'url',
'status' => 'enabled',
'group_id' => 1,
'action_code' => (int)\$code,
];
\$item = Red_Item::create(\$data);
if (!\$item->is_error()) \$count++;
}
echo 'Imported: ' . \$count . ' redirects' . PHP_EOL;
"
注意事項
- Redirectionは初期設定でWordPressのリダイレクト処理(PHPモジュール)を使用します。
.htaccessモジュールを選択すると処理が速くなりますが、AllowOverride AllがApacheで有効になっている必要があります - リダイレクト設定後に無限ループが発生した場合は
wp-config.phpにdefine('REDIRECTION_DISABLE', true);を一時的に追加してプラグインを無効化できます - REST APIエラーが表示される場合、WordfenceなどのセキュリティプラグインがREST APIへのアクセスをブロックしている可能性があります。「Wordfence → ファイアウォール → ブロック一覧」で
/wp-json/へのアクセスが許可されているか確認してください
まとめ
Redirection修復は①Red_Item::get_all()でリダイレクト一覧確認・REST API疎通テスト、②Red_Item::create()でプログラムによるリダイレクト追加・post_updatedフックでスラッグ変更時の自動リダイレクト、③rest_authentication_errorsフィルターでREST API認証エラーを解除・.htaccessパーミッション修正、④redirection_redirect_urlフィルターで循環リダイレクトを検知・REDIRECTION_DISABLE定数で緊急無効化、⑤redirection_log_daysフィルターでログ保持期間を設定しwp_cache_set()でリダイレクト確認をキャッシュする手順で解決します。