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

时间:2010-03-07 16:44:09

标签: php file include

有没有办法阻止用户查看文件但仍然将其用作PHP中另一个文件的附件?

15 个答案:

答案 0 :(得分:49)

如果您使用

define('APP_RAN'); 

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

if(!defined('APP_RAN')){ die(); }

或者

defined('APP_RAN') or die();

(这更容易阅读)

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


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

例如,如果索引页位于

/my/server/domain/public_html

您应该将包含的文件放在

/my/server/domain/

答案 1 :(得分:14)

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

答案 2 :(得分: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
}
?>

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

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

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

答案 3 :(得分:10)

只需将文件存储在网络根目录之外。

答案 4 :(得分:8)

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

答案 5 :(得分:6)

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

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

答案 6 :(得分:5)

get_included_files功能。您可以像这样使用它:

if ( empty(get_included_files()) ) die("Direct access forbidden");

答案 7 :(得分:2)

在Apache下,这很简单:在.htaccess中添加<Files>指令,以防止从Web浏览器访问它。这不适用于PHP includes,并且从浏览器访问中隐藏多个文件是一个好习惯(尽管通常您会尝试将所有不可访问的文件放在一个目录中)。

<Files="myprivatefile.php">
    deny from all
</Files>

在不同的Web服务器下,您可以将文件隐藏在文档根目录之外,但在某些情况下(例如,如果您的脚本是严格的open_basedir),它将无效。 / p>

答案 8 :(得分:2)

if($argv[0] == basename(__FILE__))
    include_once('/path/to/file.php');

答案 9 :(得分:2)

检查包含的文件数量......

if(count(get_required_files()) < 2) { die(); }

或者应该有多少最小值而不是2

答案 10 :(得分:1)

如果你想在不包含在这里时停止显示它是一种更自动化的方式。

if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) header("HTTP/1.0 404 Not Found");

这样,如果您最终更改文件名或其他内容,它仍然有效。

答案 11 :(得分:1)

这个帖子有很多好的答案 - 这里还没有提到过。

您可以在扩展程序中为i命名包含的PHP文件,例如: someincludedfile.phpi然后配置Apache,使其不提供phpi个文件。瞧。

缺点:

  • (!)高度依赖于Apache配置(如果有人忽略了那条线,你就会受到攻击) - 在这种情况下,浏览器可能会以纯文本形式看到整个PHP脚本,因为它赢了# 39; t传递给PHP(非常糟糕!)
  • 重命名包含的文件可能很烦人

优点:

  • 明确说明要包含哪些文件以及代码中没有哪些文件
  • 您不必移动文件层次结构

就个人而言,我宁愿将文件移动到文档根目录之外的目录中,但如果您有一个大型遗留应用程序,则可以更快地进行更改。

链接:http://www.ducea.com/2006/07/21/apache-tips-tricks-deny-access-to-certain-file-types/

答案 12 :(得分:0)

我会去Chacha102's solution

此外,正如您的问题标题所示«如何检查 »,您也可以执行此操作,而无需使用

定义变量
// secret.php is the name of this file.
if($_SERVER["SCRIPT_FILENAME"]=='secret.php') die();

答案 13 :(得分:0)

只是为了扩展$_SERVER变量的解决方案 - 下面是一个小的.php文件,在评论中是我在Ubuntu上做的bash测试的副本;关键是,根据访问类型,以及是否使用符号链接,这些变量可能会发生很大变化(注意,在下面的代码中,我必须在回声中转义'?\>'语句,否则语法颜色中断;如果尝试代码,则删除反斜杠):

<?php

function report($label, $value) {
  printf ("%23s: %s\n", $label, $value);
}

report("DOCUMENT_ROOT.PHP_SELF",  $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'] );
report("SCRIPT_FILENAME",         $_SERVER['SCRIPT_FILENAME'] );
report("__FILE__",                __FILE__ );
report("PHP_SAPI",                PHP_SAPI );

/*
# the test (bash):

home~$ mkdir /tmp/ptest
home~$ cd /tmp/ptest/
ptest$ ln -s /real/path/to/varcheck.php .
ptest$ echo '<? require_once "varcheck.php"; ?\>' > varcheckincl.php


# ... and in a separate terminal, run
# php (>5.4) cli server at same (/tmp/ptest) location:

ptest$ php-5.4.10 -S localhost:8000

# back to first terminal, the test - and output:

ptest$ php varcheck.php
 DOCUMENT_ROOT.PHP_SELF: varcheck.php
        SCRIPT_FILENAME: varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php -r 'require_once "varcheck.php";'
 DOCUMENT_ROOT.PHP_SELF: -
        SCRIPT_FILENAME:
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php varcheckincl.php
 DOCUMENT_ROOT.PHP_SELF: varcheckincl.php
        SCRIPT_FILENAME: varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ wget http://localhost:8000/varcheck.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheck.php
        SCRIPT_FILENAME: /tmp/ptest/varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server

ptest$ wget http://localhost:8000/varcheckincl.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheckincl.php
        SCRIPT_FILENAME: /tmp/ptest/varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server
*/
?>

答案 14 :(得分:-7)

你必须使用编码器和加载器PHP扩展:

商业