Это немного странно; Я не думаю, что это на самом деле возможно, однако сообщество SO удивило меня снова и снова; так и здесь.
Дано в PHP; У меня есть следующий фрагмент:
$path = 'path/to/file.php'; $buffer = call_user_func(function() use($path){ ob_start(); require $path; return ob_get_clean(); });
Когда включено, path/to/file.php
будет иметь $path
в своей области. Есть ли способ предотвратить доступ этой переменной в контексте включенного файла?
Например, если unset()
возвратил значение переменной, которую оно не установило, я мог бы сделать:
require unset($path);
Но, конечно, это не работает.
Для любопытных, я пытаюсь предотвратить $path
от наследования значения от include.
«Защита от обфускации» – это соображение, которое я сделал; передавая что-то вроде $thisIsThePathToTheFileAndNobodyBetterUseThisName
, но это кажется немного глупым и до сих пор не является надежным.
Для других «зарезервированных» переменных, которые должны быть унаследованы, я уже отправился с extract()
и unset()
:
$buffer = call_user_func(function() use($path, $collection){ extract($collection); unset($collection); ob_start(); // ...
с$buffer = call_user_func(function() use($path, $collection){ extract($collection); unset($collection); ob_start(); // ...
Что я, наконец, пошел с:
$buffer = call_user_func(function() use(&$data, $registry){ extract($registry, EXTR_SKIP); unset($registry); ob_start(); // only $data and anything in $registry (but not $registry) are available require func_get_arg(0); return ob_get_clean(); }, $viewPath);
с$buffer = call_user_func(function() use(&$data, $registry){ extract($registry, EXTR_SKIP); unset($registry); ob_start(); // only $data and anything in $registry (but not $registry) are available require func_get_arg(0); return ob_get_clean(); }, $viewPath);
Возможно, мой вопрос был немного заблуждением, благодаря использованию use()
для передачи переменных в область анонимных функций; прохождение аргументов было вариантом, о котором я забыл упомянуть.
Что касается @hakre и use()
+ func_get_args()
:
$var = 'foo'; $func = function() use($var){ var_dump(func_get_args()); }; $func(1, 2, 3); /* produces array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Используйте func_get_arg()
вместо использования традиционных аргументов функции:
$buffer = call_user_func(function() { ob_start(); require func_get_arg(0); return ob_get_clean(); }, $path);
Вы можете сделать это с помощью дополнительной функции. В примере я использовал echo вместо require:
$path = 'hello'; function valStore($value = null) { static $s = null; if ($value !== null) $s = $value; else return $s; } valStore($path); unset($path); # and gone echo valStore();
с$path = 'hello'; function valStore($value = null) { static $s = null; if ($value !== null) $s = $value; else return $s; } valStore($path); unset($path); # and gone echo valStore();
Вы можете использовать что-то вроде этого:
$path = 'path/to/file.php'; function getPath() { global $path; $p = $path; unset($path); return $p; } $buffer = call_user_func(function() { ob_start(); require getPath(); return ob_get_clean(); });
с$path = 'path/to/file.php'; function getPath() { global $path; $p = $path; unset($path); return $p; } $buffer = call_user_func(function() { ob_start(); require getPath(); return ob_get_clean(); });