nezamy / di
依赖注入和容器
v2.0
2020-10-02 06:00 UTC
Requires
- php: >=7.4
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- phpunit/phpunit: ^7.5 || ^8.5
README
依赖注入和容器
通过composer安装
composer require nezamy/di
然后加载composer自动加载
require __DIR__ . '/vendor/autoload.php';
用法
假设我们有一个Book
类,并且我们需要调用getName
方法。无论这个方法是否为静态。
class Book { private string $name = 'First Book'; public function getName(): string { return $this->name; } } $resolver = new Just\DI\Resolver; $resolver->resolve($resolver->prepare([Book::class, 'getName'])); //Or $resolver->resolve([new Book, 'getName']); // the both returns 'First Book'
也许你没有使用new
实例来调用Book,你应该使用第一个示例中的prepare
方法。
带有参数调用方法
现在我们有一个带有一个参数的新方法
class Book { private string $name = 'First Book'; public function getName(): string { return $this->name; } public function setName(string $name): void { $this->name = $name; } } $container = Just\DI\Container::instance(); $container->setVar('name', 'PHP'); $book = new Book(); $resolver = new Just\DI\Resolver; $resolver->resolve([$book, 'setName']); $book->getName(); // will return 'PHP'
我们没有带参数调用setName
,但是我们在上面的容器中设置了name
作为一个全局变量。解析器将在容器中查找,如果找到了与参数同名变量,则传递它,如果没有找到,则传递null。
对象类型参数 & 单例
$function = function(Book $book){ return $book->getName(); }; $container = Container::instance(); $resolver = new Resolver; $name = $resolver->resolve($function); //here $name returns 'First Book' because it's initial value $book = new Book(); $book->setName('Test Book'); // for define a singleton object $container->set(Book::class, $book); $resolver = new Resolver; $name = $resolver->resolve($function); $this->assertSame('Test Book', $name); //$name now is equal 'Test Book'
调用一个具有构造函数的类中的方法,并且构造函数需要两个参数
class User{ private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function getName(): string { return $this->name; } public function getEmail(): string { return $this->email; } } $container = Just\DI\Container::instance(); $container->setVar('name', 'Mahmoud Elnezamy'); $container->setVar('email', 'mahmoud@nezamy.com'); $resolver = new Just\DI\Resolver; $name = $resolver->resolve($resolver->prepare([User::class, 'getName'])); // name here will return 'Mahmoud Elnezamy'
魔术调用
class User{ private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function getName(): string { return $this->name; } } class Book { public function Auther(User $user){ return $user->getName(); } } $container = Just\DI\Container::instance(); $container->setVar('user', ['Mahmoud', 'email@domain.com']); $container->setMagicCall(User::class, function ($attr, $value){ return new User(...$value); }); $resolver = new Just\DI\Resolver; $book = $resolver->resolve( $resolver->prepare([Book::class, 'Auther']) ); //$book will return 'Mahmoud'
API
$container = \Just\DI\Container::instance(); $container->setVar('name', 'value'); $container->getVar('name'); $container->hasVar('name'); $container->importVars([ 'name' => 'name here', 'id' => '1' ]); $container->set('className', new stdClass()); //Maybe the new instance do some processing or load some configurations or connect with database. //and you won't to make the instance until the first use or call $container->set('className', function (){ return new stdClass(); }); $container->get('className'); $container->has('className'); // define some singleton objects $container->import([ Request::class => new Request(...), Response::class => new Response(...), DB::class => new DB('user', 'pass',...) ]); $container->setMagicCall('UserModel', function ($attr, $value){ if($attr == 'id'){ return new UserModel($value); } return null; }); $container->getMagicCall('UserModel'); $container->hasMagicCall('UserModel');