我需要向两个不同的用户组显示两个不同的索引页。例如,普通用户应该看到一个页面,而特权用户应该看到另一个页面。我看到两种解决此问题的方法:
一个带有条件的索引操作:
public function index()
{
// view for privileged users
if(request()->user()->hasRole('privileged')){
return view('index_privileged');
}
// view for regular users
if(request()->user()->hasRole('regular')){
return view('index_regular');
}
return redirect('/');
}
多个操作:
public function index_privileged()
{
return view('index_privileged');
}
public function index_regular()
{
return view('index_regular');
}
哪种方法更"休息友好",通常更好?
我是灯光控制器的忠实粉丝。 对于一个简单的问题来说,这可能有点过分,但如果这样的事情再次出现,你已经完成了所有设置。
话虽如此,最好创建一个PrivilegedUser
类和一个RegularUser
类,并为它们提供一个返回各自视图的索引方法。 将它们编码到接口UserInterface
,并确保它们都实现了这一点。
这是我测试中的样子。
class RegularUser implements UserInterface
{
public function index()
{
return view('index_regular');
}
}
class PrivilegedUser implements UserInterface
{
public function index()
{
return view('index_privileged');
}
}
interface UserInterface
{
public function index();
}
然后,您可以添加一个侦听器,该侦听器应为事件IlluminateAuthEventsLogin
运行。 当有人登录时,Laravel会自动为您触发此事件。 这将进入文件EventServiceProvider.php
.
protected $listen = [
'IlluminateAuthEventsLogin' => [
'AppListenersAuthLoginListener',
],
];
现在,您可以运行php artisan event:generate
来生成新的侦听器。 这是我的听众的样子,它应该适合你。
namespace AppListeners;
use IlluminateAuthEventsLogin;
use IlluminateFoundationApplication;
class AuthLoginListener
{
/**
* Create the event listener.
*
* @param Application $app
*/
public function __construct(Application $app)
{
$this->app = $app;
}
/**
* Handle the event.
*
* @param Login $event
* @return void
*/
public function handle(Login $event)
{
if ($event->user->hasRole('privileged')) {
$this->app->bind('AppRepositoriesUserInterface', 'AppRepositoriesPrivilegedUser');
} else if ($event->user->hasRole('regular')) {
$this->app->bind('AppRepositoriesUserInterface', 'AppRepositoriesRegularUser');
}
}
}
从本质上讲,这是在告诉Laravel根据刚刚登录的用户类型加载某个类。 User
实例可通过 Laravel 自动传入的 Login
对象获得。
现在一切都设置好了,我们几乎不需要在控制器中做任何事情,如果您需要执行更多因用户而异的操作,只需将它们添加到 RegularUser 或 PrivilegedUser 类即可。 如果你有更多的用户类型,只需为他们编写一个实现接口的新类,在你的AuthLoginListener
中添加一个额外的 else ,你应该很高兴。
要使用它,在您的控制器中,您需要执行以下操作...
// Have Laravel make our user class
$userRepository = App::make('AppRepositoriesUserInterface');
return $userRepository->index()->with('someData', $data);
或者更好的是,将其作为依赖项注入。
use AppRepositoriesUserInterface;
class YourController extends Controller
{
public function index(UserInterface $user)
{
return $user->index();
}
}
编辑:
我刚刚意识到,如果没有满足条件,我忘记了您要return redirect('/');
的部分。 你可以创建一个新的类GuestUser
(我知道这听起来像是矛盾的),它实现了UserInterface
但不是使用AuthLoginListener
,而是在Laravel启动时将其绑定到服务提供商中。 这样,Laravel在需要实现UserInterface
时将始终有返回的内容,以防在没有人登录的情况下需要这个类。
嗯,它更像是一个重构"问题",而不是一个休息友好的问题。查看本指南,您可以看到使 API 友好的大多数事情都与 url 有关。
但是,让我们回答您的问题。您要做的是重构方法,但它不仅是移动方法,而且类似于提取变量。
选项将使代码更具可读性,无论哪种方式都是正确的,但第二个选项对开发人员更友好。它增强了任何开发人员的代码可读性。我建议使用第二个选项。
重构永远不够,但是阅读这样的东西,它会帮助你编写更多可读的代码。