【问题标题】:Converting code with Anonymous functions to PHP 5.2将带有匿名函数的代码转换为 PHP 5.2
【发布时间】:2010-09-28 03:08:08
【问题描述】:

我有一些 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 代码转换为不使用匿名函数的最佳方法是什么?谢谢。

【问题讨论】:

  • 何时、如何以及为什么调用这些回调?
  • @deceze 这个数组被传递给一个视图,该视图处理数组并根据数据创建一个表。为每列中的数据调用回调以格式化数据。因此,如果第一列中的表格单元格值为“Boats”,视图会将其处理为值“Boats 我真的不想要更改视图,因为我有很多控制器像这样使用它。

标签: php anonymous-function


【解决方案1】:

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

$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();

【讨论】:

    【解决方案2】:

    匿名函数非常适合短暂的一次性,例如观察者模式中的事件侦听器。

    但是,由于您已经形式化了一个接口(用于呈现名称、类别、创建日期和删除链接的回调),您还可以去定义一个需要这 4 种方法的“渲染器”接口的额外步骤得以实施。您可以将单个渲染器子类传递给视图,而不是传递回调,然后可以使用它来调用适当的方法。视图还可以通过检查父类来验证它。这仍然允许您本着可移植、可重用 OOP 的精神交换渲染器,而无需匿名函数。

    是否存在您的回调来自任意代码(例如插件)的情况?如果没有,将这些回调匿名化并没有任何好处。看起来您节省了一点命名空间膨胀,但也使调试或记录变得更加困难。

    【讨论】:

    • +1 建议使用更简洁的 OOP 方法...可以使用源示例吗?
    • @Jeff,要做到这一点,我们实际上需要创建一个新的子类 per 匿名函数。除非有办法做匿名类,否则这是不可维护且毫无意义的。
    • @gnarf,没有源示例是有原因的。这是因为这种方法根本不干净。这实质上要求您为每个回调创建一个新的子类。因此,如果您需要 10 个回调,则需要创建 10 个新类 SubClass1SubClass10
    • @JeffStanden,这只是他提出的一个例子。在任何重要的应用程序中,您都可以找到数百个匿名函数。这意味着使用您的解决方案,我们需要声明数百个新的子类。不是个好主意。
    • @JeffStanden,数百个匿名函数绝对不是设计问题。实际上,以函数方式编写代码需要 数百个匿名函数。 create_function 确实避免必须为函数分配名称。唯一不优雅的是身体需要是一根绳子,否则它工作得很好。此外,code 有一个 surprisingly long 生命周期,而且不仅仅是经常将功能附加到旧代码上。所以不要惊讶这个问题现在和未来仍然有效,它远没有实际意义
    猜你喜欢
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    相关资源
    最近更新 更多