You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP删除.htaccess中指定RewriteRule失败问题求助

解决PHP删除.htaccess指定RewriteRule失败的问题

问题场景

尝试通过PHP删除.htaccess中选中的RewriteRule规则,但系统提示无法找到对应规则,无法完成删除操作。.htaccess文件权限为644,相关代码及.htaccess内容如下:

用户提供的PHP代码(版本1)

<?php
if (isset($_GET['delete_id'])) {
    $delete_id = $_GET['delete_id'];

    // 获取要删除页面的slug
    $statement = $pdo->prepare("SELECT page_slug FROM tbl_page WHERE page_id=?");
    $statement->execute([$delete_id]);
    $page_slug = $statement->fetchColumn();

    $htaccess_path = '../.htaccess';
    $htaccess_content = file_get_contents($htaccess_path);

    $rewrite_rule = "RewriteRule ^".$page_slug."/?$ page/".$page_slug." [NC,L]";
    $pattern = "/".preg_quote($rewrite_rule, '/')."/";
    $htaccess_content = preg_replace($pattern, '', $htaccess_content, 1, $count);

    if ($count === 0) {
        $_SESSION['error_message'] = 'Error: Could not find RewriteRule for ' . $page_slug . ' in .htaccess';
    } else {
        // 将更新后的内容写回文件
        file_put_contents($htaccess_path, $htaccess_content);
        if ($htaccess_content === false) {
            $_SESSION['error_message'] = 'Error deleting RewriteRule from .htaccess';
        } else {
            $_SESSION['success_message'] = 'RewriteRule deleted successfully.';
        }
    }


    // 从数据库删除页面
    $statement = $pdo->prepare('DELETE FROM tbl_page WHERE page_id = ?');
    $statement->execute([$delete_id]);

    header('Location: ' . BASE_URL_ADMIN . 'page');
    exit;
}
?>

用户提供的PHP代码(版本2)

<?php
if (isset($_GET['delete_id'])) {
    $delete_id = $_GET['delete_id'];

    // 获取要删除页面的slug
    $statement = $pdo->prepare("SELECT page_slug FROM tbl_page WHERE page_id=?");
    $statement->execute([$delete_id]);
    $page_slug = $statement->fetchColumn();

    // 从.htaccess移除对应的RewriteRule
    $htaccess_path = '../.htaccess';
    if (file_exists($htaccess_path) && is_writable($htaccess_path)) {
        $htaccess_content = file_get_contents($htaccess_path);
        $htaccess_content = preg_replace("/RewriteRule \^" . preg_quote($page_slug, '/') . "\/?$ page\/" . preg_quote($page_slug, '/') . " \[NC,L\]\n?/m", '', $htaccess_content, 1, $count);

        if ($count === 0) {
            echo 'Error: Could not find RewriteRule for ' . $page_slug . ' in .htaccess';
        } else {
            file_put_contents($htaccess_path, $htaccess_content);

            if ($htaccess_content === false) {
                echo 'Error deleting RewriteRule from .htaccess';
            } else {
                echo 'RewriteRule for ' . $page_slug . ' has been successfully removed from .htaccess';
            }
        }
    } else {
        echo 'Error deleting RewriteRule from .htaccess';
    }
}
?>

当前.htaccess内容

RewriteEngine On

# If the requested file or directory does not exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Rewrite the URL to append .php and try again
RewriteRule ^([^\.]+)$ $1.php [NC,L]

# If the requested directory exists, add a trailing slash and try again
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]

RewriteRule ^ewewe/?$ page/ewewe [NC,L]
RewriteRule ^ffffff/?$ page/ffffff [NC,L]
RewriteRule ^demo/?$ page/demo[NC,L]

问题分析

  1. .htaccess语法错误:最后一条规则RewriteRule ^demo/?$ page/demo[NC,L]中,page/demo和[NC,L]之间缺少空格,这会导致Apache解析错误,同时直接让正则匹配失败。
  2. 正则匹配过于严格:现有正则要求规则完全匹配(包括空格、格式),但实际场景中可能存在多余空格、换行差异,或者规则参数格式变化,都会导致匹配失败。
  3. 代码逻辑缺陷:版本1未检查文件可写性,版本2的正则转义处理不够灵活,且部分逻辑判断错误(比如用读取的内容判断写入结果)。

解决方案

步骤1:修复.htaccess语法错误

先修正最后一条规则的空格问题,确保所有RewriteRule格式一致:

RewriteRule ^demo/?$ page/demo [NC,L]

步骤2:优化PHP删除逻辑

使用更灵活的正则表达式,允许规则前后有空格、换行,同时完善文件操作的错误检查。修改后的完整代码如下:

<?php
if (isset($_GET['delete_id'])) {
    $delete_id = $_GET['delete_id'];

    // 获取要删除页面的slug
    $statement = $pdo->prepare("SELECT page_slug FROM tbl_page WHERE page_id=?");
    $statement->execute([$delete_id]);
    $page_slug = $statement->fetchColumn();

    if (!$page_slug) {
        $_SESSION['error_message'] = 'Invalid page slug';
        header('Location: ' . BASE_URL_ADMIN . 'page');
        exit;
    }

    $htaccess_path = '../.htaccess';
    // 检查文件存在且可写
    if (!file_exists($htaccess_path)) {
        $_SESSION['error_message'] = '.htaccess file not found';
        header('Location: ' . BASE_URL_ADMIN . 'page');
        exit;
    }
    if (!is_writable($htaccess_path)) {
        $_SESSION['error_message'] = '.htaccess file is not writable';
        header('Location: ' . BASE_URL_ADMIN . 'page');
        exit;
    }

    $htaccess_content = file_get_contents($htaccess_path);
    if ($htaccess_content === false) {
        $_SESSION['error_message'] = 'Failed to read .htaccess file';
        header('Location: ' . BASE_URL_ADMIN . 'page');
        exit;
    }

    // 构建灵活的正则匹配规则:允许前后空格、规则内的任意空格,匹配整行
    $escaped_slug = preg_quote($page_slug, '/');
    $pattern = '/^\s*RewriteRule\s+\^' . $escaped_slug . '\/?\$\s+page\/' . $escaped_slug . '\s+\[NC,L\]\s*$/m';
    $new_content = preg_replace($pattern, '', $htaccess_content, 1, $count);

    if ($count === 0) {
        $_SESSION['error_message'] = 'Error: Could not find RewriteRule for ' . $page_slug . ' in .htaccess';
    } else {
        // 写回文件,检查写入结果
        $write_result = file_put_contents($htaccess_path, $new_content);
        if ($write_result === false) {
            $_SESSION['error_message'] = 'Error deleting RewriteRule from .htaccess';
        } else {
            $_SESSION['success_message'] = 'RewriteRule deleted successfully.';
        }
    }

    // 从数据库删除页面
    $statement = $pdo->prepare('DELETE FROM tbl_page WHERE page_id = ?');
    $statement->execute([$delete_id]);

    header('Location: ' . BASE_URL_ADMIN . 'page');
    exit;
}
?>

代码关键点说明

  • 灵活的正则:使用\s*匹配任意数量的空格(包括0个),配合/m多行模式匹配整行,确保即使规则前后有空格或换行也能准确匹配。
  • 完善的错误检查:依次检查文件存在性、可写性、读取状态,提前拦截错误。
  • 正确的写入验证:使用file_put_contents的返回值判断写入是否成功,避免之前逻辑中用读取内容判断写入结果的错误。

内容的提问来源于stack exchange,提问作者Nita Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:07:12