我一直在努力使用包含另一个的PHP脚本,所以我想我可以使用一些帮助......
基本上我想要的是将一个php文件(称之为content-1.php)包含在带有functions.php函数的base.php中。
我的想法是,我希望根据$ _GET变量包含不同的文件。我正在寻找这样的东西:
base.php
include("functions.php");
$api->getContent($_GET["content"]);
的functions.php
class api {
function getContent($content) {
if (isset($content)) {
if (file_exists("/content/" . $content . ".php")) {
return include("/content/" . $content . ".php");
}
}
return include("/content/content-1.php");
}
function getName() {
//Some function...
}
}
$api = new api;
内容1.PHP
echo "Hello world.";
echo $api->getName();
一切似乎都有效(呼应Hello World。),直到我尝试从内容1.php到达$ api。我得到一个“致命错误:调用非对象的成员函数”..
但是如果我将content-1.php直接包含在base.php中,那么它就像这样:
base.php
include("functions.php");
include("/content/content-1.php");
所有功能都可以调用$ api和所有内容!
所以,如果我没有太乱,我想知道如何用getContent()函数包含内容,并且仍然可以传递变量,就像我立即包含文件一样?
(很抱歉复杂的描述,我试图简化我真正使用的代码,所以如果路径或语法中的任何错误不是真正的问题,而只是一些粘贴错误..!)
答案 0 :(得分:0)
尝试$ this而不是$ api:
内容1.PHP
echo "Hello world.";
echo $this->getName();
答案 1 :(得分:0)
content-1.php
$api
的内部实际上是$this
;
<?php // content-1.php
$this->getName();
答案 2 :(得分:0)
发生这种情况的原因是$api
变量仅在函数范围之外可见。您可以在函数中添加一行:
function getContent($content) {
$api = $this;
// The rest of the code
}
旁注!
该函数中的代码存在严重的安全问题!可以像现在一样包含任何文件。如果$_GET['content']
的值等于'../../../passwords.txt'
(仅作为示例),则会包含文件passwords.txt
,访问者将能够查看您的所有密码。
要解决此问题,您应构建可用文件列表,以便选择可以包含的文件。为了使这更容易,可以动态完成。
function getContent($content) {
$api = $this; // Make the $api avaiable to included file.
$path = 'path/to/contents/directory';
$files = scandir($path);
// Remove the two 'dot' directories
$files = array_diff($files, ['.', '..']);
// Now you check if the provided $content file name exists and in fact is a file.
$filename = trim($content, '/.') . '.php';
if(in_array($filename, $files) && is_file($filename)) {
return include('/content/' . $filename);
}
return include('/content/content-1.php');
}
现在您可以确定攻击者只能包含contents
目录中的文件。
<强>更新强>
问题:
如何在包含文件中声明新变量并在执行
getContent()
函数的脚本中使用它们?
有一种方法可以在没有任何脆弱代码的情况下完成您的要求。您可以通过引用传递另一个将该数组声明为该函数的变量。该功能如下所示:
function getContent($content, array &$variables = []) {...
这种方法的限制是你只能声明如下的新变量:
$variables['new_variable_name'] = 'new_variable_value';
现在,当您调用该函数时,您可以选择传递另一个参数来声明一个数组。该数组将保存在包含文件中声明的变量。
$variables = [];
$api->getContent($content, $variables);
现在您可以像这样访问变量:
$variables['new_variable'];
您也可以extract()
将它们放入当前范围。这可能会导致问题,所以我添加了标志EXTR_SKIP
来表示PHP应该忽略具有相同名称的现有变量。您可以设置标记EXTR_PREFIX_ALL
并为extract($variables, EXTR_PREFIX_ALL, 'prefix')
提供第三个参数。这将为所有提取的变量添加前缀,并帮助您避免命名冲突。
extract($variables, EXTR_SKIP);
使用函数包含文件时存在限制,但我首先描述的方法(无提取)可以帮助您区分哪些变量与包含哪些变量相关联。
我希望有用。