PHP如何在.htaccess注释区间内无重复追加访问控制规则
.htaccess指定注释区间动态追加allow from规则实现方案
问题1:提取两个注释标记之间的现有内容
核心是使用支持跨行匹配的正则,避免多区间匹配出错:
- 正则使用
s修饰符,让通配符.可以匹配换行符 - 正则使用惰性匹配
.*?,确保只匹配到第一个# COMMENT_CLOSE #就停止,不会跨区间匹配 - 匹配代码示例:
$htcontent = file_get_contents('.htaccess'); $pattern = '/#\s*COMMENT_OPEN\s*#(.*?)#\s*COMMENT_CLOSE\s*#/s'; preg_match($pattern, $htcontent, $matches); $existingRules = $matches[1] ?? ''; // 拿到区间内现有规则
注意:如果文件中不存在两个标记对,$existingRules会返回空,建议提前判断标记是否存在避免后续替换失效
问题2:编辑后替换回原区间位置
核心是先判断规则是否重复,再全量替换整个注释区间(包含首尾标记),不会改动区间外的原有配置:
- 去重判断:对要新增的规则做精确匹配,避免重复写入
- 替换逻辑:用编辑后的新规则重新拼接首尾注释标记,替换原有的整个区间内容
- 完整实现代码:
// 配置项 $htaccessPath = __DIR__ . '/.htaccess'; $newRule = 'allow from 123.123.123.123'; // 替换为你要新增的规则 $commentStart = '# COMMENT_OPEN #'; $commentEnd = '# COMMENT_CLOSE #'; // 校验文件权限 if (!is_file($htaccessPath) || !is_readable($htaccessPath) || !is_writable($htaccessPath)) { die('.htaccess文件不存在或无读写权限'); } $content = file_get_contents($htaccessPath); $pattern = '/(' . preg_quote($commentStart, '/') . ')(.*?)(' . preg_quote($commentEnd, '/') . ')/s'; // 提取现有规则并去重判断 if (preg_match($pattern, $content, $matches)) { $existingContent = trim($matches[2]); // 规则不存在才追加 if (strpos($existingContent, $newRule) === false) { $newContentBlock = $commentStart . PHP_EOL . $existingContent . PHP_EOL . $newRule . PHP_EOL . $commentEnd; // 替换回原文件内容 $newHtcontent = preg_replace($pattern, $newContentBlock, $content); // 写入文件 file_put_contents($htaccessPath, $newHtcontent); echo '规则追加成功'; } else { echo '规则已存在,无需重复添加'; } } else { die('未找到指定的注释标记对'); }
注意:如果需要支持更宽松的规则匹配(比如忽略空格、换行),可以在判断是否存在的时候先对内容做格式化处理再匹配
内容的提问来源于stack exchange,提问作者Amr
相关产品推荐
相关产品推荐

