Содержание
В одном из наших проектов существует возможность написания плагинов для расширения функционала сервиса.
Пользователи создают плагины-приложения в нашем интерфейсе и описывают их логику на PHP.
Необходимо было ограничить возможности PHP, чтобы никто нам случайно не нашкодил.
Существует некоторое количество инструментов для исполнения кода PHP в защищенной среде: выполнение в отдельном процессе, сохранение кода в файле и вызов через cli с урезанными возможностями или использование специализированных расширений для PHP.
В силу специфики сервиса и приложений а так же для возможности использования песочницы на всех ОС (процессы и расширения для sandbox не работают в Windows) с базовыми настройками PHP был написан небольшой класс:Ext_Sandbox_PHPValidator.
Небольшое описание класса
Внутри всего две функции:
- static function php_syntax_error($code, $tokens = null)
- static function validatePHPCode($source, $functions = array(), $enable = true)
php_syntax_error
Функция проверяет, правилен ли синтаксис PHP кода (не пропущены ли скобки и т.д.)
$code — php код (без <?php )
$tokens — необязательный параметр, вы можете передать его если вы уже распарсили код на токены (распарсить можно используя функцию token_get_all).
Функция возвращает ошибку в формате: array( Error Mesage, Error Line # )
Если ошибки нет — функция возвратит false.
validatePHPCode
Функция проверяет php-код и возвращает результат проверки (true или false).
$source — php-код без <?php в начале
$functions — разрешенные/запрещенные функции
$enable — boolean, если true, то $functions будут содержать список разрешенных функций, если false — список запрещенных функций.
Пример:
<?php require 'PHPValidator.php'; $code = <<<PHP \$b = 1; \$c = 2; \$a = \$b + \$c; echo \$a; class test { public function __construct() { echo 'construct'; } public function foo(\$num) { var_dump(\$num); } } \$test = new test(); \$test->foo(\$a); PHP; // validate the code $validator = new Ext_Sandbox_PHPValidator(); try { // we enable only one function - echo, all others will throw error $validator->validatePHPCode( $code, array('echo'), true); $status = 'passed'; } catch(Exception $ex) { $status = $ex->getMessage(); } echo 'Status of validation is: ' . $status;
Попробовать онлайн: http://ideone.com/e1qx28