gravatalonga/container 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

gravatalonga/container

最新稳定版本:1.8.4

Composer 安装命令:

composer require gravatalonga/container

包简介

Implementation of PSR-11 Container, it is lightweight yet powerful. Feature such as Lazy Factory, Factory, Optinal Share of Services, Array Access and other it can be very versatile.

README 文档

README

Container

Container

Latest Version on Packagist Software License Total Downloads Coverage Status Quality Score Type coverage PHP Unit Say Thanks

Container implementation which follow PSR-11.

Requirements

PHP VERSION Container Version
8.0 < <= 1.6 1.0
>= 8.0 >= 1.7 1.0
>= 8.0 >= 1.8 2.0

Installation

composer require gravatalonga/container

Usage

Basic Usage

use Gravatalonga\Container\Container;

$container = new Container();
$container->set('random', function() {
    return rand(0, 1000);
});

$container->share('uniqueSeed', function() {
    return rand(0, 1000);
});

// create alias 'sessionId'  
$container->alias('uniqueSeed', 'sessionId');

echo $container->get('random'); // get random number each time you call this.

if ($container->has('uniqueSeed'))  {
    echo $container->get('uniqueSeed'); // get same random number.  
}

When creating a new instance of Container, you can pass on first argument configurations or entries to be already bonded into container.

use Gravatalonga\Container\Container;

new Container([
    'settings' => ['my-settings'], 
    FooBar::class => function (\Psr\Container\ContainerInterface $c) { 
        return new FooBar();
    }
]);

Using Service Provider

use Gravatalonga\Container\Container;


$container = new Container();
$container->set(RedisClass::class, function () {
    return new RedisClass();
});

// then you can use...
$cache = $container->get('Cache');

When using set, factory or share with Closure and if you want to get Container it's self, you can pass type hint of ContainerInterface as argument.

use Gravatalonga\Container\Container;
use Psr\Container\ContainerInterface;

$container = new Container([
    'server' => 'localhost',
    'username' => 'root'
]);

$container->set('Cache', function (ContainerInterface $container) {
    // some where you have binding this RedisClass into container... 
    return $container->make(RedisClass::class, [
        'server' => $container->get('server'), 
        'username' => $container->get('username')
    ]);
});

// set is a method alias of factory
$container->factory('CacheManager', function() {
    return new CacheManager();
});

// then you can use...
$cache = $container->get('Cache');

Using Array like access

use Gravatalonga\Container\Container;

$container = new Container();  
$container[FooBar::class] = function(ContainerInterface $container) {
    return new FooBar($container->get('settings'));
};

if (isset($container[FooBar::class])) {
    echo $container[FooBar::class]->helloWorld();
}

Alias

Alias like the name show, it to make a possibility to make an alias from one entry to another. It will throw an exception if can't be found.

use Gravatalonga\Container\Container;

$container = new Container();  
$container->set('settings', ['driver' => 'default']);
$container->set(FooBar::class, function($settings) {
    return new FooBar($settings);
});

$container->alias(FooBar::class, 'foo.bar');

$foobar = $container->get('foo.bar');

Callable as alternative

use Gravatalonga\Container\Container;

$class = new class
{
    public function get(): int
    {
        return mt_rand(0, 100);
    }
};

$container = new Container();  
$container->factory('random', [$class, 'get']);

$foobar = $container->get('random'); // it will get random int

Extend

In order implementation to be ease for other services providers extend method was created.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    public $name;

    public function __construct($name = 'Jonathan Fontes')
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class, function(ContainerInterface $container) {
    return new Test;
});

$container->extend(Test::class, function(ContainerInterface $container, $test) {
    return new Test($test->name.' - The greatest!');
});

echo $container->get(Test::class); // It will print 'Jonathan Fontes - The greatest!';  

Advance usage

Container is capable to resolve class who isn't bounded, it will resolve dependencies from __construct type-hint/built-in which is bounded. Read example code below:

Information: built-in is type which is built in on PHP, which is string, int, boolean, etc. Type Hint is type which is created by user land, such as, when creating a class you are creating a new type.

Using Type Hint Class

use Gravatalonga\Container\Container;

class FooBar {}

class Test
{
    public function __construct(FooBar $foobar)
    {
        $this->foobar = $foobar;
    }
}

$container = new Container(); 
$container->set(FooBar::class, function () {
    return new FooBar();
});

$container->get(Test::class); // FooBar it will inject into Test class.  

Note: We only support resolving auto wiring argument on construction if they are bounded into container. Otherwise it will throw an exception if can't find entry.

Using Built in type

use Gravatalonga\Container\Container;
class Test
{
    public function __construct(string $name)
    {
        $this->name = $name;
    }
}

$container = new Container(); 
$container->set('name', 'my-var');

$container->get(Test::class); // my-var it will inject into Test class.  

If argument accept nullable if can't be resolve it will pass default value which in this case is null.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    private $name;

    public function __construct(string $name = null)
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class); // null it will inject into Test class.  

In also attempt to resolve auto wiring of construction by its default value, it will check default value of __construct and it will pass that default value.

First case, if value is a simple built-in type value.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    private $name;

    public function __construct($name = 'Jonathan Fontes')
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class); // 'Jonathan Fontes' it will pass into container...

Tip

It's well-known that using singleton pattern, it's an anti-pattern. But small feature can't hurt you

So, you can use:


$container = new Container();

// ... 

Container::setInstance($container);

Then you can get instance of container,

$container = Container::getInstance();

Tips: The container can detected circular dependencies.

Change log

Please see CHANGELOG for more information on what has changed recently.

Testing

composer grumphp

Contributing

Please see CONTRIBUTING and CODE_OF_CONDUCT for details.

Security

If you discover any security related issues, please email jonathan.alexey16[at]gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 2.46k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 5
  • 点击次数: 0
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 5
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-04-11