php - 在 PHP 中构造装饰器

标签 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 不支持该语法。但我仍然希望能够在重写尽可能少的代码的同时达到同样的效果。

最佳答案

基本上不,PHP 根本不支持它。据我所知,它甚至不在未来 PHP 版本的路线图上。

有趣且稍微相关:在 PHP 领域,我能想到的最接近您所追求的是使用 phpUnit 来测试您的代码。 phpUnit 沿这些思路实现了一些东西供自己使用,使用方法上方的 docblock 类型注释中的引用。例如:

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

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

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

这让我印象深刻,因为它与您描述的装饰器语法很接近,但又不完全相同。但是,它不是标准的 PHP 语法; phpUnit 自己实现了所有这些东西。它读取源代码并在运行测试之前解析注释 block 时进行大量预处理,因此效率不高。适用于单元测试工具,但不适用于生产系统。

但是不,对您的问题的简短回答是您想要的东西不能用 PHP 完成。对不起。

关于php - 在 PHP 中构造装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13630392/

相关文章:

php - Doctrine\Common\Persistence\Mapping\Driver 丢失

php - mysql_num_rows() expects parameter 1 to be resource 错误

写入文件的python会添加空字符

python - Django : 'unicode' object has no attribute 'get'

javascript - jQuery 无法使用相对路径

PHP/mySQL登录不成功

python - pymoo的survival.py模块中出现类型错误

ruby-on-rails-3.1 - 在 rails 中使用 Mustache 模板和 Slim

java - 如何检查继承链中是否存在特定的类类型

javascript - 在 nest.js 中,是否可以在参数装饰器中获取服务实例?