zoukankan      html  css  js  c++  java
  • 9.Laravel5学习笔记:在laravel中注冊自己的服务到容器中

    问题描写叙述


    或许标题写的不够清楚。实际情况是,在我使用laravel的过程中。须要将自己的一个类,通过服务提供者注冊到IOC容器中,可是在实际操作过程中。出现了下面错误:

    Unresolvable dependency resolving [Parameter #0 [ <required> $name ]]

    意思就是说。我的注冊东西,不能够进行类型转换。

    我的代码中没有进行代码说明须要的类型。

    代码情况


    代码主要实现的一个功能是,对传入的字符串进行AES加密。

    本来Laravel自身是提供了的,可是因为我须要与Android、IOS进行三个平台的统一。因此仅仅能自己又一次提供一个能够在三个平台间相互转化的AES加密。

    代码大体结构是,一个 interface

    <?

    php namespace AppLibaryContractsEncryption; use IlluminateContractsEncryptionEncrypter; /** * * * @desc 扩展接口。添加了设置key的接口 * @date 2015年7月15日 */ interface EncrypterInterface extends Encrypter { /** * * 设置加密、解密的key * @param string $key */ public function setKey($key); }

    这个接口是继承自Laravel的核心接口。

    仅仅是扩展了一个方法

    一个实现类 :

    <?php
    
    namespace AppLibaryEncryption;
    
    use AppLibaryContractsEncryptionEncrypterInterface;
    use RuntimeException;
    /**
     * 
     * @desc 使用AES进行加解密
     * @date 2015年7月15日
     */
    class AesCrypt implements EncrypterInterface
    {
        protected $hex_iv = 'xxxxxxx';
    
        protected $key;
    
        public function __construct($key)
        {
            //
        }
    
        public function encrypt($str)
        {
            //
        }
    
        public function decrypt($payload)
        {
            //
        }
    
        public function setKey($key)
        {
            //
        }
    }

    这个类实现了上面的接口,然后要提供一个服务提供者。将这个服务注冊到IOC中去。
    服务提供者代码:

    <?php
    
    namespace AppLibaryEncryption;
    
    use IlluminateSupportServiceProvider;
    use AppLibaryEncryptionAesCrypt;
    
    
    class AesServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton('AppLibaryContractsEncryptionEncrypterInterface', function($app){
                $config = $app->make('config')->get('app');
    
                $key = $config['key'];
    
                return new AesCrypt($key);
            });
        }
    }

    然后在一个控制器中调用,假设。控制器名称叫做 : TestController。代码例如以下:

    public function aes(AesCrypt $aes)
    {
        $payload = $aes->encrypt('hello world!');
    
        echo $payload , '<br />';
        echo $aes->decrypt($payload);
    }

    假设此时执行。这会触发 BindingResolutionException 这个异常。报错例如以下:

    Unresolvable dependency resolving [Parameter #0 [ <required> $key ]] in class AppLibaryEncryptionAesCrypt

    提示说,我这个必须的參数$key。在进行容器绑定的时候。不知道该传入一个什么类型。

    那么要解决问题。就须要告诉IOC容器,你须要给我绑定一个什么依赖的类型进来就OK了。

    我这里明显须要的是一个字符串。所以能够通过下面两种方案解决

    方案一:更改 AesCrypt 类的构造函数

    这个错误因为是未限制构造函数须要的类型,因此,能够直接先明白它的类型。可做例如以下更改

    // 请注意,这里默认给它的构造函数设置了一个空字符串,那么在进行绑定时,就能够检查到这里须要传入一个字符串
    public function __construct($key='')
    {
        //
    }

    方案二:使用接口进行调用 (推荐方法)

    在进行測试的时候。我直接使用了实现类。事实上这是不好的,写接口的目的,本来就是为了减少依赖,减小耦合。所以有接口。干嘛不用接口呢?

    这里须要改的地方是在控制器中。

    // 请注意,这里传入的參数限制类型已经变换为接口了
    public function aes(EncrypterInterface $aes)
    {
        $payload = $aes->encrypt('hello world');
    
        echo $payload , '<br />';
        echo $aes->decrypt($payload);
    }

    思考


    尽管问题得到了解决。可是我的疑惑并未全然消除。在我使用过程中,laravel自身的加密函数 IlluminateEncryptionEncrypter 它的构造函数并未指定其类型。它构造函数例如以下:

    // 并未对$key进行赋空字符串
    public function __construct($key, $cipher = 'AES-128-CBC')
    {
        //
    }

    再使用中。也不一定非要使用接口才干够。

    全然能够直接使用这个类,也不会刚刚上面的绑定类型的错误。

    翻看了源代码,也未找到问题所在。因为如今项目时间比較紧,也仅仅能临时使用 方案二 来解决我遇到的问题了。

    假设有同学遇到过这个问题、有更好的解决方式,欢迎留言或email helei5200@126.com

    不胜感激,谢谢。!


    Laravel5专题文件夹

  • 相关阅读:
    C ------ 标准函数介绍
    socket编程 ------ 建立 TCP 服务器和客户端流程(阻塞方式)
    TCP ------ keep-alive
    ARM指令集、Thumb指令集、Thumb-2指令集
    poj万人题
    Codeforces Round #273 (Div. 2)
    bnuoj 34990(后缀数组 或 hash+二分)
    hdu4691(后缀数组)
    simpson公式求定积分(模板)
    acdream1415(dij+优先队列+桥)
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7190404.html
Copyright © 2011-2022 走看看