Переопределение функции PHP? - PullRequest
35 голосов
/ 15 апреля 2010

Если у меня есть функция:

function this($a){
   return $a;
}

Если бы я хотел переопределить функцию, было бы так же просто, как переписать ее?

function this($a, $b){  //New this function
   return $a * $b;
}

Ответы [ 8 ]

22 голосов
/ 15 апреля 2010

Если вы имеете в виду перегрузку в смысле Java, то ответ - нет, это невозможно.

Цитирование руководства PHP по функциям :

PHP не поддерживает перегрузку функций, а также невозможно отменить или переопределить ранее объявленные функции.

Вы можете использовать расширение runkit, но использование runkit в производственных сценариях обычно считается сомнительной практикой. Если вы хотите обмениваться алгоритмами во время выполнения, взгляните на шаблон стратегии или Анонимные функции .

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

Другой вариант будет использовать http://antecedent.github.io/patchwork

Patchwork - это библиотека PHP, которая позволяет переопределять пользовательские функции и методы во время выполнения, свободно копируя функциональность runkit_function_redefine в чистом коде PHP 5.3, который, помимо прочего, позволяет заменять статические и частные методы. с двойным тестом.

22 голосов
/ 15 апреля 2010

Нет, это выдает ошибку:

Fatal error: Cannot redeclare foo()

Runkit предоставляет опции, включая runkit_function_rename() и runkit_function_redefine().

10 голосов
/ 28 января 2013

Вы не можете переопределить или «отменить» функцию в PHP (не прибегая к сторонним модулям). Однако вы можете определить функцию условно.

Итак, если вы знаете, что функцию A можно определить в другом месте, но не всегда, вы можете обернуть ее так:

if (!function_exists('A')) {
    function A() {
        // default A implementation
    }
}

Тогда вам нужно только убедиться, что в первую очередь вы встретите нужную реализацию:

function A() {
    // another A implementation
}
1 голос
/ 10 июня 2016

У меня хорошие и плохие новости.

Хорошие новости
Это возможно (ссылка ниже).

Надновости
Есть 2 плохие новости:

По умолчанию только функции пользовательского пространства могут быть удалены, переименованы или изменены. Чтобы переопределить внутренние функции, необходимо включить параметр runkit.internal_override в php.ini.

И вторая плохая новость: Вы должны пожертвовать удобочитаемостью кода .

Пример: * * один тысяча двадцать-одна

<?php
function this($a){
   return $a;
}

echo this(0);

$f_name = 'this';
$f_args = '$a';
$f_code = 'return $a*$b;';
runkit_function_redefine($f_name, f_args, f_code);

echo this(1,3);

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

<?php
class theclass{
  $a = 'a';
  function a($a){
    echo $a;
    $a = this.$a;
  }
}
theclass $object = new theclass();
$object -> a('b'); // will echo: ab
1 голос
/ 31 января 2014

У меня есть библиотека функций, которые иногда я просто не хочу вызывать во время тестирования (как правило, обновления базы данных). Если у меня есть, например, несколько различных функций обновления базы данных, которые находятся по всему коду. вместо того, чтобы комментировать код, я просто создаю специальный класс (например, класс foo {}). Определите глобальную переменную (например, $ DEBUG) и фиктивную функцию (например, функцию dummy {}). Внутри foo определите все (публичные статические) функции, которые вам нужно имитировать, как

$ fn = isset ($ DEBUG)? «пустышка»: «реальная функция»; return call_user_func_array ($ fn, func_get_args ());

Кроме того, теперь у вас есть преимущества, связанные с другими вещами, такими как регистрация вызовов и параметров.

Затем просто замените все ваши вызовы real_function (...) на foo :: real_function (...). Обычно простой поиск / замена (или оставить его там; в зависимости от того, что происходит в функции и как часто она вызывается, накладные расходы могут не иметь значения).

0 голосов
/ 15 апреля 2010

Установка соответствующих значений по умолчанию для любых новых аргументов, которые вы добавляете, может помочь для обратной совместимости, то есть ::10000

function this($a, $b=1){  //New this function with a sane default.
    return $a * $b;
}

Я также рекомендую, для ясности, вообще избегать использования this для имен функций / переменных.

0 голосов
/ 15 апреля 2010

Вы не можете переопределить это. Если ваш вопрос просто о перегрузке этого примера, как насчет:

function this($a, $b=1)
{
    return $a * $b;
}
0 голосов
/ 15 апреля 2010

Вы не можете одновременно объявлять обе функции, что приведет к ошибке.

...