请问如何在一个请求的生命周期里复用类?

ljnchn

比方时候登陆之后的用户类,登陆之后,可以在任意地方调用这个类,获取已登录的信息?

193 5 1
5个回答

2548a

你说的东西叫session,
你要搞清楚,http是短链接,请求的生命周期在你返回响应以后已经结束,webman虽然在运行,但那是webman的生命周期,不是你这个请求的生命周期.所以,当下一次请求上来的时候,除非它携带cookie或者你自定义的校验参数上来,不然根本不知道这个请求是谁.

  • ljnchn 8天前

    嗯,可能想岔了。其实就是看到 laravel 可以在Auth::login 后,随意在代码其他地方获取用户信息,不知道 webman 怎么实现😂

  • walkor 8天前

    自己实现一个类或者函数取下session就好了,例如app/functions.php里定义一个函数

    function user()
    {
        // 假设登录用户会写一个user_info为key的session信息
        return session('user_info');
    }
  • ljnchn 8天前

    好的,多谢!

liziyu

beforeAction() 配合中间件实现,应该可以。
我没试过!

  • 极胜100 8天前

    其实就是单例,或者 static,但是webman中记得请求完成后手动清理掉

tangzhangming

我之前写了一个 群主不让我合并到主框架 给你参考一下吧

<?php
namespace Webman\Auth;

use Webman\App;

class AuthManger
{

    /**
     * 登录页地址
     */
    protected $login_url;

    /**
     * 登录成功后跳转地址
     */
    protected $return_url;

    /**
     * session中保存用户ID的键名
     */
    protected $user_id_key;

    /**
     * 当前用户的认证类
     */
    protected $identityClass;

    private $_identity;

    public function __construct($guard='web')
    {
        $config = config("auth.guards.{$guard}");

        //默认用户组不配置则使用默认配置
        if( $guard=='web' && is_null($config) ){
            $config = self::default();
        }

        if( $config && is_array($config) ){
            foreach ($config as $key => $value) {
                $this->$key = $value;
            }
        }
    }

    /**
     * 默认用户组配置
     */
    public static function default()
    {
        return [
            'user_id_key'   => '6ac21fd8270b4f6d_id',
            'login_url'     => 'login',
            'return_url'    => '/?login_success',
            'identityClass' => '\app\model\User',
        ];
    }

    /**
     * 指定看守器
     */
    public function guard(string $guard)
    {
        return (new self($guard));
    }

    /**
     * 返回当前看守器用户储存在session中的key
     */
    protected function get_login_id()
    {
        return $this->user_id_key;
    }

    /**
     * 登录
     */
    public function login($user)
    {
        return App::request()->session()->set($this->get_login_id(), $user->id());
    }

    /**
     * 退出
     */
    public function logout()
    {
        return App::request()->session()->forget($this->get_login_id());
    }

    /**
     * 是否为游客
     * @return 布尔值
     */
    public function IsGuest()
    {
        return $this->user() === null;
    }

    /**
     * 强制登录 否则跳转至登录页面
     * webman中无法使用redirect
     */
    public function loginRequired()
    {
        if( $this->IsGuest() ){
            return redirect('/');
        }
    }

    /**
     * 返回用户ID
     */
    public function id()
    {
        if( $this->_identity == false ){
            $this->renewAuthStatus();
        }

        return $this->_identity->id();
    }

    /**
     * 获取用户类实例
     */
    public function user()
    {
        if( $this->_identity == false ){
            $this->renewAuthStatus();
        }

        return $this->_identity;
    }

    protected function renewAuthStatus()
    {
        $id = App::request()->session()->get($this->get_login_id());

        //读取用户信息
        if( $id == null ){
            $identity = null;
        }else{
            $class = $this->identityClass;
            $identity = $class::findIdentity($id);
        }

        //验证validateAuthKey
        if ($identity !== null){

        }

        $this->setIdentity($identity);
    }

    protected function setIdentity($identity)
    {
        if( $identity instanceof \Webman\Auth\IdentityInterface ){
            $this->_identity = $identity;

        }elseif ($identity === null){
            $this->_identity = null;

        }else{
            throw new \Exception("identity must implements from IdentityInterface");

        }
    }
}

Support下建一个单例类

<?php
namespace support;

use Webman\Auth\AuthManger;

class Auth
{

    public static function __callStatic($method, $args)
    {
        $request = request();
        if( !$request->auth_instance ){
            $request->auth_instance = new AuthManger();
        }
        $instance = $request->auth_instance ;

        if (! $instance) {
            throw new RuntimeException('未获取到 Webman\Auth\Auth 的实例');
        }

        return $instance->$method(...$args);
    }

}

User模型

<?php

namespace app\model;

use support\Model;
use Webman\Auth\IdentityInterface;

class User extends Model implements IdentityInterface
{

    protected $table = 'user';

    public function id()
    {
        return $this->id;
    }

    public static function findIdentity($id)
    {
        return self::where('id', $id)->first();
    }

    public static function findByLoginName($login_name)
    {
        if( filter_var($login_name, FILTER_VALIDATE_EMAIL) ){
            $login_field = 'email';
        }else{
            $login_field = 'mobile';
        }

        return self::where($login_field, $login_name)->first();
    }

    public function validatePassword($password)
    {
        return $this->password == $password;
    }

    public function setPassword($password)
    {
        return $this->password = md5($password);
    }
}

命名空间你按自己放的位置和需求改一下吧

//用法
use support\Auth;

Auth::login($user)

Auth::logout()

if( !Auth::IsGuest() ){
    return Auth::user()->username
}

Auth::guard('admin')->login($user)
  • ljnchn 8天前

    ok,我参考一下,多谢

tegic

楼上有位老哥说的是对的,就是请求生命周期单例。
你可以放到request里面,例如:

.
.
.
$data = 123;
$request->data = $data;

然后在业务代码里获取request就行

  • 暂无评论
橘叔

直接中间件处理...在中间件中读取请求中的TOKEN,缓存读取用户信息,存到request上,进行读取.如果是其他的类,可以使用DI依赖注入或者直接静态类。(谨慎使用静态变量)

  • 暂无评论
🔝