Laravel服务容器中的contextual binding(上下文绑定)

PHP Laravel

此文章为作者原创。未经允许,不得用于商业用途。

这一篇其实还是服务容器中的"绑定"的知识,应该与服务容器一起介绍比较合适,只是上一篇《Larave核心概念理解——服务容器与服务提供者》写得有点长而杂了,索性另写一篇来介绍contextual binding。我还是习惯从官方文档来初次认识一些概念,看看官方文档对contextual binding的介绍

Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, two controllers may depend on different implementations of the Illuminate\Contracts\Filesystem\Filesystem contract. Laravel provides a simple, fluent interface for defining this behavior……

可以看到contextual binging针对的是两个或两个以上的类实现同一个接口这种情况,通过简单平滑的接口为每个类注入不同的实现。更多细节请看官方文档https://laravel.com/docs/5.3/container。

下面看上下文是如何工作的。建3个文件,分别为接口文件Software.php,实现类文件Wechat.php和Oicq.php。

Software.php

<?php
namespace App\Interfaces;

interface Software{
	public function use();
}
?>

Wechat.php

<?php
namespace App\Test;
use App\Interfaces\Software;

class Wechat implements Software{
  public function use(){
    echo "I use Weixin";
  }
}
?>

Oicq.php

<?php
namespace App\Test;
use App\Interfaces\Software;

class Oicq implements Software{
  public function use(){
    echo "I use QQ";
  }
}
?>

创建服务提供者SoftwareServiceProvider并注册(config/app.php),然后绑定上下文如下

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class SoftwareServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //
    }
    public function register()
    {
        $this->app->when('App\Http\Controllers\WechatController')
                  ->needs('App\Interfaces\Software')
                  ->give('App\Test\Wechat');
        $this->app->when('App\Http\Controllers\OicqController')
                  ->needs('App\Interfaces\Software')
                  ->give('App\Test\Oicq');
    }
}

创建控制器WechatController和OicqController并编辑文件如下

WechatController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Interfaces\Software;

class WechatController extends Controller
{
    public function __construct(Software $soft){
    	$this->soft = $soft;
    }
    public function index(){
    	$this->soft->use();
    }
}

OicqController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Interfaces\Software;

class OicqController extends Controller
{
    public function __construct(Software $soft){
    	$this->soft = $soft;
    }
    public function index(){
    	$this->soft->use();
    }
}

注册路由

Route::get('/weixin','WechatController@index');
Route::get('/qq','OicqController@index');

最后访问localhost/your projectName/public/weixin会输出"I use Weixin";而localhost/your projectName/public/qq则会输出"I use QQ"。

 


Huas Leung
程序员/web开发者
Light up my life!

分享到: