lendable/时钟

时钟抽象

4.1.0 2024-08-21 14:52 UTC

README

Latest Stable Version License

Lendable Clock 库提供了 PHP 访问系统时间的面向对象接口。虽然 PHP 提供了直接实例化 \DateTime\DateTimeImmutable 来获取当前系统时间的方法,但这个库引入了时钟的概念,以提供对时间相关操作的更多控制和灵活性。

为什么使用时钟?

您可能会想知道为什么您需要时钟,因为您可以直接在需要时实例化 \DateTime 对象。以下是时钟抽象的好处:

  • 对时间控制:通过依赖于时钟而不是直接实例化时间对象,您可以在您的应用程序中推理和控制时间。

  • 测试灵活性:使用时钟允许您交换底层实现,使测试依赖时间代码更容易。您可以以固定值存根时间,模拟时间流逝,并观察与时钟的交互以进行更健壮的测试。

  • 依赖管理:对时钟类的明确依赖有助于管理依赖当前系统时间的组件。

  • PSR-20 兼容性:该库与 PSR-20 兼容,提供与其他库和框架的互操作性。

安装

您可以通过 Composer 安装 Lendable Clock 库。

composer require lendable/clock

时钟类型

该库提供几种时钟类型,以适应不同的用例。

SystemClock

  • 目标:运行时
  • 描述:在构造时使用固定时区委托给 PHP 以获取当前系统时间。

FixedClock

  • 目标:单元/功能测试
  • 描述:始终提供在构造时提供的特定时间戳,便于确定性测试。
$clock = new FixedClock(new \DateTimeImmutable('2024-03-01 14:19:41'));

echo $clock->now()->format('Y-m-d H:i:s'), "\n";
sleep(5);
echo $clock->now()->format('Y-m-d H:i:s'), "\n";
2024-03-01 14:19:41
2024-03-01 14:19:41

TickingMockClock

  • 目标:单元/功能测试
  • 描述:从给定的时间戳开始模拟时间,并从该点模拟时间流逝。对于测试依赖时间的功能很有用。
$clock = TickingMockClock::tickingFromCurrentTime(new \DateTimeImmutable('2024-03-01 14:19:41'));

echo $clock->now()->format('Y-m-d H:i:s.u'), "\n";
sleep(5);
echo $clock->now()->format('Y-m-d H:i:s.u'), "\n";
2024-03-01 14:19:41.000006
2024-03-01 14:19:46.005175

PersistedFixedClock

  • 目标:功能测试(例如,Behat 与 Symfony Kernel)
  • 描述:类似于 FixedClock,但可以从磁盘持久化和加载给定的时间戳。适用于您需要在测试期间重新加载上下文的情况。

使用 PersistedFixedClock::initializeWith(...) 来设置时间戳,使用 PersistedFixedClock::fromPersisted(...) 从磁盘加载持久化的值。

通过利用这些时钟类型,您可以提高依赖时间 PHP 应用程序的可靠性、可测试性和可维护性。

$clock = PersistedFixedClock::initializeWith(
    __DIR__,
    new FixedFileNameGenerator('time.json'),
    new \DateTimeImmutable('2024-03-01 14:19:41'),
);

echo $clock->now()->format('Y-m-d H:i:s.u'), "\n";

sleep(5);

$clock = PersistedFixedClock::fromPersisted(__DIR__, new FixedFileNameGenerator('time.json'));

echo $clock->now()->format('Y-m-d H:i:s.u'), "\n";
2024-03-01 14:19:41.000000
2024-03-01 14:19:41.000000