V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
revlis7
V2EX  ›  PHP

哪位大佬能解释下关于 PHP 闭包转换的问题

  •  
  •   revlis7 · 148 天前 · 1141 次点击
    这是一个创建于 148 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这里有篇文章 Link 是关于 PHP 的(...)闭包转换语法的,里面有一个例子是通过闭包转换使得外部函数调用私有成员变量:

    <?php
    class MyClass
    {
        public function __construct(private string $value)
        {
        }
    }
    
    echo Closure::fromCallable(fn () => $this->value)
                ->call(new MyClass('THIS IS A PRIVATE VALUE'));
    // OUTPUTS
    // THIS IS A PRIVATE VALUE
    

    然而转换的方法本身就是一个闭包函数,所以我发现其实这里不做转换一样可以得到结果:

    <?php
    class MyClass
    {
        public function __construct(private string $value)
        {
        }
    }
    
    echo (fn () => $this->value)->call(new MyClass('THIS IS A PRIVATE VALUE'));
    // OUTPUTS
    // THIS IS A PRIVATE VALUE
    

    而当你试图真正将一个类方法转换成闭包时,你却会得到一个 Warning:

    <?php
    class MyClass
    {
        public function __construct(private string $value)
        {
        }
    }
    
    $classMethod = new class {
        public function method()
        {
            return $this->value;
        }
    };
    
    echo Closure::fromCallable([$classMethod, 'method'])->call(new MyClass('THIS IS A PRIVATE VALUE'));
    // OUTPUTS
    // PHP Warning:  Cannot bind method class@anonymous::method() to object of class MyClass 
    

    关于这个 Warning 我也查到了一些讨论:

    https://stackoverflow.com/questions/47165930/php-binding-method-to-another-class

    https://bugs.php.net/bug.php?id=73931&edit=3

    我理解大概的意思就是为了避免 $this 在闭包转换后变量产生歧义,那既然如此,我觉得他在这里举的这个例子其实就不是很合理,你完全不需要使用闭包转换,还是说我使用的方式不对?

    2 条回复    2024-07-07 12:49:12 +08:00
    ssgooglg
        1
    ssgooglg  
       148 天前
    我觉得直接问 chatgbt 回复的也不错
    Rache1
        2
    Rache1  
       124 天前
    使用类实例方法的时候,你 call 传入的第一个参数(即 this )需要是调用类的祖先类才行(类型兼容)。

    https://3v4l.org/jM1rt
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2554 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 15:26 · PVG 23:26 · LAX 07:26 · JFK 10:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.