Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在yii2中使用两种不同的模型登录或切换标识类?_Php_Yii_Yii2_Yii2 Basic App_Yii2 User - Fatal编程技术网

Php 如何在yii2中使用两种不同的模型登录或切换标识类?

Php 如何在yii2中使用两种不同的模型登录或切换标识类?,php,yii,yii2,yii2-basic-app,yii2-user,Php,Yii,Yii2,Yii2 Basic App,Yii2 User,我想允许用户从两个不同的模型登录 Config.php LoginForm.php User.php Controller.php 我不知道如何验证家长登录。我花了几个小时寻找解决办法,但没有成功 我被困在Yii::$app->user->login($this->getUser(),$this->rememberMe?3600*24*30:0)因为用户表没有父登录记录 我的问题 1) 是否可以有两个identityClass。如果是,那怎么办 2) 是否可以将ParentLogin模型扩展到U

我想允许用户从两个不同的模型登录

Config.php

LoginForm.php

User.php

Controller.php

我不知道如何验证家长登录。我花了几个小时寻找解决办法,但没有成功

我被困在
Yii::$app->user->login($this->getUser(),$this->rememberMe?3600*24*30:0)因为用户表没有父登录记录

我的问题

1) 是否可以有两个
identityClass
。如果是,那怎么办
2) 是否可以将
ParentLogin
模型扩展到
User
。如果是,那么如何验证

参考资料




**编辑,这不起作用,您只能有一个标识类** **参考号** 我建议尝试以下方法-未经测试

按照您的建议,在配置中添加一个额外的标识接口

'user' => [
        'identityClass' => 'app\models\User',
        'enableAutoLogin' => false,
        'authTimeout' => 3600*2,
    ],
'parent' => [
        'identityClass' => 'app\models\Parent',
        'enableAutoLogin' => false,
        'authTimeout' => 3600*2,
    ],
然后,您的
父级
模型可以扩展
用户
模型,该模型将提供与原始
用户
模型相同的验证方法,或者从头开始实现
标识接口
。根据
父表中的列名,我建议使用第二种方法,因为列与
用户表不同

然后需要两个
loginForms
loginForm
parentLoginForm
,因为每种情况下的验证都不同


然后,在控制器中,您可以根据需要调用相应的登录表单。

Joe Miller提出了一个很好的建议,即在用户表中使用一个用户类和一些布尔字段来检查用户角色,作为rbac的替代方案。但由于在您的情况下,这是不可能的,因此我可以向您提出以下建议(这种方法经过了一半的测试,需要采用)

是的,您可以有两个或多个IdentityClass,但不能同时使用。您需要处理身份之间的切换。因此,首先,我建议您稍微编辑一下您的
LoginForm
模型:

class LoginForm extends Model
{
    public $username;
    public $password;
    public $rememberMe = true;
    // we added this parameter to handle userModel class
    // that is responsible for getting correct user
    public $userModel;

    private $_user = false;

    /* all other methods stay same */

    /**
     * Finds user by [[username]]
     *
     * @return User|null
     */
    public function getUser()
    {
        if ($this->_user === false) {
            // calling findByUsername method dynamically
            $this->_user = call_user_func(
                [$this->userModel, 'findByUsername'], 
                $this->username
            );
        }

        return $this->_user;
    }
}
现在在控制器中:

public function actionParentLogin()
{
    $model = new LoginForm(['userModel' => ParentLogin::className()]);
    // calling model->login() here as we usually do
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
            // no need to worry about checking if we found parent it's all done polymorphycally for us in LoginForm
            // here is the trick, since we loggin in via parentLogin action we set this session variable.
            Yii::$app->session->set('isParent', true);
            return $this->redirect(['parent-dashboard']);
        } else {
            Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
        }
    }
    return $this->render('parent-login', [
            'model' => $model,
        ]);
}
您的
parentLogin
模型应该扩展
User
模型以使所有这些工作正常:

class parentLogin extends User
{
    public static function tableName()
    {
        //you parent users table name
        return 'parent_users';
    }

    public static function findByUsername($username)
    {
         return static::findOne(['p_username' => $username]);
    }
}
现在,当您登录时,您需要处理标识切换,因为在配置中您有
'identityClass'=>'app\models\User'
。我们可以使用
bootstrap
属性:

//in your config file
'bootstrap' => [
    'log',
    //component for switching identities
    'app\components\IdentitySwitcher'
],
IdentitySwitcher类:

class IdentitySwitcher extends Component implements BootstrapInterface
{
    public function bootstrap($app)
    {
        //we set this in parentLogin action
        //so if we loggin in as a parent user it will be true
        if ($app->session->get('isParent')) {
            $app->user->identityClass = 'app\models\ParentLogin';
        }
    }
}

您是否已经尝试在User.php中扩展您想要的类?@GuilhermeLopes。我试过了,但没有成功。所以,回滚更改。我总是这样做。。。我使用默认模型,并使用findOne的GuilhermeLopes修改默认模型的函数。你能详细说明一下吗。我花了半天的时间来解决这个问题。我不明白为什么你需要两个单独的桌子和模型来解决这个问题。为什么不在
user
表中添加一个extra列,将其称为isParent并将其设置为
boolean
。然后你可以测试它是否正确,做一些事情,如果它是错误的,做一些其他的事情。然后,您只需使用一个模型、一组验证和两个视图,具体取决于
isParent
的值,我已经尝试过了,它不会起作用。它给出了第一个“缺少类”错误,添加后给出了标识错误。是的,刚刚发现这不起作用,只支持一个标识类。我会把这个放在这里,让人们知道它不起作用!谢谢@托尼。检查它。好的,让我知道它是如何进行的。
config
中用于切换标识的组件是什么。对不起,没有得到它。您需要创建一个类。在本例中,我称之为
IdentitySwitcher
。所以您需要创建一个目录组件,并在其中创建IdentitySwitcher.php文件,其中包含来自示例的内容
public function actionParentLogin()
{
    $model = new LoginForm(['userModel' => ParentLogin::className()]);
    // calling model->login() here as we usually do
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
            // no need to worry about checking if we found parent it's all done polymorphycally for us in LoginForm
            // here is the trick, since we loggin in via parentLogin action we set this session variable.
            Yii::$app->session->set('isParent', true);
            return $this->redirect(['parent-dashboard']);
        } else {
            Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
        }
    }
    return $this->render('parent-login', [
            'model' => $model,
        ]);
}
class parentLogin extends User
{
    public static function tableName()
    {
        //you parent users table name
        return 'parent_users';
    }

    public static function findByUsername($username)
    {
         return static::findOne(['p_username' => $username]);
    }
}
//in your config file
'bootstrap' => [
    'log',
    //component for switching identities
    'app\components\IdentitySwitcher'
],
class IdentitySwitcher extends Component implements BootstrapInterface
{
    public function bootstrap($app)
    {
        //we set this in parentLogin action
        //so if we loggin in as a parent user it will be true
        if ($app->session->get('isParent')) {
            $app->user->identityClass = 'app\models\ParentLogin';
        }
    }
}