问题 使用匿名函数将代码转换为PHP 5.2


我有一些PHP 5.3代码,它构建一个要传递给视图的数组。这是我的代码。

# Select all this users links.
$data = $this->link_model->select_user_id($this->user->id);
if (count($data) > 0) {
    # Process the data into the table format.
    $table = array
    (
        'properties' => array
        (
            'delete_link_column' => 0,
        ),
        'callbacks' => array
        (
            # Callback for the name link.
            function($value) {
                return sprintf('<a href="/links/view/name/%s">%s</a>', $value, $value);
            },
            # Callback for the category link.
            function($value) {
                return sprintf('<a href="/category/view/name/%s">%s</a>', $value, $value);
            },
            # Callback for the creation date.
            function($value) {
                return date('jS M Y', $value);
            },
            # Callback for the delete link.
            function($value) {
                return sprintf('<a href="links/delete/name/%s">delete</a>', $value);
            },
        ),
        'columns' => array
        (
            'name', 'category', 'creation date',
        ),
        'data' => array
        (

        ),
        'sorting' => array
        (
            'sort' => false,
        ),
    );

但问题是我不能在PHP 5.2中使用匿名函数,这是我必须上传这个功课的服务器。该视图需要定义回调函数,以便可以调用它们。

将PHP代码转换为不使用匿名函数的最佳方法是什么?谢谢。


13078
2017-09-28 03:08


起源

何时以及如何以及为何调用这些回调? - deceze♦
@deceze此数组传递给视图,该视图处理数组并根据数据创建表。为每列中的数据调用回调以格式化数据。因此,如果第一列中的表格单元格值为“Boats”,则视图会将其处理为值'<a href="/links/view/name/Boats"> Boats </a>我真的不想要改变视图,因为我有很多控制器像这样使用它。 - NeedsEducation


答案:


您可以像这样调用其中一个函数:

$func = $callbacks[0];
$func();

哪个也适用 create_function() 并使用字符串作为命名函数,如下所示:

function test() {
  echo "test";
}
$func = 'test';
$func();

$func = create_function('' , 'echo "test 2"; ');
$func();

此外,如果使用完成调用 call_user_func 您可以使用 array($object, 'func_name') 用对象调用对象或类的公共方法 array('Class_Name', 'func_name')

class Test {
  public static function staticTest() { echo "Static Test"; }
  public function methodTest() { echo "Test"; }

  public function runTests() {
    $test = array('Test', 'staticTest');
    call_user_func($test);

    $test = array($this, 'methodTest');
    call_user_func($test);
  }
}

$test = new Test();
$test->runTests();

8
2017-09-28 03:54



谢谢我的需要。 - NeedsEducation


匿名函数非常适合短暂的一次性使用,例如像Observer这样的模式中的事件监听器。

但是,由于您已经形式化了一个接口(用于呈现名称,类别,创建日期和删除链接的回调),您可以采取额外步骤来定义需要实现这4种方法的“渲染器”界面。您可以将单个渲染器子类传递给视图,而不是传递回调,然后可以使用该子类调用适当的方法。视图还可以通过检查父类来验证它。这仍然允许您在不需要匿名功能的情况下,以便携,可重复使用的OOP的精神交换渲染器。

是否有一种情况,你的回调将来自任意代码(例如插件)?如果没有,那么使这些回调匿名是没有好处的。看起来你可能正在节省一点名称空间膨胀,但是你也在调试或编写文件时变得更难。


7
2017-09-28 03:32



+1表示更清洁的OOP方法......可能使用源示例吗? - gnarf
@Jeff,这样做,我们实际上需要创建一个新的子类 每 匿名功能。除非有办法进行匿名课程,否则这是不可维护和毫无意义的。 - Pacerier
@gnarf,这就是为什么没有源代码示例的原因。这是因为这种方法是 不干净 一点都不这基本上要求您为每个回调创建一个新的子类。因此,如果您需要10个回调,则需要创建10个新类 SubClass1 至 SubClass10。 - Pacerier
@JeffStanden,这只是他提出的一个例子。在任何非平凡的应用程序中,您将能够找到数百个匿名函数。这意味着使用您的解决方案我们需要声明数百个新的子类。不是个好主意。 - Pacerier
@JeffStanden,数以百计的匿名函数绝对不是设计问题。确实以功能的方式编写代码 要求 数百个匿名函数。 create_function  确实避免 必须为函数指定名称。唯一不合理的是身体需要成为一个字符串,否则它完全正常。也, 码 有一个 令人惊讶的长 生命周期和不仅仅是经常使用的功能被附加到旧代码上。所以不要惊讶于这个问题现在仍然有效,而且未来也是如此 远没有实际意义。 - Pacerier