Я хочу выполнить 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 ') не является вариантом.
Существует runkit , но вам может быть проще просто вызвать скрипт над командной строкой (используйте shell_exec ), если вам не требуется никакого взаимодействия между основным и дочерним процессами.
Это класс на GitHub, который может помочь, на ранних этапах, но выглядит многообещающим.
Кроме того, вы должны посмотреть на оператора backtick :
$sOutput = `php script_to_run.php`;
Это позволит вам проверять вывод из сценария, который вы используете. Однако обратите внимание, что скрипт будет запущен с вашими привилегиями, но вы можете обойти это, используя sudo в Linux.
Этот подход также предполагает, что у вас установлен CLI PHP, что не всегда так.
Существует 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();
в$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();
Для этой цели я разработал BSD-лицензированный класс песочницы. Он использует библиотеку PHPParser для анализа изолированного кода, проверки его против настраиваемых пользователем белых списков и черных списков, а также широкий выбор параметров конфигурации наряду со стандартными настройками по умолчанию. Для ваших нужд вы можете легко переопределить классы, называемые вашим изолированным кодом, и перенаправить их на разные.
Проект также включает в себя инструментарий для песочницы (используется только на вашем локальном компьютере!), Который можно использовать для экспериментов с настройками песочницы, а также полную документацию по ручному и API-интерфейсу.
динамическое выполнение функции плагина, которое позволяет загруженному файлу и функции выполнять все, что угодно, но может принимать и возвращать переменные, которые могут быть json_encode
.
function proxyExternalFunction($fileName, $functionName, $args, $setupStatements = '') { $output = array(); $command = $setupStatements.";include('".addslashes($fileName)."');echo json_encode(".$functionName."("; foreach ($args as $arg) { $command .= "json_decode('".json_encode($arg)."',true),"; } if (count($args) > 0) { $command[strlen($command)-1] = ")";//end of $functionName } $command .= ");";//end of json_encode $command = "php -r ".escapeshellarg($command); exec($command, $output); $output = json_decode($output,true); }
внешний код полностью изолирован, и вы можете применять любые разрешения, которые вы хотите, выполнив sudo -u restricedUser php -r ...
Я знаю его не на 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; };