Переопределить встроенные функции PHP

Я хотел бы переопределить некоторые функции в PHP, которые уже созданы, например, echo() или time() - мне не нужно определять эти функции глобально, только в одном скрипте для тестирования.

Я думаю, что это можно сделать в Perl, но в PHP - это возможно?

3 ответа

Решение

http://no2.php.net/runkit_function_redefine - заменить определение функции новой реализацией

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

Вы также можете проверить

override_function()- Переопределяет встроенные функции

из расширенного пакета отладчика PHP.

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

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

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

Последний не работает для нативных функций, хотя

echo это не функция, это языковая конструкция. У меня нет ничего для этого.

Но вызовы функций вроде time() может быть переопределено, поскольку политика восстановления пространства имен в PHP-5.3:

Для функций […] PHP вернется к глобальным функциям […], если функция пространства имен […] не существует.

Например, для неквалифицированного вызова функции time() в неглобальном пространстве имен foo Вы можете предоставить foo\time(),

Лично я использую это, чтобы издеваться, например, time() для юнит-теста. Я опубликовал эти макеты в библиотеке PHP-Mock:

namespace foo;

use phpmock\phpunit\PHPMock;

class FooTest extends \PHPUnit_Framework_TestCase
{

    use PHPMock;

    public function testBar()
    {
        $time = $this->getFunctionMock(__NAMESPACE__, "time");
        $time->expects($this->once())->willReturn(3);
        $this->assertEquals(3, time());
    }
}
Другие вопросы по тегам