divengine / laze
Div PHP Laze
Requires
- php: >=8.0.0
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2024-09-09 10:14:09 UTC
README
laze 是一个用于定义 惰性求值 的 PHP 库。值被设置为闭包,只有在首次访问时才会实现,确保高效且可控的初始化。一旦闭包函数被评估,它就变为不可变的,不能重新定义为不同的值。然而,它可以在访问之前重新定义为闭包,在访问时转换为非闭包值。
laze 可能是一个表示放松或懒惰的英文单词,但在这种情况下,它实际上是一个由 Lazy Evaluation 衍生的缩写。这指的是一种编程技术,其中表达式的评估被延迟到其值需要时。使用 laze,一旦值被评估,它就变成一个不可变值。换句话说,一个虽然延迟评估,但在初始评估后不能修改的值。因此,laze 封装了导致最终值的延迟评估概念,将灵活性和鲁棒性结合到一个概念中。
安装
您可以使用 Composer 安装 laze
composer require divengine/laze
用法
定义一个惰性常量
要定义一个惰性常量,使用 laze::define
方法。值必须提供为闭包。
use divengine\laze; // Define a lazy constant laze::define('MY_CONSTANT', fn() => computeExpensiveValue());
读取惰性常量
要访问值,使用 Laze::read 方法。闭包将在第一次访问时被评估,并将结果存储为常量的值。
$value = laze::read('MY_CONSTANT');
基本示例
use divengine\laze; // Define a lazy constant. Simulate an expensive computation laze::define('MY_CONSTANT', fn() => return rand(1, 100)); // First access, the closure is evaluated $value = laze::read('MY_CONSTANT'); echo $value; // Outputs the evaluated value // Subsequent access returns the stored value $value = laze::read('MY_CONSTANT'); echo $value; // Outputs the same value as before
综合示例
此示例以简洁的方式概述了 Laze 的全部功能,适合 README 文件,展示了它在实际场景中的应用。
- 约束:确保 APP_CONFIG 实现 Configurable 接口。
- 返回闭包的闭包:MY_FUNCTION 键持有一个返回另一个闭包的闭包
- 具有对象实例的惰性值:APP_CONFIG 存储了一个 AppConfig 实例,该实例通过约束进行验证。
- 重复定义和读取:FINAL_MESSAGE 从 APP_CONFIG 和 MY_FUNCTION 读取,结合它们的值。
- PHPUnit 测试:演示了如何使用模拟对象重新定义 APP_CONFIG 进行测试。
interface Configurable { public function configure(array $settings): void; } class AppConfig implements Configurable { private array $settings; public function configure(array $settings): void { $this->settings = $settings; } public function getSetting(string $key) { return $this->settings[$key] ?? null; } } // 1. Add a constraint to ensure a value implements the Configurable interface laze::constraint( name: 'Must implement Configurable interface', fn($key, $value) => $key == 'APP_CONFIG' ? $value instanceof Configurable : true ); // 2. Define a lazy value that returns a closure laze::define('MY_FUNCTION', function() { return function() { return "Function Result"; }; }); // 3. Define a lazy value with an object instance laze::define('APP_CONFIG', function() { $config = new AppConfig(); $config->configure([ 'timezone' => 'UTC', 'locale' => 'en_US' ]); return $config; }); // 4. Reuse define and read within each other laze::define('FINAL_MESSAGE', function() { $config = laze::read('APP_CONFIG'); $timezone = $config->getSetting('timezone'); return laze::read('MY_FUNCTION')() . " in timezone $timezone"; }); $finalMessage = laze::read('FINAL_MESSAGE'); echo $finalMessage; // Outputs: "Function Result in timezone UTC" // 5. PHPUnit Test - Redefining a value class LazeTest extends \PHPUnit\Framework\TestCase { public function testAppConfigCanBeMocked() { // mock function laze::define('MY_FUNCTION', function() { return function() { return "Mocked Result"; }; }); // mock object laze::define('APP_CONFIG', function() { $mockConfig = $this->createMock(Configurable::class); $mockConfig->method('getSetting')->willReturn('mocked_timezone'); return $mockConfig; }); $message = laze::read('FINAL_MESSAGE'); $this->assertEquals("Mocked Result in timezone mocked_timezone", $message); } }
如何在测试期间重置 Laze
如果您需要在测试期间重置 Laze,您有两个选择
-
使用反射重置 Laze 的内部状态。
class LazeTest extends \PHPUnit\Framework\TestCase { public $lazeBackup; public function setUp(): void { parent::setUp(); $reflection = new ReflectionClass(laze::class); $property = $reflection->getProperty('store'); $property->setAccessible(true); $this->lazeBackup = $property->getValue(); } public function tearDown(): void { $reflection = new ReflectionClass(laze::class); $property = $reflection->getProperty('store'); $property->setAccessible(true); $property->setValue($this->lazeBackup); parent::tearDown(); } }
-
如果您使用
phpunit
,则使用带有参数--process-isolation
的它来在单独的进程中运行每个测试。vendor/bin/phpunit --process-isolation
此库的用途
-
惰性求值:通过延迟值评估直到需要时,优化资源使用,提高性能和加载时间。
-
不可变性:确保值在评估后保持不变,在并发环境和函数式编程中非常有用。
-
依赖注入:支持依赖的惰性初始化,提高模块化和测试(例如,模拟服务)。
-
配置管理:管理特定于环境或条件的配置,仅在需要时评估。
-
缓存:实现延迟缓存,仅在需要时存储结果,并支持具有约束的多级缓存。
-
事件驱动编程:便于延迟事件处理,仅在特定条件或请求下触发操作。
-
测试:在单元测试中使用约束验证值,并使用惰性加载的依赖模拟复杂环境。
-
安全:在使用值之前强制执行数据验证和安全约束,降低风险。
-
声明式编程:支持按需评估的声明式配置。
-
领域特定语言(DSLs):使用声明式值定义构建DSLs,在特定上下文中执行。
-
CI/CD:定义CI/CD管道的动态配置或脚本,根据环境状态条件评估。
许可证
本项目受GNU通用公共许可证(GPL)许可。请参阅LICENSE文件以获取详细信息。
贡献
欢迎贡献!请随时提交拉取请求或开启一个问题。
关于
laze
由Divengine软件解决方案开发和维护。如果您觉得这个库很有用,请考虑给它点星并与其他人分享。