Удаление функции во времени выполнения в PHP (без runkit расширения)

Я знаю, что этот вопрос кажется 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 приветствуются также!

24
задан Blackbam 5 September 2018 в 14:12
поделиться

6 ответов

из Руководства 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 .

Примечание: отредактировано и конденсируется после комментариев

20
ответ дан 28 November 2019 в 23:51
поделиться

Простой ответ: нет.

Однако Вы можете попробовать размещать функцию внутри пространства имен, класс или даже в другой функции - но я думаю, что это не то, что вы ищете.

Один другой вариант, который у вас есть, это использовать 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);
}

Нет функций, и Код не так долго. =)

3
ответ дан 28 November 2019 в 23:51
поделиться

Нет. Но удаление определения функции глупо.
Либо вы определяете функцию по-разному в блоке блока и нуждаетесь в определении для изменений в зависимости от состояния программы, эффективно сделать ваш проект ближе и ближе к невозможным отладочную, или код, который вызывает, чтобы функционировать, и Сжечь, если этого не произошло, чтобы определиться во время выполнения.

Вы должны поместить эту функцию в классе:

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();

    }
        ...

Я не знаю, что вы пытаетесь сделать или почему вы хотите удалить определение функции, но Надеюсь, это может помочь вам сделать это чистым способом.

2
ответ дан 28 November 2019 в 23:51
поделиться

Я согласен с Аликс. Однако вы можете избежать вызываемой функции из любого места, избавившись от функции. Перепишите рекурсивную функцию как итеративную петлю. Вы получите дополнительное преимущество уменьшения использования памяти.

Обновление: с вашим примером кода, я не уверен, почему вы чувствуете необходимость предотвращения вызываемой этой функции снова. Он просто форматирует некоторые строки в массиве рекурсивно ... Опять же, вы могли бы сделать это итеративно и избежать функции в первую очередь. В противном случае просто оставьте это и не называйте это снова.

0
ответ дан 28 November 2019 в 23:51
поделиться

Я тоже вижу очень мало причин, чтобы позволить функции » Живи "или" не жить "в зависимости от состояния, но чтобы ответить на вопрос, это своего рода возможна с использованием анонимных функций. @ Гордон уже изложил, как это сделано. Начиная с 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);
}
1
ответ дан 28 November 2019 в 23:51
поделиться

Это невозможно без Runkit_function_Remove. Runkit - это расширение, предназначенное для того, чтобы делать такие вещи.

Вы уверены, что функция проживает после завершения IF-Block? Я бы подумал, что если бы он был определен в формате IF-Block, что он станет недоступным позже.

0
ответ дан 28 November 2019 в 23:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: