【问题标题】:How do I point to another function? Is this possible?如何指向另一个函数?这可能吗?
【发布时间】:2020-10-25 10:04:07
【问题描述】:

对象是让函数的名字更短。

我有一个名为 somedescriptivefunctionName 的函数。

function somedescriptivefunctionName($a) {
   echo $a;
}

我想将它分配给$this->f,这样我就不会乱扔长名称的代码。

$this->f('Yahoo!!'); // will echo 'Yahoo!!'

例如我想像这样:

$this->f = $this->somedescriptivefunctionName; // wrong way

这可能吗?

当然我可以创建一个新函数 f,并返回一些描述性函数名()。但这不是重点。

【问题讨论】:

  • 这里的f是函数还是变量?
  • f 应该是我想给已经存在的函数 (somedescriptivefunctionName) 的新名称。但你是对的,它也是一个变量。如果你愿意,你可以选择 $f 而不是 $this->f
  • 他们是在同一个类,继承还是其他场景?
  • @Chilarai 现在让它保持简单。假设他们在同一个班级

标签: php scripting


【解决方案1】:

你将把字符串存储在某个地方

$f = "somedescriptivefunctionName";

然后通过在大括号中指定函数名称来调用函数:

$this->{$f}('Yahoo!!');

编辑

根据评论部分,目的是调用另一个类的同名实例的方法。您可以扩展配置类以实现某种类似的行为,但我认为在这种情况下作为解决方案是不可接受的。您可以将您的类转换为装饰器,例如

class SomeClassDecorator
{
    protected $_instance;

    public function myMethod() {
        return strtoupper( $this->_instance->someMethod() );
    }

    public function __construct(SomeClass $instance) {
        $this->_instance = $instance;
    }

    public function __call($method, $args) {
        return call_user_func_array(array($this->_instance, $method), $args);
    }

    public function __get($key) {
        return $this->_instance->$key;
    }

    public function __set($key, $val) {
        return $this->_instance->$key = $val;
    }

    // can implement additional (magic) methods here ...
}

上面的代码是从 Gordon 的惊人答案中复制而来的:How to add a method to an existing class in PHP?

这个想法的演变可能是为您的配置类创建一个装饰器作为基类,并为您配置的类扩展该基类,因此您将实现单个装饰器并(重新)使用它。

【讨论】:

  • 我可以确认这有点用,但我需要更好的东西。使用你的方法我这样做并且它有效: $ref = new ReflectionClass($this->config_class); $this->plcfg=$ref->newInstanceWithoutConstructor(); $errorTitle='错误标题'; echo $this->plcfg->${errorTitle}('fatal','asdf');我的目标是实际上能够做到这一点: echo $this->errorTitle('fatal','asdf');如果我们能做到这一点,那么两个类(当前类和位于 $this->plcfg 中的远程类)中的调用将完全相同。谢谢!!!
【解决方案2】:

您可以将属性绑定到闭包并将该属性作为方法调用:

class T{
    private $f;
    function abcdefghijklmnopqrstuvwxyz($param){
        echo $param;
    }
    function __construct(){
        $this->f = fn() => $this->abcdefghijklmnopqrstuvwxyz(...func_get_args());
    }
    function doWork() {
        ($this->f)('hello');
        $g = $this->f;
        $g('world');
    }
}

(new T())->doWork();

在这段代码中,f 类属性通过箭头函数绑定到闭包,该函数从 PHP 7.4 开始可用,我们可以动态获取通过 func_get_args 传递的参数。如果您使用的是低于 7.4 的版本,您也可以只使用常规匿名函数。

不幸的是,对name resolution issues 执行操作,如果不使用一组额外的括号,则无法将属性作为方法调用,这意味着您必须执行($this->f)('hello')。如果你想跳过它,你可以进一步将类属性分配给一个局部变量,然后可以在 $g 完成时正常调用。

编辑

这是一个不使用箭头函数的构造函数版本,它的调用方式相同。

    function __construct()
    {
        $this->f = function () {
            return $this->abcdefghijklmnopqrstuvwxyz(...func_get_args());
        };
    }

【讨论】:

  • 这很好。如果不是因为它是 php7.4+ 和以下的事实,那几乎是完美的: $this->f = fn() => $this->plcfg->errorTitle(...func_get_args()); $this->errorTitle=$this->f; echo ($this->errorTitle)('fatal','hello');是否可以到达不需要括号的阶段,例如: echo $this->errorTitle('fatal','hello');如果我们能做到这一点,那么两个类中的调用将完全相同(当前类和位于 $this->plcfg 中的远程类)谢谢!!!
猜你喜欢
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多