Я знаю, что этот вопрос кажется hacky и странный, но является там способом удалить функцию во времени выполнения в PHP?
Мне объявили рекурсивную функцию в, "если" блок и хочет, чтобы та функция была "допустима" только в этом "если" блок. Я не хочу, чтобы эта функция была названа вне этого блока.
Я узнал runkit_function_remove, но runkit не включен на моем веб-хосте. Там другой путь состоит в том, чтобы сделать это?
BTW я только поддерживаю PHP 5.1.0.
Править: Я знал, что мой вопрос был hacky, но здесь является точной вещью, которую я хочу сделать:
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
//runkit_function_remove('stripslashes_deep');
}
Так как "stripslashes_deep" будет только жить, когда Волшебные Кавычки будут идти, я хотел избавиться от него, когда я сделан с ним. Я не хочу, чтобы люди полагались на функцию, которая является не всегда там. Я надеюсь, что это более ясно теперь. Предложения решения Non-hacky приветствуются также!
из Руководства PHP по функциям :
Все функции и классы в PHP имеют глобальный объем - их можно назвать вне функции, даже если они были определены внутри и наоборот. [...] PHP не поддерживает перегрузку функций и не возможно, не удастся или переопределить ранее объявленные функции.
Исключение через Runkit. Тем не менее, вы можете определить вашу функцию как анонимную функцию и Unset
. Это после того, как вы запустите его, например, E.g.
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
$fn = create_function('&$v, $k', '$v = stripslashes($v);');
array_walk_recursive(array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST), $fn);
unset($fn);
}
Некоторые комментарии правильно указали (но больше не проблема в PHP Now), вы не можете вызвать анонимную функцию внутри себя. Используя Array_walk_recursive
Вы можете обойти это ограничение. Лично я бы просто создал регулярную функцию и не беспокою о удалении. Это не повредит никому. Просто дайте ему правильное имя, как STRIPSLASHES_GPC_CALLBACK
.
Примечание: отредактировано и конденсируется после комментариев
Простой ответ: нет.
Однако Вы можете попробовать размещать функцию внутри пространства имен, класс или даже в другой функции - но я думаю, что это не то, что вы ищете.
Один другой вариант, который у вас есть, это использовать Debug_BackTrace ()
Внутри упомянутой функции, чтобы проверить, какой файл / Line / etc ... вызывает это - это взлома, я знаю, но так это runkit_function_remove ()
.
Изменить - слишком плохо, вы не запускаете PHP 5.3+, в противном случае вы могли бы просто сделать:
if (get_magic_quotes_gpc())
{
$_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
$_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
$_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
$_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
}
для более старых версий PHP У вас все еще есть эта опция :
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
Нет функций, и Код не так долго. =)
Нет. Но удаление определения функции глупо.
Либо вы определяете функцию по-разному в блоке
блока и нуждаетесь в определении для изменений в зависимости от состояния программы, эффективно сделать ваш проект ближе и ближе к невозможным отладочную, или код, который вызывает, чтобы функционировать, и Сжечь, если этого не произошло, чтобы определиться во время выполнения.
Вы должны поместить эту функцию в классе:
class foo {
public function bar() {
if( /* some condition */ ) {
$this->baz();
} else {
$this->bazzer();
}
}
private function baz() {
/* if the if condition was met */
}
private function bazzer() {
/* if the if condition failed */
}
}
или, если вы хотите, только когда-то проверяется условие,
class foo {
private $bar_function = NULL;
public function __construct() {
if( /* some condition */ ) {
$this->bar_function = baz;
} else {
$this->bar_function = bazzer;
}
}
public function bar() {
$this->$bar_function();
}
...
Я не знаю, что вы пытаетесь сделать или почему вы хотите удалить определение функции, но Надеюсь, это может помочь вам сделать это чистым способом.
Я согласен с Аликс. Однако вы можете избежать вызываемой функции из любого места, избавившись от функции. Перепишите рекурсивную функцию как итеративную петлю. Вы получите дополнительное преимущество уменьшения использования памяти.
Обновление: с вашим примером кода, я не уверен, почему вы чувствуете необходимость предотвращения вызываемой этой функции снова. Он просто форматирует некоторые строки в массиве рекурсивно ... Опять же, вы могли бы сделать это итеративно и избежать функции в первую очередь. В противном случае просто оставьте это и не называйте это снова.
Я тоже вижу очень мало причин, чтобы позволить функции » Живи "или" не жить "в зависимости от состояния, но чтобы ответить на вопрос, это своего рода возможна с использованием анонимных функций. @ Гордон уже изложил, как это сделано. Начиная с PHP 5.3.0, вы также можете использовать анонимные функции следующим образом. (Не существует функциональной разницы в Create_function ()
подход.)
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
$stripslashes_deep = function($value)
{
return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
$_POST = array_map($stripslashes_deep, $_POST);
$_GET = array_map($stripslashes_deep, $_GET);
$_COOKIE = array_map($stripslashes_deep, $_COOKIE);
$_REQUEST = array_map($stripslashes_deep, $_REQUEST);
unset ($stripslashes_deep);
}
Это невозможно без Runkit_function_Remove. Runkit - это расширение, предназначенное для того, чтобы делать такие вещи.
Вы уверены, что функция проживает после завершения IF-Block? Я бы подумал, что если бы он был определен в формате IF-Block, что он станет недоступным позже.