如何使用Closure对象调用所需的函数?

时间:2013-05-22 07:09:28

标签: php

我创建了一个基本类来使用Closure对象。我不明白这个应用程序/闭包的行为所以我想问一些事情。我的思绪目前相当混乱,所以我不知道为什么会出现问题,或者为什么不运行。

<?php

class Route
{
     public static $bindings = array();
     public static $dispatch = array();

     public static function bind($bind)
     {
         self::$bindings[] = $bind;
     }

     public static function getAllBindings()
     {
         return (array) self::$bindings;
     }

     public static function get($binding, Closure $dispatch)
     {

         if(in_array($binding, self::$bindings))
         {
             if(is_callable($dispatch))
             {
                 return call_user_func($dispatch);
             }
             else
             {
                 die("Dispatch method is not callable.");
             }
         }
         else
         {
             die("Binding is not found in bindings array.");
         }
     }

     public static function test()
     {
         echo "Test ran!";
     }
 }

基本上,我们绑定绑定(例如/ admin,/ account,/ profile等)然后,我们尝试使用闭包调用方法。

// Let's bind account and admin as available bindings
    Route::bind('account');
    Route::bind('admin');

// Let's try doing a get call with parameter "account"
    Route::get('account', function() { 
         // This is where I'm stuck. See below examples:
         // Route::test();
         // return "test";
         // return "testa";
         // return self::test();
    });

如果你在上面检查过,这是我的问题:

  1. 如果我提供的方法不存在,则is_callable检查不会运行,我会收到php fatal error。是否is_callable是检查不存在的方法的有效检查?为什么会这样?
  2. 如果我在关闭中提供return "Test";,我的$closure parameter in get method是否会包含"Test"字符串?
  3. 我可以从闭包内的不同类传递方法吗?像:

    Route::get('account', function () {
        if(User::isLoggedIn() !== true)
             return Error::login_error('Unauthorized.');
    });
    
  4. 如果是这样,这个电话的范围在哪? PHP的闭包范围,或者call_user_func是否在Route类的范围内调用它,因为它是通过闭包传递给它的? (为了清楚一点,PHP的范围可能会$route->get但是关闭范围可能会使用$this->get
  5. 有没有办法像var_dump / print_r一样转储Closure对象来查看它的内容?
  6. 简短的指导将让我前进。我知道PHP,但使用闭包对我来说是一个新手。

    非常感谢,感谢您的回复。

1 个答案:

答案 0 :(得分:1)

您不需要is_callable()检查,因为方法声明中的Closure类型提示已经确保了这一点。您也不需要call_user_func()。这将为您提供以下get()方法:

 public static function get($binding, Closure $dispatch)
 {

     if(!in_array($binding, self::$bindings))
     {
         die("Binding is not found in bindings array.");
     }

     return $dispatch();
 }

注意:目前$binding param只会在支票中使用,但不会作为$dispatch()的参数,我的预期是什么。我看不出原因。你应该重新考虑这部分


我在帖子中发现了另一个隐藏的问题:

// Let's try doing a get call with parameter "account"
Route::get('account', function() { 
    // This is where I'm stuck. See below examples:
    // Route::test();
    // return "test";
    // return "testa";
    // return self::test();
});

应该看起来像:

// Let's try doing a get call with parameter "account"
Route::get('account', function() { 
    // Both should work well:
    // Route::test();
    // .. or 
    // return self::test();
});