在php中包含from / with function

时间:2014-12-05 18:04:09

标签: php function include

我一直在努力使用包含另一个的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()函数包含内容,并且仍然可以传递变量,就像我立即包含文件一样?

(很抱歉复杂的描述,我试图简化我真正使用的代码,所以如果路径或语法中的任何错误不是真正的问题,而只是一些粘贴错误..!)

3 个答案:

答案 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);

使用函数包含文件时存在限制,但我首先描述的方法(无提取)可以帮助您区分哪些变量与包含哪些变量相关联。

我希望有用。