PHP:检查文件是否直接加载而不是包含?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2397004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP: Check if a file is loaded directly instead of including?
提问by Martti Laine
回答by Tyler Carter
If you use
如果你使用
define('APP_RAN');
in the file that includes it and then put
在包含它的文件中,然后把
if(!defined('APP_RAN')){ die(); }
or alternatively
或者
defined('APP_RAN') or die();
(which is easier to read)
(这更容易阅读)
in included files it would die if you access them directly.
在包含的文件中,如果您直接访问它们,它会死。
It would probably be better to put all of your included files above your DocumentRoot though.
不过,最好将所有包含的文件放在 DocumentRoot 之上。
For example, if your index page is at
例如,如果您的索引页位于
/my/server/domain/public_html
You should put the included files in
你应该把包含的文件放在
/my/server/domain/
回答by user187291
Do not use any global code in your files, only functions and methods. Then there will be no need to care about include vs. direct use.
不要在文件中使用任何全局代码,只使用函数和方法。那么就不需要关心包含与直接使用。
回答by mgutt
My proposal:
我的建议:
<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) {
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>404 Not Found</title>\r\n</head><body>\r\n<h1>Not Found</h1>\r\n<p>The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on this server.</p>\r\n</body></html>");
}
else {
// your code
}
?>
1.) it checks if it is called directly else it throws an error
1.) 它检查它是否被直接调用,否则它会抛出一个错误
2.) it outputs a 404 standard apache error page (please compare with your original 404 page or simple include that page) to add security through obscurity
2.) 它输出一个 404 标准 apache 错误页面(请与您原来的 404 页面进行比较或简单地包含该页面)以通过默默无闻来增加安全性
3.) The else-part avoids partial execution while the file is uploaded to the live environment (PHP doesn't wait for the "?>"). You don't need it if your included file contains only one function / one class.
3.) else 部分避免在文件上传到实时环境时部分执行(PHP 不等待“?>”)。如果包含的文件只包含一个函数/一个类,则不需要它。
回答by tim
if (!defined('FLAG_FROM_A_PARENT'))
// Works in all scenarios but I personally dislike this
if (__FILE__ == get_included_files()[0])
// Doesn't work with PHP prepend unless calling [1] instead.
if (__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME'])
// May break on Windows due to mixed DIRECTORY_SEPARATOR
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']))
// Doesn't work with files with the same basename but different paths
if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']))
// Seems to do the trick
回答by Erik
Just store the file outside your web root.
只需将文件存储在您的网络根目录之外。
回答by moebius_eye
There's the get_included_filesfunction. You could use it like so:
有get_included_files函数。你可以像这样使用它:
if ( empty(get_included_files()) ) die("Direct access forbidden");
回答by moebius_eye
if (__FILE__ == $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']){
die("Direct access forbidden");
}
It works regardless of where it is. (Cheers to @col-sharpnel for pointing out an incomplete yet good solution.)
无论它在哪里,它都可以工作。(感谢@col-sharpnel 指出了一个不完整但很好的解决方案。)
回答by HelpNeeder
Check how many included files are there...
检查有多少包含文件...
if(count(get_required_files()) < 2) { die(); }
Or how many minimum there should be rather than 2
或者应该有多少个最小值而不是 2
回答by zneak
Under Apache, this is easy: add a <Files>directive in your .htaccess to prevent access to it from a web browser. This doesn't apply to PHP includes, and it is a good practice to hide several files from browser access (though usually you'll try to put all the non-accessible files together in a single directory).
在 Apache 下,这很容易:<Files>在您的 .htaccess 中添加一个指令以防止从 Web 浏览器访问它。这不适用于 PHP includes,并且从浏览器访问中隐藏多个文件是一个很好的做法(尽管通常您会尝试将所有不可访问的文件放在一个目录中)。
<Files="myprivatefile.php">
deny from all
</Files>
Under a different web server, you can hide the file out of your document root, but under some cases (like if your scripts are open_basedir'd in a strict way), it won't work.
在不同的 Web 服务器下,您可以将文件隐藏在文档根目录之外,但在某些情况下(例如,如果您的脚本open_basedir以严格的方式进行),它将不起作用。
回答by ZeekDaGeek
If you want to stop it from ever being displayed when not included here's a more automated way.
如果您想阻止它在未包含时显示,这里有一种更自动化的方式。
if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) header("HTTP/1.0 404 Not Found");
This way it'll still work if you end up changing the file name or something.
这样,如果您最终更改文件名或其他内容,它仍然可以工作。

