【问题标题】:Can I create a new class that inherits from User in Laravel 5.2?我可以在 Laravel 5.2 中创建一个继承自 User 的新类吗?
【发布时间】:2016-04-11 17:47:04
【问题描述】:

我对 laravel 很陌生(使用 5.2,这是迄今为止的最新版本),因此我有以下两难境地:我知道 Laravel 带有一个开箱即用的 User 类,但我想开发在这个系统中,我可以拥有另外两种类型的用户,分别称为 ResearcherAdmin

我主要需要创建完全不同的用户类别(研究员和管理员),可能继承自 User,因为它们之间的业务逻辑几乎 100% 不同,我不想在数据库中创建一个列来分类用户的类型。此外,股票UserAdminResearcher 类之间重叠的字段并不多。

我的主要问题是:如果我从 User 继承其他 2 个类,那么一切是否仍能正常工作(Auth Controller、启用中间件等)?我知道 OOP 的原理,凭直觉,我认为如果我执行以下操作应该没问题:

//'Stock' User class:
//
class User extends Authenticatable{
    //Any overlapping logic between Researcher and Admin.
}


class Researcher extends User{
    //My class definition here.
}

class Admin extends User{
    //My class definition here.
}

然后像我通常使用类User 的实例一样使用这两个类。我的意思是使用所有方法和开箱即用的User 功能。

问题扩展: 在写我的问题时,我意识到 User 类默认看起来像这样:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

我不能只执行以下操作而不是从 User 继承来创建我的其他 2 个类(ResearcherAdmin):

//Researcher Class:
namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Researcher extends Authenticatable
{
    //Class definition...
}

...

//Admin Class:
namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    //Class definition
}

在这种方法中,我试图“模仿”User 类。问题是我不知道内核中是否有任何逻辑被硬编码并被隐式引用到User 类。

任何想法和帮助将不胜感激。对不起,如果这对你来说很愚蠢。我刚刚开始使用 laravel 框架。

干杯!

【问题讨论】:

标签: php oop laravel laravel-5 laravel-5.2


【解决方案1】:

是的,你可以扩展类Illuminate\Foundation\Auth\User

use Illuminate\Foundation\Auth\User as Authenticatable;

class Researcher extends Authenticatable {
    //My class definition here.
}

如果你看看User类:

class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;
}

您会看到它扩展了 Model 类并实现了所有其他有用的身份验证处理接口

您可以安全地扩展 User 类,因为 Laravel 足以使用 Illuminate\Contracts\Auth\Authenticatable 接口来处理身份验证,而不是直接使用 User

事实上,如果你签到:

Illuminate/Auth/SessionGuard.php

这是身份验证处理的主要类,您会看到所有身份验证操作都是针对Illuminate\Contracts\Auth\Authenticatable 接口进行的,即:

/**
 * Log a user into the application.
 *
 * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
 * @param  bool  $remember
 * @return void
 */
public function login(AuthenticatableContract $user, $remember = false)
{
    //other code
} 

我认为您真正的问题是:如何在身份验证过程中实例化 ResearcherAdmin 类而不是 User 类?

如果您使用 Eloquent 作为身份验证驱动程序,默认情况下 Laravel 将使用 Illuminate\Auth\EloquentUserProvider 创建模型的实例。所以,如果你想创建一个你的类的实例而不是User,你应该覆盖这个提供者(或创建你自己的一个),在这里你可以选择要实例化的类

【讨论】:

  • 我认为最好的方法是采用您的方法。我唯一想知道的是我在哪里注册那个新的供应商?我假设App\config\app.php 对吗?我的第一个想法是在Illuminate\Auth` as EloquentAdminProvider` 和EloquentResearcherProvider 下同时创建,但这没有多大意义,因为它不是 Illuminate 软件包的一部分。我想我会在“自定义”目录 `App\Custom\Providers` 下创建这两个提供程序。
  • @JackGal :您可以创建一个自定义服务提供者,您可以在其中注册新的EloquentResearcherProvider。并让应用程序使用它而不是默认的EloquentUserProvider。你永远不应该在vendor 文件夹下编写代码
【解决方案2】:

我认为使用此概念的最佳方法是使用角色并保持用户类不变。详情请见https://github.com/spatie/laravel-permission

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 2023-03-26
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多