有没有办法在php中的沙盒中执行php代码

时间:2008-11-27 22:12:52

标签: php module sandbox

我想从php执行一个php脚本,它将使用不同的常量和已经定义的不同版本的类。

我有没有沙箱php_module:

sandbox('script.php'); // run in a new php environment

而不是

include('script.php'); // run in the same environment

或者proc_open()是唯一的选择吗?

PS:无法通过网络访问该脚本,因此不能选择fopen('http://host/script.php')。

6 个答案:

答案 0 :(得分:10)

runkit,但如果您不需要主进程和子进程之间的任何交互,您可能会发现通过命令行调用脚本(使用shell_exec)会更简单。

答案 1 :(得分:5)

GitHub上的课程可能有所帮助,早期阶段但看起来很有希望。

https://github.com/fregster/PHPSandbox

答案 2 :(得分:2)

此外,您应该查看backtick operator

$sOutput = `php script_to_run.php`;

这将允许您检查正在运行的脚本的输出。但请注意,脚本将以您拥有的权限运行,但您可以通过在Linux上使用sudo来规避此操作。

此方法还假设您已安装PHP CLI,但情况并非总是如此。

答案 3 :(得分:1)

Runkit_Sandbox - 您可以使用它,它是PHP扩展。我想说的路要走。

但您可能需要创建自己的“沙盒”,例如:通过重置您使用的超全局变量的全局变量状态。

class SandboxState
{
    private $members = array('_GET', '_POST');
    private $store = array();
    public function save() {
        foreach($members as $name) {
            $this->store[$name] = $$name;
            $$name = NULL;
        }
    }
    public function restore() {
        foreach($members as $name) {
            $$name = $this->store[$name];
            $this->store[$name] = NULL;
        }

    }
}

用法:

$state = new SanddboxState();
$state->save();

// compile your get/post request by setting the superglobals
$_POST['submit'] = 'submit';
...

// execute your script:
$exec = function() {
    include(func_get_arg(0)));
};
$exec('script.php');

// check the outcome.
...

// restore your own global state:
$state->restore();

答案 4 :(得分:1)

我为此目的开发了一个获得BSD许可的沙盒类。它利用PHPParser库分析沙盒代码,针对用户可配置的白名单和黑名单进行检查,并提供各种配置选项以及理智的默认设置。根据您的需要,您可以轻松地重新定义沙盒代码中调用的类,并将它们路由到不同的类。

该项目还包括一个沙盒工具包(仅在本地计算机上使用!),可用于试验沙盒设置,以及完整的手册和API文档。

https://github.com/fieryprophet/php-sandbox

答案 5 :(得分:0)

我知道它不是100%主题相关,但可能对某人有用n__n

function require_sandbox($__file,$__params=null,$__output=true) {

    /* original from http://stackoverflow.com/a/3850454/209797 */

    if($__params and is_array($__params))
     extract($__params);

    ob_start();
    $__returned=require $__file;
    $__contents=ob_get_contents();
    ob_end_clean();

    if($__output)
     echo $__contents;
    else
     return $__returned;

};