浅谈lumen的自定义依赖注入

比如我现在有个token认证系统,目前我用mysql的token表实现,将来有可能会改成redis,怎么实现未来的无缝连接呢。

先定义一个合约文件app/Contracts/TokenHandler.php

<?php 

namespace App\Contracts; 

/**
 * 处理Token的Contracts
 * @package App\Contracts
 */
interface TokenHandler
{
 /**
  * 创建一个token
  * @param $userId integer 用户Id
  * @return string
  */
 public function createToken($userId); 

 /**
  * 得到该token的用户
  * @param $token string token值
  * @return \App\User 拥有该token的用户
  */
 public function getTokenUser($token); 

 /**
  * 删除一个token
  * @param $token string token值
  * @return bool 是否成功
  */
 public function removeToken($token);
}

这里定义了3个方法:创建token,得到token对应用户,删除token。

然后我们写一个Mysql下的实现app/Services/MysqlTokenHandler.php

<?php 

namespace App\Services; 

use App\Contracts\TokenHandler;
use App\Orm\Token; 

/**
 * 处理Token的Contracts对应的Mysql Service
 * @package App\Services
 */
class MysqlTokenHandler implements TokenHandler
{
 /**
  * @var int 一个用户能够拥有的token最大值
  */
 protected $userTokensMax = 10; 

 /**
  * @inheritdoc
  */
 public function createToken($userId)
 {
  while (Token::where('user_id', $userId)->count() >= $this->userTokensMax) {
   Token::where('user_id', $userId)->orderBy('updated_at', 'asc')->first()->delete();
  } 

  $token = \Illuminate\Support\Str::random(32);
  if (!Token::create(['token' => $token, 'user_id' => $userId])) {
   return false;
  } 

  return $token;
 } 

 /**
  * @inheritdoc
  */
 public function getTokenUser($token)
 {
  $tokenObject = Token::where('token', $token)->first(); 

  return $tokenObject && $tokenObject->user ? $tokenObject->user : false;
 } 

 /**
  * @inheritdoc
  */
 public function removeToken($token)
 {
  return Token::find($token)->delete();
 }
}

然后在bootstrap/app.php里绑定两者的映射关系:

$app->singleton(
 App\Contracts\TokenHandler::class,
 App\Services\MysqlTokenHandler::class
);

如果将来换成了redis,只要重新写一个RedisTokenHandler的实现并重新绑定即可,具体的业务逻辑代码不需要任何改变。

于是在controller里就可以直接注入该对象实例,只要在参数前声明合约类型:

public function logout(Request $request, TokenHandler $tokenHandler)
{
 if ($tokenHandler->removeToken($request->input('api_token'))) {
  return $this->success([]);
 } else {
  return $this->error(Lang::get('messages.logout_fail'));
 }
}

也可以在代码里手动得到注入对象的实例,比如:

$currentUser = app(\App\Contracts\TokenHandler::class)->getTokenUser($request->input('api_token'));

