路由匹配

程序启动后,会进入路由匹配RouteCollection::match()

public function match(Request $request)
{
    #此处获取了所有路由列表
    $routes = $this->get($request->getMethod());

    #通过当前请求与路由列表获取到当前路由
    $route = $this->check($routes, $request);

    if (! is_null($route)) {
        return $route->bind($request);
    }

    $others = $this->checkForAlternateVerbs($request);

    if (count($others) > 0) {
        return $this->getRouteForMethods($request, $others);
    }

    throw new NotFoundHttpException;
}

RouteCollection::match() 方法通过一个闭包函数进行进行判断

protected function check(array $routes, $request, $includingMethod = true)
{
    return Arr::first($routes, function ($key, $value) use ($request, $includingMethod) {
        return $value->matches($request, $includingMethod);
    });
}

Arr::first() 该函数会在闭包函数首次为真时结束循环,并返回所匹配的路由

public static function first($array, callable $callback, $default = null)
{
    foreach ($array as $key => $value) {
        if (call_user_func($callback, $key, $value)) {
            return $value;
        }
    }

    return value($default);
}

延伸阅读【闭包函数】

格式:function($external1, $external2) use($global1, $global2){}
列1:

$arg1 = '外部参数1';
$arg2 = '外部参数2';
$call = function($key, $value) use ($arg1, $arg2) {
  return 'key:' . $key . ',value:' . $value . ',args1:' . $args1 . ',args2:' . $args2;
}
echo $call('函数参数1','函数参数2');
#最终输出的结果为:  
>key:函数参数1,value:函数参数2,args1:外部参数1args2:外部参数2

列2:

class Cart {
    public $products;
    public function addProduct($product) {
        $this->products[] = (int) $product;
        return $this;
    }
}
$cart = new Cart();
$product = 10001;
$func = function($value) use ($product) {
    return $value->addProduct($product);
};
$new_cart = call_user_func($func, $cart);
print_r($new_cart);

Laravel在路由分配中,巧妙的利用了闭包这种特性