也许你可以看看Docker。例如,您可以将用户代码复制到服务器上的文件中(不执行它),然后在容器中运行它。这将允许您:
- 将代码运行到特定的专用容器中,该容器可以在脚本执行后销毁
- 使用不同版本的 PHP 运行代码
一些例子:
docker run -v "$PWD":/usr/src -w /usr/src --rm php:7.4.5 php ./myScript.php
这会将文件 myScript.php 执行到基于 php 7.4.5 的新容器中,一旦完成,容器将被删除。
使用另一个 PHP 版本也是如此:
docker run -v "$PWD":/usr/src -w /usr/src --rm php:5.6 php ./myScript.php
有用的链接:
关于表演的编辑:
显然,使用容器运行代码比直接从 PHP 运行代码要长。
例如,我们可以运行以下代码对其进行测试:
<?php
function reverseArray(array $array): array {
for ($i = 0; $i < count($array) / 2; $i++) {
$tmp = $array[$i];
$array[$i] = $array[count($array) -1 - $i];
$array[count($array) - 1 - $i] = $tmp;
}
return $array;
}
$tabToReverse = [5, 8, 95, 10, 6, 17, 42, 20];
echo 'Reversed array : '."\n";
echo implode(' ', reverseArray($tabToReverse));
具有语法错误的相同代码:
<?php
// syntax error
function reverseArray($array: array): array {
for ($i = 0; $i < count($array) / 2; $i++) {
$tmp = $array[$i];
$array[$i] = $array[count($array) -1 - $i];
$array[count($array) - 1 - $i] = $tmp;
}
return $array;
}
$tabToReverse = [5, 8, 95, 10, 6, 17, 42, 20];
echo 'Reversed array : '."\n";
echo implode(' ', reverseArray($tabToReverse));
下面的 PHP 代码将比较两种执行(加上一些语法错误):
<?php
/**
* Run code using eval
*/
$start = microtime(true);
$code = str_replace('<?php', '', file_get_contents('./reverseArray.php'));
echo eval($code)."\n";
$end = microtime(true);
$duration = $end - $start;
echo "Duration using eval $duration\n";
/**
* Run code using container
*/
$start = microtime(true);
$cmd = 'docker run -v "$PWD":/usr/src -w /usr/src --rm php:7.4.5 php ./reverseArray.php';
exec($cmd, $result);
echo implode("\n", $result)."\n";
$end = microtime(true);
$duration = $end - $start;
echo "Duration using container $duration\n";
/**
* Run code using container with an error
*/
$start = microtime(true);
$cmd = 'docker run -v "$PWD":/usr/src -w /usr/src --rm php:7.4.5 php ./reverseArrayWithError.php';
exec($cmd, $resultWithError);
echo implode("\n", $resultWithError)."\n";
$end = microtime(true);
$duration = $end - $start;
echo "Duration using container $duration\n";
我的笔记本电脑上的结果是:
php ./runCode.php
Reversed array :
20 42 17 6 10 95 8 5
Duration using eval 0.00031089782714844
Reversed array :
20 42 17 6 10 95 8 5
Duration using container 0.79519391059875
Parse error: syntax error, unexpected ':', expecting ')' in /usr/src/reverseArrayWithError.php on line 3
Duration using container 0.81346988677979
如您所见,启动容器需要时间。但代码已在特定区域执行。
在所有情况下,前端部分都是一样的,它将使用一些 Ajax 查询来在服务器上发布数据,等待结果并显示它。
注意 1:即使代码在特定容器中执行,也必须在之前对其进行清理,因为永远不应信任用户输入。
注意 2:使用此架构需要管理正在运行的容器以防止过载。如果 10 000 个用户同时提交代码会发生什么?但我认为这是另一个话题。