dev-lucid /container
Requires
- php: ^7.0
- container-interop/container-interop: ^1.1
Requires (Dev)
- phpunit/phpunit: ^5.0
README
一系列容器类,实现了即将到来的Psr-11容器接口(通过扩展,当前容器互操作接口)。其中一些类非常简单(ServerContainer仅使用$_SERVER存储/检索数据,对基础容器类没有其他更改),但也有一些相当复杂(InjectorFactoryContainer做了魔法!)。以下是一个包含7个类的图示以及它们如何相互关联/区别的简要说明。
开发/使用这些类的原因
最初,我编写这些类是为了提供一个通用的API来访问会话变量和请求变量,这些变量可以配置为指向单元测试的模拟数据。最终,它变成了一组更通用的类,可以形成使用服务定位器模式或依赖注入模式;或者两者的混合的框架的基础。
基本功能
在容器中设置/获取数据
有2个函数用于在容器中设置数据
- ->set($id, $newValue),非常直观。
- ->setValues(array $newValues)。该函数遍历数组,使用数组的索引作为键。
有8个函数用于从容器中获取数据
- ->get($id),它不会进行任何类型转换。这基于Psr-11的ContainerInterface
- ->getValues(),它返回容器中所有键/值作为关联数组。这可能在调试中很有用,但如果你的容器中有许多对象,调用print_r可能会输出大量数据。
- ->string(string $id, string $defaultValue),它首先调用strval在数据上。如果没有设置索引,将返回$defaultValue(与->get不同,它将引发错误)
- ->int($id, int $defaultValue),它首先调用intval在数据上。如果没有设置索引,将返回$defaultValue(与->get不同,它将引发错误)
- ->float($id float $defaultValue),它首先调用floatval在数据上。如果没有设置索引,将返回$defaultValue(与->get不同,它将引发错误)
- ->bool($id, bool $defaultValue),它首先调用boolval在数据上。如果没有设置索引,将返回$defaultValue(与->get不同,它将引发错误)
- ->DateTime($id, DateTime $defaultValue),它尝试将数据转换为DateTime对象。如果没有设置索引,将返回$defaultValue(与->get不同,它将引发错误)
- ->array($id, array $defaultValue, string $delimiter=','),它将数据转换为数组,并返回数组。如果索引没有包含数组,则使用分隔符(默认为逗号)将值展开。
以下是一些简单的示例
$container = new \Lucid\Container\Container(); $container->set('mystring', 'my value'); echo($container->get('mystring')); # echos with no conversion at all echo($container->string('mystring')); # calls strval() on the data first $container->set('myint', 1); echo($container->string('myint')); # calls strval() on the data first, you get back '1' echo($container->int('myint')); # calls intval on your data first, so you should get back 1 $container->set('mydate', '2010-01-01T12:00:00+00:00'); print_r($container->DateTime('mydate')); # In this case, the function will return a DateTime object. print_r # should print out something like this: # # DateTime Object #( # [date] => 2010-01-01 12:00:00.000000 # [timezone_type] => 1 # [timezone] => +00:00 #)
DateTime格式
尝试将值转换为DateTime对象时,默认情况下Container将调用\DateTime::createFromFormat并按顺序尝试3种不同的格式:\DateTime::ISO8601,\DateTime::W3C,'U'。如果这些尝试中的任何一个失败,则返回结果。你可以通过调用->setDateTimeFormats(...$newFormats)来设置要尝试的格式。请注意,这将替换要测试的格式,而不是添加。
布尔值,RequestContainer的区别
默认情况下,调用 ->bool 将仅在索引中的值严格等于 true 时返回 true。因此,'1' 将返回 false,'true' 将返回 false,等等。只有真正的布尔值 true 才会返回 true。这是按设计实现的。RequestContainer 类通过添加多个可能的 true 和 false 匹配来改变这种行为。这是为了考虑到,在许多情况下,当你尝试从请求中获取特定的布尔值时,该请求可能是由表单提交生成的,并且相关的布尔值可能被渲染为复选框。复选框不会将它们的选中状态作为布尔值 true/false 发送。相反,它们的值只是简单地存在于 $_REQUEST 中。通过使用 RequestContainer,你可以在提交带有复选框的表单时,很可能从你的容器中获取正确的值。
默认情况下,以下 RequestContainer 中的值将导致调用 ->bool 返回 true
- 'on'
- '1'
- 1
- 'yes'
- 'true'
- true
默认情况下,以下 RequestContainer 中的值将导致调用 ->bool 返回 false
- ''
- '0'
- 0
- 'no'
- 'false'
- false
- null
这些值可以使用两种方法进行替换
- ->setBoolTrueValues(...$boolTrueValues)
- ->setBoolFalseValues(...$boolFalseValues)
请注意,这些函数完全替换了可能的值,它不是累加的。
使用 __call()
Container 和 PrefixDecorator 都允许你使用 __call 来访问索引,但仅限于获取,而不是设置。例如
$app = new \Lucid\Container\Container(); $app->set('myindex', 'myvalue'); echo($app->get('myindex')); # echos 'myvalue', as expected echo($app->myindex()); # Also echos 'myvalue'
CookieContainer 设置
锁定数据
你可以使用 ->lock($id) 和 ->unlock($id) 方法锁定索引,以防止意外覆盖。例如
$config = new \Lucid\Container\Container(); $config->set('admin-username', 'admin'); $config->lock('admin-username'); $config->set('admin-username', 'user1234'); # Throws a glorious exception! $config->unlock('admin-username'); $config->set('admin-username', 'user1234'); # Will ungloriously succeed
注意:基本上没有什么可以防止索引被解锁,所以如果你真的很担心恶意活动,锁定索引并不能阻止其他代码更改值。这实际上只是为了防止你意外地覆盖某些内容。
异常类
使用了一些可捕获的异常类
- Lucid\Container\Exception\InvalidSourceException:当调用 ->setSource 时抛出,但新源不可用。一个可用的源可以是数组,或者一个同时实现了 ArrayAccess 接口和 Iterator 接口的对象。
- Lucid\Container\Exception\DateTimeParseException:当调用 ->DateTime() 时抛出,但无法使用任何已注册的格式将值转换为 DateTime 对象。
- Lucid\Container\Exception\InvalidBooleanException:当调用 ->bool() 时抛出,但无法使用任何可接受的真/假值将值转换为 bool。
- Lucid\Container\Exception\LockedIndexException:当调用 ->set() 时抛出,并且你尝试设置的索引已被 ->lock() 锁定。
- Lucid\Container\Exception\NotFoundException:当调用 ->get() 时抛出,但索引在容器中不存在。这个异常是 Psr-11 所必需的。值得注意的是,所有类型化的获取器在访问不存在的索引时都不会抛出异常,因为它们都有一个 $defaultValue 参数,将返回该参数的值。
- Lucid\Container\RequiredInterfaceException:当设置一个仅配置为接受实现一个或多个特定接口的对象的索引时抛出。值得注意的是,如果索引已设置,并且配置了接口要求,它也会抛出。
高级内容
我可能在未来添加的内容
- 建议的构造函数配置示例(monolog、swiftmailer 等)
- 将Psr-3日志记录器注入到容器类的某种方式,用于调试目的
