如何将PHP回调作为非字符串传递,从而使其可重构?

如何将PHP回调作为非字符串传递,从而使其可重构?,php,Php,PHP5.5中引入了MyClass::class来引用一个类,而不是将其作为'MyClass'传递,这是不容易重构的,因为它只是一个字符串 在将回调/可调用传递给call\u user\u func()或usort()时,我非常希望对函数名执行相同的操作 在这个例子中 usort($files, [FileFunctions::class, 'dircmp']); 只有FileFunctions可以轻松重构 如何以类似的方式引用dircmp函数 使用 导致未定义的类常量“dircmp”致命错误

PHP5.5中引入了
MyClass::class
来引用一个类,而不是将其作为
'MyClass'
传递,这是不容易重构的,因为它只是一个字符串

在将回调/可调用传递给
call\u user\u func()
usort()
时,我非常希望对函数名执行相同的操作

在这个例子中

usort($files, [FileFunctions::class, 'dircmp']);
只有
FileFunctions
可以轻松重构

如何以类似的方式引用
dircmp
函数

使用


导致
未定义的类常量“dircmp”
致命错误,因为双冒号后面的参数被解释为常量(当然)。

在这个reddit线程中有一些有趣的讨论:

当前使用方法作为回调动态调用的语法相当糟糕

这似乎是一个很难解决的问题。看过它的人 已经说过,如果不合并符号,它是无法解决的 表(这是不可能发生的,因为它打破了太多) 代码),或者使用新语法。有一件事是 在不与任何现有语法冲突的情况下,可以使用$()作为 “给我一个可调用/闭包”的语言结构:

$(functionName);  // Usable at compile time.
$(SomeClass::staticMethodNameAsString); //Usable at compile time
$($object->methodName); //Usable at runtime
在不合并符号表的情况下,几乎可以肯定的是 从最小字符数的意义上讲,最干净 实施它。我看不出有任何问题(除了它是新的) 每个人都害怕的语法),但这超出了我的能力 实施

获得良好反馈的道具。这绝对是必要的 这个问题需要以一种比我们目前的选择更干净的方式来解决

我完全同意,解决更大的回调语法非常重要 棘手的甚至是转换方法调用的某种语法糖 将其作为可调用项放入当前数组中会有很大帮助。主要问题一 显式使用字符串的好处是它使查找调用站点变得容易 无论是静态分析还是 基本工具,如grep。当使用
[$obj,'someMethodCall']
调用它时,不能简单地
grep-ri--'->someMethodCall('*
),并在没有箭头或箭头的情况下查找方法名 帕伦斯倾向于留下许多假阳性


我会毫不犹豫地说,只有匿名函数包装器才行。这显然是一个让人头疼的问题。一个问题……为什么你必须写FileFunctions::class而不是“FileFunctions”……你赢了什么?@Svetlio IDE可以毫不含糊地说,它是对类的引用,而不仅仅是一个随机字符串,并有助于重构@deceze是真的。这是一个不错的主意,但很麻烦。我想知道这样做的最佳实践是什么。我真的不喜欢将函数名作为字符串传递。我也是,但这是PHP for ya。函数不是一流的实体。
<?php

class FileFunctions {
    static function dircmp($a, $b) {
        if ($a == $b) return 0;
        return ($a > $b) ? 1:-1;
    }
}

$files = [2,6,1,6,9,2,6,1,7,4];

usort($files, function($a, $b) {return FileFunctions::dircmp($a, $b);});
var_dump($files);
$(functionName);  // Usable at compile time.
$(SomeClass::staticMethodNameAsString); //Usable at compile time
$($object->methodName); //Usable at runtime