我如何使用闭包对象调用所需的函数


How can I make a call to desired function using Closure object?

我创建了一个基本类来处理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 erroris_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在路由类的作用域内调用它,因为它是通过闭包传递给它的?(为了更清楚一点,PHP的作用域可以使用$route->get,但闭包作用域可以使用$this->get)
  5. 是否有任何方法转储关闭对象像var_dump/print_r看到它的内容?
一个简短的指导会让我走。我懂PHP,但是使用闭包对我来说还是很新鲜的。

非常感谢您的回复。

您不需要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参数将只是在检查中使用,但不是作为$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();
});