У меня уже установленное закрытие, и я хочу вводить код внутри, когда я его выполняю. Вот пример:
$predefined = "print 'my predefined injected code<br />';"; $closure = function () { print 'hello<br />'; }; call_user_func_array($closure, array()); // output : hello
Я хочу смешать 2 кода: предопределенный и закрывающий. После модификации я хочу, чтобы мое закрытие выглядело так
$closure = function () { print 'my predefined injected code<br />'; print 'hello<br />'; };
Возможно ли вставить какой-либо код в закрытие перед его выполнением?
Примечание. Я не могу использовать «create_function», которые принимают код как строку, поэтому его можно легко модифицировать. Закрытия уже определены и определены определенным образом (через функцию, которая принимает аргумент callback, а не строку arg).
Спасибо за вашу помощь.
РЕДАКТИРОВАТЬ:
Вот решение
function hackClosure($closure, $inject_code) { $reflection = new ReflectionFunction($closure); $tmp = $reflection->getParameters(); $args = array(); foreach ($tmp as $a) array_push($args, '$'.$a->getName() . ($a->isDefaultValueAvailable() ? '=\''.$a->getDefaultValue().'\'' : '')); $file = new SplFileObject($reflection->getFileName()); $file->seek($reflection->getStartLine()-1); $code = ''; while ($file->key() < $reflection->getEndLine()) { $code .= $file->current(); $file->next(); } $start = strpos($code, '{')+1; $end = strrpos($code, '}'); return create_function(implode(', ', $args), substr($code, $start, $end - $start) . $inject_code); } $theClosure = function () { print 'something'; }; $inject_code = "print ' to say';"; $func = hackClosure($theClosure, $inject_code); $func();
Он оказывает
something to say
вместо
something
Вы не можете напрямую вводить его. Однако вы можете его обернуть.
$newClosure = function() use ($closure) { print 'my predefined injected code<br />'; $closure(); };
Кроме того, нет необходимости использовать call_user_func_array
поскольку вы не передаете никаких аргументов. Просто вызовите $closure();
Кроме того, вы можете создать оболочку, чтобы получить новое закрытие:
$creator = function($closure) { return function() use ($closure) { print 'my predefined injected code<br />'; $closure(); }; }; $newClosure = $creator($closure); $newClosure();
возможно, что-то вроде этого:
$closure = function($optionalcode = null) { print('blah blah blah'); if (!isnull($optionalcode)) { eval($optionalcode); } print('blah blah blah'); } $closure("print('yoohoo!');");
Однако eval()
является злым, и его следует избегать любой ценой.
Разве это то, что вы ищете? http://php.net/manual/en/function.eval.php