首页 > PHP > Laravel 服务容器 生活示例和代码

Laravel 服务容器 生活示例和代码

2025-02-01 19:01:05

日常比喻

 

把 Laravel 服务容器想象成一个大型的汽车维修中心。这个维修中心就像是服务容器,而汽车的各种零部件(如发动机、轮胎、刹车系统等)就好比是应用程序里的各类对象(类的实例)。

依赖注入

 

当一位技师要维修一辆汽车时,他不需要自己去市场上购买各种零部件来组装,只需要向维修中心的仓库管理员说明需要哪些零部件,管理员就会从仓库里把相应的零部件拿给他。在 Laravel 应用中,当一个类需要依赖其他类的实例时,不用在类内部手动创建这些依赖,只需要向服务容器请求,服务容器就会把相应的实例提供给它,这就是依赖注入。

单例模式

 

维修中心里可能有一些特殊的工具,比如高精度的测量仪器,整个维修中心只有一台。无论哪个技师需要使用这个仪器,都会从同一个地方拿到它。在 Laravel 服务容器中,单例模式就类似这种情况,对于某些类,服务容器只创建一个实例,并且在整个应用程序的生命周期内都使用这同一个实例。

绑定接口到具体实现

 

想象维修中心里有多种品牌的轮胎可供选择,比如米其林、普利司通等。技师在维修汽车时,只需要告诉管理员需要轮胎,管理员可以根据不同的情况选择不同品牌的轮胎提供给技师。在 Laravel 中,接口就像是 “轮胎” 这个概念,具体的实现类就像不同品牌的轮胎,你可以将接口绑定到不同的具体实现类上,服务容器会根据绑定关系提供合适的实例。

代码示例

1. 定义相关类和接口

 

收起
php
 
 
 
 
// 定义一个轮胎接口
interface Tire
{
    public function getBrand();
}

// 定义米其林轮胎实现类
class MichelinTire implements Tire
{
    public function getBrand()
    {
        return 'Michelin';
    }
}

// 定义普利司通轮胎实现类
class BridgestoneTire implements Tire
{
    public function getBrand()
    {
        return 'Bridgestone';
    }
}

// 定义汽车类,依赖轮胎接口
class Car
{
    private $tire;

    public function __construct(Tire $tire)
    {
        $this->tire = $tire;
    }

    public function showTireBrand()
    {
        return 'This car uses ' . $this->tire->getBrand() . ' tires.';
    }
}

// 定义特殊工具类,使用单例模式
class SpecialTool
{
    private static $instance;

    private function __construct() {}

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function useTool()
    {
        return 'Using the special tool.';
    }
}

2. 在 Laravel 服务提供者中进行绑定

 

收起
php
 
 
 
 
// 在 AppServiceProvider 中进行绑定
namespace App\Providers;

use App\Car;
use App\MichelinTire;
use App\BridgestoneTire;
use App\SpecialTool;
use App\Tire;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        // 绑定接口到具体实现
        $this->app->bind(Tire::class, function ($app) {
            // 这里可以根据不同条件选择不同的实现类,例如配置文件中的设置
            return new MichelinTire();
        });

        // 注册单例
        $this->app->singleton(SpecialTool::class, function ($app) {
            return SpecialTool::getInstance();
        });

        // 绑定汽车类
        $this->app->bind(Car::class, function ($app) {
            return new Car($app->make(Tire::class));
        });
    }
}

3. 在控制器中使用服务容器

 

收起
php
 
 
 
 
// 在控制器中使用服务容器
namespace App\Http\Controllers;

use App\Car;
use App\SpecialTool;
use Illuminate\Http\Request;

class CarController extends Controller
{
    public function showCarInfo()
    {
        // 获取汽车实例,服务容器自动注入轮胎实例
        $car = app(Car::class);
        $carInfo = $car->showTireBrand();

        // 获取特殊工具单例实例
        $tool = app(SpecialTool::class);
        $toolUsage = $tool->useTool();

        return response()->json([
            'car_info' => $carInfo,
            'tool_usage' => $toolUsage
        ]);
    }
}

代码解释

 

  • 接口和实现类:定义了 Tire 接口以及 MichelinTire 和 BridgestoneTire 两个实现类,模拟不同品牌的轮胎。Car 类依赖于 Tire 接口,通过构造函数注入轮胎实例。SpecialTool 类使用单例模式,确保整个应用中只有一个实例。
  • 服务提供者:在 AppServiceProvider 中,使用 bind 方法将 Tire 接口绑定到 MichelinTire 实现类,使用 singleton 方法注册 SpecialTool 类为单例,同时绑定 Car 类并注入 Tire 实例。
  • 控制器:在 CarController 中,使用 app() 辅助函数从服务容器中获取 Car 实例和 SpecialTool 单例实例,并调用相应的方法输出信息。
使用 Ctrl+D 可将网站添加到书签
收藏网站
扫描二维码
关注早实习微信公众号
官方公众号
Top