我正在制作一个使用URL查询访问应用程序不同部分的Web应用程序。我正在寻找一个解决方案,使index.php?page=dashboarrrd
这样的无效查询显示错误404消息,而不是PHP错误。
经过一番搜索后,我发现我可以使用以下内容来完成这项工作:
if(!@include($fileName)){
@include("pageData/404.php");
}
这是有道理的,但我不知道为什么有效。我的意思是,@
之前include
的意思是什么?我完全理解include $filename;
,但我需要@include ($fileName)
答案 0 :(得分:9)
这是@
Error Control Operator (引用):
当加入表达式时 PHP,可能是任何错误消息 由该表达式生成的将是 忽略。
在正常情况下,如果include
无法加载您作为参数传递的文件,则会发出警告。
将 @
操作符添加到 include
将阻止该警告被发出 - 因此,显示/记录该警告。
那么,以下代码部分:
include 'does-not-exist.php';
会给你以下警告:
Warning: include(does-not-exist.php) [function.include]: failed to open stream: No such file or directory
Warning: include() [function.include]: Failed opening 'does-not-exist.php' for inclusion
这一行:
@include 'does-not-exist.php';
不会警告你。
作为旁注,有关信息: Five reasons why the shut-op operator (@) should be avoided
答案 1 :(得分:8)
您真正需要的代码
$fileName = "pagedata/".basename($_GET['page']).".php";
if(is_readable($fileName)) {
include($fileName);
} else {
include("pagedata/404.php");
}
和@在这里完全无关
@是缺乏经验的最大妄想之一 使用它的人确实希望只有一种错误,而事实上可能会有更多错误。并且禁止所有可能的消息来压制他们中的一个肯定是想把孩子和洗澡一起扔掉。
存在一个基本问题,使得这种误解如此普遍:
大多数PHP用户无法区分错误控制的三个方面:
大多数时候,为了[3],人们会混淆(1)和(2)。虽然每个都需要单独处理:
is_readable()
完全是为了那个。 404.php
就是这种用户友好行为的一个很好的例子。至于系统错误消息,用户根本不应该看到它们。只需关闭display_errors
并查看 - 再次使用@!答案 2 :(得分:3)
@
可以抑制错误。这通常是不鼓励的,因为在开发时你想看到错误。
移动到display_errors
设置为off
的生产环境时,很容易抑制错误。所以,在大多数情况下,确实不需要抑制错误。
修改强>
作为“改进”的额外花絮,我在动态包含文件时曾经做过的事情是array
,它充当有效请求的“白名单”。这不是“必须”成为array
,正如我选择做的一样。
$whiteList = array('filename1', 'index', 'home', 'about');
if (in_array($filename, $whiteList)) {
include($filename);
}else {
include('page/404.php');
}
这会做一些事情,1让你不需要错误抑制器。第二,它会使它更安全,因为没有这个,你需要进行basename
调用来过滤文本以防止某些类型的包含注入等。(不知道你是否已经这样做了,只是额外的信息)。
所以,你可能需要分析/看其他方法来实现这一目标,上面只是一种方法:)
答案 3 :(得分:1)
使用“@”只会抑制通常由(在这种情况下)丢失文件导致的错误。虽然通常使用非常糟糕的主意,但有一些罕见的例外情况,例如您在上面提供的代码段。
有关详细信息,请参阅PHP手册的Error Control Operators部分。
此外,您可能会发现现有的Reference - What does this symbol mean in PHP?问题值得快速扫描。
答案 4 :(得分:0)
php中的@
会抑制所有错误输出。例如,如果您有警告的错误报告,则在生成警告的函数前面的@不会显示警告文本。
include
就是这种结构的一个例子。如果找不到包含的文件,它将显示一条警告。在代码中根本不需要@,它就在那里,以便用户不会看到警告。
但是,最好使用apache(或者如果您愿意,还可以使用php)更改ini,以便在开发站点上显示错误,而不是在生产站点上显示错误。这会使@符号无用。
更好的问题是为什么你需要这样做404包括。为什么要包含要显示的文件?为什么不让apache自己处理404重定向?为什么文件首先不存在?
答案 5 :(得分:0)
@
会抑制错误消息。括号在include
中是可选的,但是编写该片段的人都包括它们。
答案 6 :(得分:0)
@include()
与require()
相反。第一个将默默地忽略(可选和缺少)包含脚本,而第二个将抛出错误并在缺少(关键)依赖关系时暂停脚本。
在这种情况下,它只在if()
内有意义。第二个应该优先没有错误抑制,因为它不会掩盖任何严重的安全相关错误消息。