尽管将应用程序的所有逻辑都塞进控制器中可能很诱人,但最好将控制器视为在你的应用程序中调度路由HTTP请求的交通警察。 因为请求还可以通过其他方式进入您的应用程序(定时作业,Artisan命令行调用,队列作业等),因此明智的做法是不要依赖控制器来执行很多操作。 这意味着控制器的主要工作是捕获HTTP请求的意图并将其传递给应用程序的其余部分。

创建控制器

php artisan make:controller TasksController

This will create a new file named TasksController.php in app/Http/Controllers

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. class TasksController extends Controller
  5. {
  6. //
  7. }

tip: 注意命名空间问题,默认 app/Http/Controllers, 如果需要自定义,请在生成时指定。

依赖注入

larave 的 facades 和 全局的帮助函数,为我们提供了很多有用的接口,但是如果你要使用一个 laravel 没有提供的服务,你就需要把该服务注入到控制器中。

如下:

// 使用帮助函数
public function store()
{
    Task::create(request()->only(['title', 'description']));
    return redirect('tasks');
}

// 使用依赖注入
public function store(\Illuminate\Http\Request $request)
{
    Task::create($request->only(['title', 'description']));
    return redirect('tasks');
}

laravel 依赖注入的实现是 laravel 服务容器的功劳,就像一点魔法,所有控制器的方法(包括构造方法),都从容器中解析出来,也就意味着,如果你指定了方法参数的 类名和接口名,容器就知道如何解析,并自动注入。

// Logger 告诉 php 传递给构造函数的参数必须是 Logger 的类或接口
public function __construct(Logger $logger) {

}

资源控制器

  • 生成资源控制器
    php artisan make:controller MySampleResourceController --resource

  • 注册资源路由
    Route::resource('tasks', 'TasksController');

API资源控制器

  • 生成API资源控制器
    php artisan make:controller MySampleResourceController --api

  • 注册API资源路由
    Route::apiResource('tasks', 'TasksController');

与资源控制器相比,少了 create 和 edit 方法。

单方法控制器

有时你的控制器只为一个路由提供服务,也就是只有一个方法,你可能纠结,该怎么为这个方法命名。谢天谢地,laravel 允许你直接将单个路由指向单个控制器,而不用思考怎么命名方法。

其实,laravel 使用了 __invoke 的 php 魔术方法,它允许你像调用一个方法一样,调用一个类的实例。

// \App\Http\Controllers\UpdateUserAvatar.php
public function __invoke(User $user)
{
    // Update the user's avatar image
}

// routes/web.php
Route::post('users/{user}/update-avatar', 'UpdateUserAvatar');