当我们的路由没有映射到控制器的方法时,默认会调用控制器的一个__invoke()方法,路由如下:

Route::match('get','/note/{action}','App\Http\Controllers\NoteController');

控制器代码如下:

<?php  
namespace App\Http\Controllers;  
use Illuminate\Http\Request;  
class NoteController extends Controller  
{  
      //默认执行的方法
    public function __invoke(Request $request)
    {
        $action = $request->route('action');//获取路由的参数
        return '您调用了方法:'.$action;
    }
  
}

上面的例子中,路由只映射到控制器但没有控制器的方法,那么它此时会调用控制器的__invoke()方法。

启动项目访问http://127.0.0.1:8000/note/show如下所示:

Laravel 控制器invoke方法

由以上可以看出,通过laravel __invoke()方法可以简化我们的路由定义,下面看下改造后的效果。

<?php  
namespace App\Http\Controllers;  
use Illuminate\Http\Request;  
class NoteController extends Controller  
{ 
    public function __invoke(Request $request)
    {
        $action = $request->route('action');
        //return '您调用了方法:'.$action;
        $method = "_{$action}";
        if (method_exists($this, $method)) {
            $this->$method();
        } else {
            echo "方法不存在";
            return '';
        }
    }

    protected function _show(){
        echo "show some data";
        return ;
    }
    
} 
再次访问 访问http://127.0.0.1:8000/note/show

Laravel 控制器invoke方法

访问一个不存在的方法 http://127.0.0.1:8000/note/xxx

Laravel 控制器invoke方法