如何更好地使用单行为控制器
大家好
今天这篇文章,我们将讨论下 Laravel 的单行为控制器,那你知道什么是单行为控制器吗?
单行为控制器就是借助 php 的魔术方法: __invoke() 从而实现以使用方法的形式使用控制器,并且一个控制器仅仅提供一个操作。
你可能不理解为什么要这么操作,下面我们将通过一些例子来说明我们为什么要这样做。下面开始:
在这个事例中,我们将看一下如何通过一个路由实现多个页面的调用。例如 about,contact,以及 terms 等页面,下面我们看一下这个 __invoke() 是如何运作的。
Route::get('/{pages}','TestController');
你可以看到,代码中仅有一个 invoke 方法,它允许你像使用方法一样使用这个控制器。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function __invoke()
{
//逻辑代码
}
}
下面我们看一下如何在路由中使用它。
在之前我们的路由可能看起来像下面这样:
Route::get('about', 'TestController@about');
Route::get('contact', 'TestController@contact');
Route::get('terms', 'TestController@terms');
现在,我们可以这样写:
Route::get('/{pages}','TestController')
->name('page');
在浏览器访问你的网址你会发现,它调用的正是你写在 __invoke 方法中的逻辑。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function __invoke()
{
return view('pages.' . request()->segment(1));
}
}
通过路由参数的传递,laravel 分别向我们展示了下面几个不同的页面:
resources/views/pages/contact.blade.php
resources/views/pages/about.blade.php
resources/views/pages/terms.blade.php
当然,想要实现上面的效果,你需要像下面这样修改你的路由:
<a class="nav-link" href="{{ route('page','contact') }}">{{ __('Contact') }}</a>
<a class="nav-link" href="{{ route('page','about') }}">{{ __('About') }}</a>
<a class="nav-link" href="{{ route('page','terms') }}">{{ __('Terms') }}</a>
这里第一个参数是我们的路由名称,第二个参数是你想要看到的页面;
他还有改进的空间,例如当你访问一个不存在的页面的时候,他会触发类似于 view x not found 的错误,显然,这并不是我们想让客户看到的。
Route::get('/{pages}','TestController')
->name('page')
->where('pages','about|contact|terms');
现在,我们限制了他可以处理路由的枚举值,只有在你输入的值匹配的时候才会显示相应的页面。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function __invoke($page)
{
return view('pages.' . $page);
}
}
现在我们访问不存在在的页面的时候,laravel 会抛出 404 not found 提示信息,而并非之前的错误页面了。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
如果这么写,不同页面不同的数据,怎么处理比较好呢?加一个通用的仓库层,还是怎么做,有大佬解答一下码