
在 PHP 开发中,可通过比较 __FILE__ 与 $_SERVER['PHP_SELF'] 的文件名来可靠识别脚本是否被直接请求(如通过浏览器访问),从而避免意外暴露数据或执行不安全逻辑。
在 php 开发中,可通过比较 `__file__` 与 `$_server['php_self']` 的文件名来可靠识别脚本是否被直接请求(如通过浏览器访问),从而避免意外暴露数据或执行不安全逻辑。
在 Web 应用中,常需将某些 PHP 文件设计为“仅作为工具模块被包含”,而非直接对外提供服务(例如返回 JSON 数据的接口脚本)。若未加防护,用户直接访问 GetCategories.php 就可能绕过业务逻辑、泄露数据库内容,甚至引发安全风险。
最常用且轻量的方法是利用 PHP 预定义常量与服务器变量进行比对:
<?php // GetCategories.php
require_once "Connection.php";
$query = mysqli_query($connection, "SELECT * FROM CATEGORIES");
$array = [];
while ($row = mysqli_fetch_assoc($query)) {
$array[] = $row;
}
// 判断是否被直接访问(即通过 HTTP 请求入口加载)
if (basename(__FILE__) === basename($_SERVER['PHP_SELF'])) {
// ✅ 直接访问:输出 JSON 供前端调用
header('Content-Type: application/json; charset=utf-8');
echo json_encode($array, JSON_NUMERIC_CHECK);
} else {
// ⚠️ 被 include/require 包含:仅准备数据,不输出
// 可选:将结果赋值给全局变量或返回数组,供调用方进一步处理
return $array;
}关键原理说明:
-
__FILE__是当前文件的绝对物理路径(如/var/www/app/GetCategories.php); -
$_SERVER['PHP_SELF']是当前 HTTP 请求所对应的入口脚本路径(如/GetCategories.php或/api/index.php); - 使用
basename()提取两者文件名后比对,可忽略路径差异,精准判断执行上下文。
✅ 优势: 无需额外配置、不依赖 URL 重写规则、兼容绝大多数 Apache/Nginx 环境。
⚠️ 注意事项:
- 若使用了
.htaccess重写或mod_rewrite(如将/api/cat重写为GetCategories.php),$_SERVER['PHP_SELF']会反映重写后的路径,此时该方法仍有效——因为重写后它仍等于basename(__FILE__); - 在 CLI 模式下
$_SERVER['PHP_SELF']可能未定义,如需支持命令行运行,请先做判空处理:$isDirect = isset($_SERVER['PHP_SELF']) ? (basename(__FILE__) === basename($_SERVER['PHP_SELF'])) : true;
进阶建议:
对于更健壮的架构,推荐将数据获取逻辑封装为函数或类方法,并在入口文件中统一控制输出行为,而非依赖文件加载方式判断。但上述 basename 方案仍是快速、清晰、低侵入的实用技巧,特别适合已有脚本的快速加固。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











