PHP - 有没有一种方法可以将字符串作为文件"include"进来?

7
已知一种方法可以在加载时将文件包含并捕获其内容到字符串中。
$string = get_include_contents('somefile.php');
function get_include_contents($filename) {
if (is_file($filename)) {
        ob_start();
        include $filename;
        return ob_get_clean();
    }
    return false;
}

https://www.php.net/manual/en/function.include.php

有没有一种方法可以从字符串中加载内容而不是从文件中“包含”它们?

我的意思是像这样:

$string = file_get_contents("file.php");
include_from_string($string);

2
有一个叫做 eval() 的函数。它可能是一个糟糕的想法。 - Álvaro González
尝试使用 eval() 是最佳选择。 - Sundar
5个回答

10
如果您希望将字符串解析为 PHP 代码,就像使用 include() 加载文件的内容一样,则需要使用 eval() 函数。
请注意,与 include() 加载的代码不同,由 eval() 执行的代码自动启动在 PHP 模式下,因此您不需要(也不应该!)使用 <?php 前缀。如果您想要精确地模拟 include() 的行为,则可以在将字符串传递给 eval() 之前用 ?> 前缀让其退出 PHP 模式。
$string = file_get_contents( 'somefile.php' );
eval( '?>' . $string );

另外请注意,eval() 是一个非常危险的函数!虽然在这种情况下,它应该不比 include() 本身更具风险,但是对于任何可能包含未经过滤(或未充分过滤)的用户输入的字符串使用 eval() 都是极其危险的,攻击者可能利用它在您的系统上执行恶意代码,从而控制您的系统。


1
_eval()_方法很简陋,但似乎没有其他方法。谢谢。 - Galileo

3
这可能不是你正在寻找的,但我有一个“解决方法”。

只需使用tempnam()创建临时文件,然后包含它,最后再用unlink()删除即可。

$path = "somefile.php";
$stringFile = file_get_contents($path);
$pathTmp = tempnam("tmp/", ""); // you pass directory in which you will store tmp files for me it's "tmp/"
$file = fopen($pathTmp, "w+");
fwrite($file,$widget);
fclose($file);
include $pathTmp; // include the file, and PHP will be automatically parsed
unlink($pathTmp); // delete file

错误的做法:

我不确定这是否是一种好的做法(但该死的,它很简单),因为没有人建议它,但比eval()更好,后者基本上是“代码危险”。

正确的做法:

正如@Chris Harrison所评论的那样,这是一种安全风险,等同于eval()。因此,你可以基本上这样做:

eval($string);

1
将任意代码进行“eval”和保存到文件并进行“include”的安全隐患完全相同。 - Chris Harrison
1
这是可以的,因为你的代码不会包含eval,它是一个合适的替代方案。 - NVRM

0

这是一个简单的示例,如果你将字符串传递到 eval() 中,它将执行字符串中的代码。

<?php 

//here your PHP Code goes
$string = get_include_contents('somefile.php');

//evaluating the string this will work
eval($string); //output

0

这与使用include不同。问题在于:eval()接受提供的PHP代码,并在当前环境中执行它。因此,任何全局变量、函数、类等你在eval()之前定义的内容都可以被处理器访问。这很好,返回时,原始(eval'd)字符串中仅剩下任何echo(或等效)语句的结果。

这与include不同。文件内容会与你的源代码合并,然后传递给eval()。非常非常不同。最简单的方法是将字符串定义为'class fu { static function bar() { echo "wow"; } }',将其放入文件中,并从你的代码中调用fu::bar(),你将看到“wow”显示出来。但是,在你的代码中的同一点上,如果你执行eval('class fu ...')并从你的代码中调用fu::bar(),你将得到“Fatal error: Call to private method fu::bar() from context ...”

但是,只要你不需要与“include”交互,结果看起来就是相同的。


-1

只需在函数内部使用echo而不是include即可输出所需内容!

更新

您的函数应该像这样:

$string = "Whatever";
$str = get_var($string);
function get_var($str) {
ob_start();
echo $str;
return ob_get_clean();
}

1
一旦您读取文件,它就被视为字符串。简单的 echo 在这种情况下无法帮助您。 - Sundar
你是什么意思?你正在缓冲输出,有什么问题吗? - Ashraf Samhouri
1
请检查下面的答案和内联注释,供您参考。 - Sundar
2
哦,我没有注意到他愿意评估内容!我的错。 - Ashraf Samhouri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接