萌新laravel踩坑记一:ServiceProvider

一直就听说过laravel框架,但是从来也没用过,最近有个项目有机会用到,算是个小项目,但是中间遇到的坑还是挺多的,目的就是想记录一下,供大家参考。

注:笔者用的是 laravel 10.48.12

功能需求

  • 需求是说,需要将数据库中的图片资源加上七牛云的链接,由于桶设置了私有属性,所以必须通过算法生成链接,因此就想抽象出一个类,同时使用 ServiceProvider 的方式注入进来,经大佬指点,由于是简单的client类,可以直接用简单注入的方式来实现。

实现部分 已弃用

  1. 首先在Services下创建一个七牛云的 Client 类,用于处理七牛云逻辑
  2. 其次,使用 php artisan make:provider 命令创建一个 QiniuServicesProvider类,并在类中加入:
    class QiniuServicesProvider extends ServiceProvider
    {
     public function register()
     {
         $this->app->singleton(Client::class, function () {
             return new Client();
         });
     }
    }
  3. 使用,直接在XXXController.php中,使用App::make(Client::class)的方式来创建出client实例即可

已更正,使用简单注入的方式实现

use App\Services\Qiniu\Client;
class Home extends Controller
{
    public function __construct(protected Client $client)
    {
    }
}

坑点

  1. 看文档时,不太了解 ServiceProvider的相关概念,以为是直接在Provider中,直接写逻辑,现在一看真的是差太远。
  2. Provider中,原来是想使用构造函数中加入配置参数进行实例化,但是看了下实践,还是觉得直接在Client类内部自动处理配置逻辑比较合适

多说一句

laravel小白第一次上手写,请轻喷

疑惑

何时使用 ServiceProvider 目前还没有想清楚,本着如不了解,就不使用的原则,暂时先打个记号,可能等后面具体用到了就能解惑了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
个人博客,随意转载
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 15
JaguarJack

:sweat_smile: 你这个直接注入不就行了吗?没必要这样

3周前 评论
zanetti (楼主) 3周前
JaguarJack (作者) 3周前
zanetti (楼主) 3周前

单词拼错了吧,一会儿 Service 一会儿 Server

3周前 评论
zanetti (楼主) 3周前
goStruct

一般接口实现用服务注册

3周前 评论
zanetti (楼主) 3周前
fatrbaby

需要理解一下依赖倒置原则,才能明白为什么要这么做

3周前 评论
zanetti (楼主) 3周前

如果一个类存在依赖嵌套或经常用到可以考虑通过服务提供者将其注册到容器里去。另外用依赖注入,框架其实也会先到容器里找到这个类的实例,找到就返回,没找到就再解析。

3周前 评论

如果不用到接口,那么没必要做这个

2周前 评论
sanders

我记得七牛有好几个兼容 laravel 的扩展,比如超哥的这个 overtrue/laravel-filesystem-qiniu,安装后配置一下就可以用。用法跟框架自己提供的文件存储用法是一样的(如果配置成默认的驱动)。

另外回答一下楼主的疑问,对框架使用者来说,使用服务提供者最多的场景可能是批量替换代码中的某个类或某个实例化的方法。但对于扩展开发者来讲,这是将自己的功能混入使用者程序最丝滑的方式。就跟我上面提到的这个七牛文件系统扩展一样,你可以看一下他项目中的服务提供者代码非常简单就将自己的驱动加入到程序的驱动列表中:github.com/overtrue/laravel-filesy...

但一定要注意的是:如果使用服务提供者,那么你在项目代码中就尽量不要直接实例化,最好要使用依赖注入的方式,最次也只能使用解析的方式 (app() 函数或 resolve() 函数)。

2周前 评论
zanetti (楼主) 2周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!