zfr / hydrator
Zend Framework 3 hydrator组件原型,提供更好的组件体验
Requires
- php: >=5.5
Requires (Dev)
- athletic/athletic: 0.1.7
- phpunit/phpunit: ~4.1
- squizlabs/php_codesniffer: 1.4.*
- zendframework/zend-servicemanager: ~2.2.
Suggests
- zendframework/zend-servicemanager: To use the HydratorPluginManager
This package is auto-updated.
Last update: 2024-08-29 04:12:49 UTC
README
该组件是Zend Framework 3 hydrator组件的原型,您可以现在用于新项目(以下为更多详细信息)。与原始实现相比,它提供以下功能:
- 性能大幅提升(这个新实现比当前实现快5-10倍)
- 更简洁(在ZF2生命周期的整个过程中,许多被巧妙地集成进来的功能)。
- 提供内置策略以应对常见用例(目前有
DateStrategy
以及允许嵌套hydrator的hydrator)。 - 一些接口已被修改,以提供更明确的表示(例如,查看
NamingStrategyInterface
)。 - 通过两个新的上下文对象
ExtractionContext
和HydrationContext
,更统一地处理上下文。在ZF2中,您只能在注入阶段获取注入的数组数据,现在您还可以访问注入的对象。 - 所有内置hydrator都被标记为final
在现有/新项目中使用
此库可在任何项目中使用。如果您是Zend Framework 2用户,您现在实际上可以在新项目中使用它,只需提供以下配置:
use Hydrator\HydratorPluginManager; use Hydrator\Factory\HydratorPluginManagerFactory; return [ 'service_manager' => [ 'factories' => [ HydratorPluginManager::class => HydratorPluginManagerFactory::class ] ] ];
您可以通过与ZF2 hydrator类似的方式设置hydrator,只需使用“zfr_hydrators”键而不是“hydrators”。
限制
当前实现有一些兼容层,使其与ZF2兼容。例如,此库的hydrator接口扩展了Zend\Stdlib\Hydrator\HydratorInterface
。此外,hydrator插件管理器允许您创建Hydrator\HydratorInterface
(新)和Zend\Stdlib\Hydrator\HydratorInterface
(旧)。
实际上,如果您的第三方模块或其他ZF2组件以非常简单的方式使用hydrator(使用extract
和hydrate
方法),此库可以作为即插即用组件使用,只需进行少量更改。
然而,一旦代码使用更高级的功能,如命名策略、自定义过滤器或策略,有很大可能由于接口冲突而无法使用。因此,在使用此库之前,建议您仔细测试代码。
为什么内置hydrator是final的,我应该怎么使用它们?
这实际上不是ZF3的决定,而是一个实验。我们决定将所有内置hydrator设置为final。这不是一个广为人知的PHP关键字,但基本上,这意味着您不能扩展它们。
这个选择背后的原因是性能。通过确保没有人可以扩展它们,我们可以进行更激进的优化(如缓存)。这导致性能得到显著提升,尤其是对于对象集合。
问题是如何处理过滤属性?如果您之前扩展了ZF2 ClassMethods hydrator,您已经编写了这样的代码
class UserHydrator extends ClassMethods { public function __construct() { parent::__construct(); $this->filterComposite->addFilter('password', new MethodMatchFilter('getPassword'), FilterComposite::CONDITION_AND); } }
在此配置下,"getPassword"方法永远不会被hydrator调用,因此此字段永远不会被提取。在这个原型中,您的hydrator实际上组合了一个ClassMethods hydrator。
class UserHydrator implements HydratorInterface { protected $hydrator; public function __construct() { $this->hydrator = new ClassMethods(); } public function extract($object) { $values = $this->hydrator->extract($object); unset($values['password'], $values['anotherValue']); return $values; } public function hydrate(array $data, $object) { return $this->hydrator->hydrate($data, $object); } }
虽然这更啰嗦,但背后的原因是删除值实际上是业务特定的。您可能只需要为password
值清除UserHydrator
。
此外,这使我们能够执行更多的优化。例如
- 因为像
ArraySerializableHydrator
这样的hydrator无法扩展,我们可以肯定过滤功能对这个来说毫无用处,因此它被完全移除(这使得这个hydrator比ZF2的hydrator快得多)。 - 对于ClassMethods hydrator,我们可以积极缓存很多东西,这样如果您为两个不同的对象运行相同的hydrator,第二次迭代将会快得多。这之所以可能,仅仅是因为final的存在,因为您可能有依赖于上下文的过滤函数,这会使使用如此积极的缓存变得几乎不可能。
当然,由于PHP 5.4 traits,您完全可以轻松地重新创建自己的可继承的ClassMethods hydrator(使用ProvidesNamingStrategyTrait
和ProvidesStrategiesTrait
,您可以在几分钟内完成;)。