【问题标题】:Redefine Built in PHP Functions重新定义内置 PHP 函数
【发布时间】:2011-01-20 13:47:46
【问题描述】:

我想重新定义 PHP 中已经构建的某些函数,例如 echo() 或 time() - 我不需要全局定义这些函数,只需在单个脚本中进行测试。

我认为这可以在 Perl 但在 PHP 中完成 - 这可能吗?

【问题讨论】:

标签: php


【解决方案1】:

runkit_function_redefine — 用新的实现替换函数定义

注意:默认情况下,只有用户空间函数可以被删除、重命名或 修改的。为了覆盖 内部功能,您必须启用 runkit.internal_override 设置 在 php.ini 中。

【讨论】:

  • 这对所有 PHP 脚本都有全局影响,还是特定于特定脚本?
  • 编辑 php.ini 文件将影响在特定 PHP 安装上运行的所有 PHP 脚本。然而,函数重定义本身是调用 runkit_function_redefine() 的脚本所独有的。
  • +1 for runkit - APD 有点笨拙,它会弄乱进程退出代码,这会在测试用例中破坏它。我使用github.com/zenovich/runkit 的runkit 来拦截测试用例中的mt_rand() 和time(),我是一个快乐的露营者。
  • 除了测试目的之外,Runkit 是生产环境的有效解决方案吗?我想将它与我无法修改的解决方案一起使用,以允许后台用户在未来通过重写 time() 和任何其他相关函数来预览他们的前台。我应该停止思考 Runkit 并开始重写产品的大多数类吗?
  • @ChrisNash,Happy camper... 是什么意思?
【解决方案2】:

您可能还想查看

override_function() — 覆盖内置函数

来自Advanced PHP debugger 包。

尽管如此,必须重新定义原生 PHP 函数或语言语句应该敲响警钟。在我看来,这不应该成为您的生产代码的一部分,除非您正在编写调试器或类似工具。

另一种选择是使用http://antecedent.github.io/patchwork

Patchwork 是一个 PHP 库,可以在运行时重新定义用户定义的函数和方法,在纯 PHP 5.3 代码中松散地复制功能runkit_function_redefine,除其他外,它使您能够替换静态和私有方法带有测试双打。

后者不适用于本机函数

【讨论】:

  • @Gordon - 感谢您的建议。我只是为了测试目的而不是生产代码而这样做 - 你是对的,它确实敲响了警钟!
【解决方案3】:

echo 不是函数,它是一种语言结构。我对此无能为力。

但是像time()这样的函数调用可以被覆盖,因为PHP-5.3's namespace fallback policy

对于函数 […],如果命名空间函数 […] 不存在,PHP 将回退到全局函数 […]。

例如对于非全局命名空间foo 中的非限定函数调用time(),您可以提供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());
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-08
    • 2010-10-13
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 2011-05-20
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多