evelikto / di
最灵活的(ευέλικτος!) PHP 依赖注入容器
1.0.0
2018-12-15 01:13 UTC
Requires
- php: >=7.0.0
Requires (Dev)
- phpunit/phpunit: ^7
This package is auto-updated.
Last update: 2024-09-15 14:17:20 UTC
README
evelikto-di
世界上最具灵活性的(ευέλικτος!) PHP 依赖注入容器。只需使用您需要的功能,无需运行时配置开销。
动机
尽管GitHub上有成百上千个PHP DI库,但没有任何一个提供零运行时成本容器配置。或者配置,可以被轻松分解成更小的块,或者可以被扩展用于不同的环境。Evelikto-DI的目标是结合性能、小巧的体积、最大灵活性以及易于使用的容器配置。
安装
Evelikto通过Composer/Packagist提供
"require": { "evelikto/di": "^1.0" }
或者通过Composer CLI
composer require evelikto/di ^1.0 --prefer-distr
使用方法
类 \evelikto\di\AppContext 是DI容器的默认实现。基本用法是用构造函数实例化容器,传递应用程序配置给构造函数,然后将容器传递给框架,或者使用容器初始化框架。
$appContext = new \evelikto\di\AppContext(new AppConfig());
配置类必须遵循一些约定:1. 类中的每个方法都被视为一个工厂方法。2. 类中的每个常量都被视为一个配置值。3. 一个常量也可以代表一个接口名称别名(等于实现的具体类)。4. 一个方法也可以将一个接口映射到工厂方法。
// Every class can be a configuration class, there are no base classes class AppConfig { // every constant in this class is considered to be a config value // these values are injectable by name: use $MY_APP_CONFIG_VALUE as argument const MY_APP_CONFIG_VALUE = 'config value'; const ANOTHER_CONFIG_VALUE = 1.42; // this an alias for the interface \evelikto\mvc\Router // pointing to the concrete class \evelikto\mvc\router\ViewRouter // AppContext can now autowire ViewRouter if asked for a Router interface // function xxx(Router $router) will be injected with a ViewRouter instance. const EVELIKTO_MVC_ROUTER = '\\evelikto\\mvc\\router\\ViewRouter'; // every method is considered to be a factory method // $pdo argument will be autowired by the container // container will register the new dependency // as 'databaseService' & '\app\core\DatabaseService' public function databaseService(\PDO $pdo) { $db = new \app\core\DatabaseService($pdo); // do some additional initialization return $db; } // Arrays can also be config values const MVC_VIEW_ROUTER_MAPPINGS = [ 'GET /' => '/index.php', 'GET /about' => '/about/index.php', ]; public function eveliktoMvcRouter($MVC_VIEW_ROUTER_MAPPINGS) { return new ViewRouter($MVC_VIEW_ROUTER_MAPPINGS); } // this is another possibility to initialize interfaces // full interface name will be converted to camel-case method name // \evelikto\mvc\Router translates to public function eveliktoMvcRouter() { // inside the config file ask for config values via static:: return new ViewRouter(static::MVC_VIEW_ROUTER_MAPPINGS); } } // in your index.php: $appContext = new \evelikto\di\AppContext(new AppConfig());
这种方法的优点是配置的完全自由。它还允许您通过原生PHP方式以自然的方式定义多个配置。最好的消息是——您在CPU周期方面根本不需要为此付费!
// Extending base config class allows you to redefine values and factories // for different environments. class AppConfig { const PDO_HOSTNAME; const PDO_DATABASE; const PDO_USERNAME; const PDO_PASSWORD; /** @return \PDO */ public function pdo() { $hostname = static::PDO_HOSTNAME; $database = static::PDO_DATABASE; $username = static::PDO_USERNAME; $password = static::PDO_PASSWORD; return new \PDO("mysql:host=$hostname;dbname=$database", $username, $password); } } class LocalConfig extends AppConfig { const PDO_HOSTNAME = 'local_host'; const PDO_DATABASE = 'local_db'; const PDO_USERNAME = 'local_dbo'; const PDO_PASSWORD = 'local_pwd'; } class CloudConfig extends AppConfig { const PDO_HOSTNAME = 'cloud_host'; const PDO_DATABASE = 'cloud_db'; const PDO_USERNAME = 'cloud_dbo'; const PDO_PASSWORD = 'cloud_pwd'; } // in your index.php: $config = IS_CLOUD ? new CloudConfig : new LocalConfig; $appContext = new \evelikto\di\AppContext($config); // you may also put a number of config values into an interface interface CloudDatabaseConsts { const PDO_HOSTNAME = 'cloud_host'; const PDO_DATABASE = 'cloud_db'; const PDO_USERNAME = 'cloud_dbo'; const PDO_PASSWORD = 'cloud_pwd'; } class CloudConfig extends AppConfig implements CloudDatabaseConsts { // other cloud values and factories } // or just put parts of your configuration into a trait trait MvcConfig { public function eveliktoMvcRouter() { return new ViewRouter([ 'GET /' => '/index.php', 'GET /about' => '/about/index.php', ]); } } trait DatabaseConfig { // yes, you can autowire config values! public function pdo($PDO_CONNECTION, $PDO_USERNAME, $PDO_PASSWORD) { return new \PDO($PDO_CONNECTION, $PDO_USERNAME, $PDO_PASSWORD); } } // combine the traits in your config class to keep it clean and maintainable. class AppConfig { uses MvcConfig, DatabaseConfig; }
结论:“类作为配置”约定非常强大、快速且易于使用。