ocramius / lazy-property
一个提供对象属性惰性实例化逻辑的库
Requires
- php: ~8.1.0 || ~8.2.0
Requires (Dev)
- doctrine/coding-standard: ^10.0.0
- phpunit/phpunit: ^9.5.26
- roave/infection-static-analysis-plugin: ^1.26.0
- vimeo/psalm: ^5.0.0
- 2.6.x-dev
- 2.5.x-dev
- 2.5.0
- 2.4.x-dev
- 2.4.0
- 2.3.x-dev
- 2.3.0
- 2.2.x-dev
- 2.2.0
- 2.1.x-dev
- 2.1.0
- 2.0.x-dev
- 2.0.0
- 1.0.1
- 1.0.0
- dev-renovate/phpunit-phpunit-10.x
- dev-renovate/all-minor-patch
- dev-renovate/actions-checkout-4.x
- dev-renovate/lock-file-maintenance
- dev-renovate/doctrine-coding-standard-12.x
- dev-dependabot/composer/vimeo/psalm-4.9.1
- dev-dependabot/composer/phpunit/phpunit-9.5.8
- dev-dependabot/composer/infection/infection-0.22.0
- dev-dependabot/add-v2-config-file
This package is auto-updated.
Last update: 2023-09-19 12:15:00 UTC
README
这个小库旨在提供非常简单高效的惰性属性加载
废弃
从PHP 8.3开始,动态属性不再允许“默认情况下”使用(不再允许动态属性)。虽然仍然可以通过显式声明(使用#[\AllowDynamicProperties]
属性)来拥有动态属性,但这个软件包的方法不再被认为是安全或长期高效的。
基于这一点,该软件包已被弃用并废弃:请使用传统的PHP array
。
安装
建议的安装方法是通过 composer
composer require ocramius/lazy-property
用例
在许多需要惰性初始化私有/受保护属性的情况下,许多人编写了如下所示的类
class SomeService { protected $dependency; public function doWork() { $this->getDependency()->delegateWork(); } protected function getDependency() { return $this->dependency ?: $this->dependency = get_dependency_somehow(); } }
这是有问题的,因为实现者和子类化 SomeService
的人最终会写出
class SomethingElse extends SomeService { public function doOtherWork() { $this->dependency->doMoreWork(); } }
这只有在 SomeService#getDependency()
至少被调用一次的情况下才能工作(这在某些情况下可能是真实的),因此是bug/头痛/自杀等原因的源头。
为了避免这个问题,实现 SomeService
同时也公开其受保护 $dependency
属性的开发者可以使用 LazyProperty\LazyPropertiesTrait
来解决问题
#[\AllowDynamicProperties] class SomeService { use \LazyProperty\LazyPropertiesTrait; protected MyDependency $dependency; public function __construct() { $this->initLazyProperties(['dependency']); } public function doWork() { // look ma! no getter! $this->dependency->delegateWork(); } protected function getDependency() { return $this->dependency ?: $this->dependency = get_dependency_somehow(); } }
这样,任何对 SomeService#$dependency
的访问都会在属性尚未初始化的情况下调用 SomeService#getDependency()
。
class SomethingElse extends SomeService { public function doOtherWork() { // always works $this->dependency->doMoreWork(); } }
请注意,为了使属性惰性,必须有一个获取器。
性能说明
使用 LazyProperty\LazyPropertiesTrait
可以加速在私有/受保护范围内大量进行获取器调用的应用程序。调用 SomeService#initLazyProperties()
以及第一次属性访问时有一些轻微的开销,但应该可以忽略不计。