以上这篇浅谈lumen的自定义依赖注入就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈lumen的自定义依赖注入

    比如我现在有个token认证系统,目前我用mysql的token表实现,将来有可能会改成redis,怎么实现未来的无缝连接呢. 先定义一个合约文件app/Contracts/TokenHandler.php <?php namespace App\Contracts; /** * 处理Token的Contracts * @package App\Contracts */ interface TokenHandler { /** * 创建一个token * @param $userId integ

  • 浅谈Spring 解决循环依赖必须要三级缓存吗

    我们都知道 Spring 是通过三级缓存来解决循环依赖的,但是解决循环依赖真的需要使用到三级缓冲吗?只使用两级缓存是否可以呢?本篇文章就 Spring 是如何使用三级缓存解决循环依赖作为引子,验证两级缓存是否可以解决循环依赖. 循环依赖 既然要解决循环依赖,那么就要知道循环依赖是什么.如下图所示: 通过上图,我们可以看出: A 依赖于 B B 依赖于 C C 依赖于 A public class A { private B b; } public class B { private C c; }

  • 浅谈SpringBoot如何自定义Starters

    一.Starters原理 1.1 Starters场景启动器 1.场景需要用到的依赖是什么? 比如依赖的jar 2.如何编写自动配置? 以WebMvcAutoConfiguration自动配置为例: @Configuration @ConditionalOnWebApplication @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class }) @Conditiona

  • 浅谈keras中自定义二分类任务评价指标metrics的方法以及代码

    对于二分类任务,keras现有的评价指标只有binary_accuracy,即二分类准确率,但是评估模型的性能有时需要一些其他的评价指标,例如精确率,召回率,F1-score等等,因此需要使用keras提供的自定义评价函数功能构建出针对二分类任务的各类评价指标. keras提供的自定义评价函数功能需要以如下两个张量作为输入,并返回一个张量作为输出. y_true:数据集真实值组成的一阶张量. y_pred:数据集输出值组成的一阶张量. tf.round()可对张量四舍五入,因此tf.round(

  • 浅谈Docker如何自定义host文件

    目录 一.命令 二.docker-compose.yml 三.dockerfile 四.直接修改 五.修改镜像 总结 1.问:我们的真正开发的时候数据库都是部署在内网的,而我们程序连接数据库的时候,需要指定内网的地址.但是有时候我们需要迁移环境,那么我们的后端代码就得跟着进行修改,有没有一种好的办法,不让我们修改代码吗? 答:可以肯定的说是有的,那就是在代码中指定的不是IP地址,而是域名.我们只需要配置域名和IP地址建立映射关系,所有的项目都无需更改代码就可以达到目的. 2.问:正式环境一般都是

  • 浅谈为什么#{}可以防止SQL注入

    目录 #{} 和 ${} 的区别 #{} 底层是如何防止 SQL 注入的? 为什么能防止SQL注入? #{} 和 ${} 的区别 #{} 匹配的是一个占位符,相当于 JDBC 中的一个?,会对一些敏感字符进行过滤,编译过后会对传递的值加上双引号,因此可以防止 SQL 注入问题. ${} 匹配的是真实传递的值,传递过后,会与 SQL 语句进行字符串拼接.${} 会与其他 SQL 进行字符串拼接,无法防止 SQL 注入问题. <mapper namespace="com.gitee.shiay

  • 浅谈Spring解决循环依赖的三种方式

    引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种:构造器参数循环依赖 表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyIn CreationException异常表示循环依赖. 如在创建TestA类时,构造器需要TestB类,那将去创建TestB,在创建TestB类时又发现需要TestC类,则又去创建Test

  • 浅谈一次与sql注入 & webshell 的美丽“邂逅”

    引言 一波未平,一波又起.金融公司的业务实在是太引人耳目,何况我们公司的业处正处于风口之上(区块链金融),并且每天有大量现金交易,所以不知道有多少躲在暗处一直在盯着你的系统,让你防不胜防,并且想方设法的找到突破点,以达到的目的来获取非法利益. 俗话说:"道高一尺,魔高一丈".系统和代码也可以这么理解,防的在好,总有漏洞.系统和代码也没有绝对的安全.该来的总会来...... sql注入与"她"相遇 某一天,天气晴朗,心情舒畅."她"来了,打破了笔者

  • 浅谈goland导入自定义包时出错(一招解决问题)

    使用goland编写go语言程序的时候,发现针对自定义的包无法引入. 如下图所示: 具体错误也就是 main.go:13:2: cannot find package "grpool" in any of: 然后就各种在网上查找,大多数也都讲得很不清楚,最后找到一个说的比较详细的链接 //www.jb51.net/article/202148.htm. 但是这个链接也只是启发了我.下面来图形结合的方式讲述我的方法. (1)首先将之前定义的包和包下的文件移至到新定义的目录src下,我的目

  • 浅谈Vue项目骨架屏注入实践

    相比于早些年前后端代码紧密耦合.后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主业.然而在带来便利的同时,也带来了一些弊端,比如首屏渲染时间(FCP)因为首屏需要请求更多内容,比原来多了更多HTTP的往返时间(RTT),这造成了白屏,如果白屏时间过长,用户体验会大打折扣,如果用户网速差,则FCP会更长. 由此引申出一系列的优化方法,骨架屏也因此被提出. 1. FCP优化 在 Google 提出的以用户为中心

随机推荐