PHP:检查文件是否直接加载而不是包含?

Mar*_*ine 34 php file include

有没有办法阻止用户查看文件但仍然使用它包含在PHP中的另一个文件中?

Tyl*_*ter 52

如果你使用

define('APP_RAN'); 
Run Code Online (Sandbox Code Playgroud)

在包含它的文件中然后放入

if(!defined('APP_RAN')){ die(); }
Run Code Online (Sandbox Code Playgroud)

或者

defined('APP_RAN') or die();
Run Code Online (Sandbox Code Playgroud)

(这更容易阅读)

在包含的文件中,如果您直接访问它们将会死亡.


将所有包含的文件放在DocumentRoot上面可能会更好.

例如,如果您的索引页面位于

/my/server/domain/public_html
Run Code Online (Sandbox Code Playgroud)

你应该把包含的文件放入

/my/server/domain/
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的解决方案,它是基本网站保护的一部分. (2认同)

use*_*291 14

不要在文件中使用任何全局代码,只使用函数和方法.然后就没有必要关心包括与直接使用.

  • 同意; 如果有人设法猜测只包含函数和类的包含文件的名称,那么当他们尝试查看它时,他们所看到的只是一个空白页面.如果您输出带有include的html(我不喜欢这样做),您可以将其放入函数中,包含该文件,然后调用该函数. (3认同)

mgu*_*utt 14

我的建议:

<?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
}
?>
Run Code Online (Sandbox Code Playgroud)

1.)它检查是否直接调用,否则会抛出错误

2.)它输出一个404标准的apache错误页面(请与你原来的404页面比较或简单包含该页面)通过默默无闻添加安全性

3.)else文件在文件上传到实时环境时避免部分执行(PHP不等待"?>").如果包含的文件只包含一个函数/一个类,则不需要它.

  • 为了支持在Linux和Windows上托管的PHP,我使用str_replace('\\','/',_ _ FILE _ _)包装_ _ FILE _ _ (2认同)

tim*_*tim 11

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
Run Code Online (Sandbox Code Playgroud)


Eri*_*rik 10

只需将文件存储在Web根目录之外.


moe*_*eye 6

if (__FILE__ == $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']){
  die("Direct access forbidden");
}
Run Code Online (Sandbox Code Playgroud)

无论它在哪里,它都可以工作.(欢呼@col-sharpnel指出一个不完整但很好的解决方案.)


moe*_*eye 6

get_included_files函数.您可以像这样使用它:

if ( empty(get_included_files()) ) die("Direct access forbidden");
Run Code Online (Sandbox Code Playgroud)

  • 应该注意到PHP5,这种情况永远不会过去.请参阅[此文档中的评论](http://php.net/manual/en/function.get-included-files.php#45451).当前文件始终在数组中,因此数组总是至少有1个项目ergo永远不会为空.在PHP5 +中,可以尝试`if(count(get_included_files())=== 1)die("Direct access forbidden");`而不是. (3认同)