在PHP中构造装饰器

时间:2012-11-29 16:35:45

标签: php python decorator

我是一个新手开发人员,试图扩展我的工具箱并学习更多技巧。我最近遇到了一个名为“装饰”的Python模式,我想知道是否/如何在PHP中实现它,因为我有一个现有的PHP代码库。

以下是我的意思的简短例子:

import time

def log_calls(func):
    def wrapper(*args, **kwargs):
        now = time.time()
        print("Calling {0} with {1} and {2}".format(
            func.__name__,
            args,
            kwargs
        ))
        return_value = func(*args, **kwargs)
        print("Executed {0} in {1}ms".format(
            func.__name__,
            time.time() - now
        ))
        return return_value
    return wrapper

@log_calls
def test1(a,b,c):
    print("\ttest1 called")

@log_calls
def test2(a,b):
    print("\ttest2 called")

@log_calls
def test3(a,b):
    print("\ttest3 called")
    time.sleep(1)

test1(1,2,3)
test2(4,b=5)
test3(6,7)

它不一定必须在语法上相当漂亮;我知道所有语言都有其细微差别,我知道PHP不支持这种语法。但是我仍然希望能够在尽可能少地重写代码的同时实现相同的效果。

2 个答案:

答案 0 :(得分:1)

基本上没有,它完全不支持PHP。据我所知,它甚至不是未来PHP版本的路线图。

感兴趣,并且稍微相关:如果你使用phpUnit来测试你的代码,那么在PHP-land中我能想到的最接近你所追求的是什么。 phpUnit使用docblock类型注释中的引用来实现它们自己使用的这些行。例如:

/**
 * @dataProvider myProviderFunc
 */
public function myTestFunc($argsFromProvider) {
    ....
}

public function myProviderFunc() {
    return array(....);
}

因此,当phpUnit想要调用myTestFunc()时,它首先调用myProviderFunc(),并将该函数的输出传递给myTestFunc()

这让我感到非常接近,但与你描述的装饰器语法并不完全相同。但是,它不是标准的PHP语法; phpUnit实现了所有这些东西。它会在运行测试之前读取源代码并进行预处理,因为它会解析注释块,因此效率不高。适用于单元测试工具,但不适用于生产系统。

但不是,对你的问题的简短回答是你想要的东西不能在PHP中完成。遗憾。

答案 1 :(得分:1)

PHP没有对装饰器模式的语法支持,但没有什么真正阻碍你自己实现它。

您可以查看以下讨论,这些讨论可能与您的问题相关:

这是另一个资源,包含多种语言的UML图和代码示例,包括PHP。