提及/kebab

围绕 PHP 标准库的功能,专注于安全性和可测试性的包装器

1.4.2 2023-11-28 19:07 UTC

This package is auto-updated.

Last update: 2024-08-28 20:55:23 UTC


README

Kebab 是围绕 PHP 标准库的一些功能的集合,提供了安全包装和测试工具。它非常有用,以至于我们希望将其用于所有地方,包括我们的个人项目。因此,我们无法将其保留给自己。

Build Status Latest Version MIT License PHPStan Enabled

安装

composer require mention/kebab

目标

本包的目标是

  • 提供默认安全(通过在出错时抛出异常)的包装器
  • 提供具有更好 API 的包装器
  • 让静态分析器满意
  • 让测试更容易

PHP 标准库中的一些函数具有臭名昭著的糟糕 API。例如,json_decode():如果出错,或 JSON 字符串是 NULL 文字面量,则返回 null。该包提供了合理的包装器,可以自动检查错误并在失败时抛出异常。该包还提供了一些不太损坏的函数(如 file_get_contents())的包装器,因为错误时抛出异常是有用的。

包装器不仅检查错误,还尝试改进 API。例如,json_decode() 有两种变体:JsonUtils::decodeArray()JsonUtils::decodeObject()

所有包装器都有静态、单返回类型,以使静态分析器满意。例如,有 Clock::microtimeFloat()Clock::microtimeString() 而不是返回两种可能类型的单个函数。

最后,该包提供了一些工具以使测试更容易,例如允许在测试期间伪造系统时间的 Clock 类。

概述

时钟

时钟以允许在测试期间返回伪造时间(以及系统时间)的方式包装了 time()microtime()sleep()usleep()

示例

<?php

Clock::enableMocking(946681200); // 946681200 can be any arbitrary timestamp

Clock::time(); // int(946681200)
Clock::microtimeFloat(); // float(946681200.0)

Clock::usleep(5500000); // returns immediately (no actual sleep)
Clock::microtimeFloat(); // float(946681205.5) : clock has advanced by 5500000 micro seconds

Clock::disableMocking();

在调用 enableMocking() 之前,Clock 方法返回真实系统时间,并且睡眠函数实际上暂停程序,如预期。调用 enableMocking() 后,将返回伪造的时间,并且睡眠函数将推进伪造时间而不实际暂停程序。

这主要受到 Symfony 的 ClockMock 类的启发。

Date\DateUtils

DateUtils 提供了一些日期创建方法。该类使用 Clock 来获取系统时间,因此其结果可以在测试中受控和预测。

<?php

DateUtils::now(); // Same as new \DateTimeImmutable();

DateUtils::nowMutable(); // Same as new \DateTime();

DateUtils::nowTz($timezone); // Same as new \DateTimeImmutable('now', $timezone);

DateUtils::fromString($dateString); // Same as new \DateTimeImmutable($dateString);

DateUtils::fromString($dateString, $format); // Same as \DateTimeImmutable::createFromFormat($format, $dateString);

DateUtils::fromStringMutable($dateString); // Same as new \DateTime($dateString);

DateUtils::fromStringMutable($dateString, $format); // Same as \DateTime::createFromFormat($format, $dateString);

DateUtils::fromStringTz($dateString, $timezone); // Same as new \DateTimeImmutable($dateString, $timezone);

DateUtils::fromStringTz($dateString, $timezone, $format); // Same as \DateTimeImmutable::createFromFormat($format, $dateString, $timezone);

DateUtils::fromTimestamp($timestamp); // Same as \DateTimeImmutable::createFromFormat("|U", (string) $timestamp);

DateUtils::fromTimestamp($timestamp, $micro); // Same as \DateTimeImmutable::createFromFormat("U u", "$timestamp $micro");

File\FileUtils

此类提供了一些在失败时抛出异常的文件函数。

<?php

FileUtils::read($file); // Reads file $file, throws exception on failure

FileUtils::open($file, $mode); // Opens file $file, throws exception on failure

Json\JsonUtils

此类提供了一些在失败时抛出异常(无效参数、无效正则表达式等)的 JSON 函数,并带有略微改进的接口。

<?php

JsonUtils::encode($value); // json_encode, with exceptions on failure

JsonUtils::encodePretty($value); // returns pretty-printed JSON, throw exceptions on failure

JsonUtils::prettify($json); // prettifies a JSON string

JsonUtils::decodeObject($json); // decodes a JSON string, use stdClass to represent JSON objects (same as json_decode($value, false))

JsonUtils::decodeArray($json); // decodes a JSON string, use arrays to represent JSON objects (same as json_decode($value, true))

Log\LogUtils

可以使用 LogUtils::truncate() 方法来防止记录过长的值。默认情况下,它将给定的字符串截断到 255 字节。可以通过将 NO_TRUNCATE_LOG 环境变量设置为 1 来禁用截断。

<?php

LogUtils::truncate($veryLargeString); // Truncates to 255 characters by default. 

Pcre\PcreUtils

此类提供了具有更好 API 的 PCRE/preg 包装器

  • 在出错时抛出异常(无效参数、无效正则表达式等)
  • 返回静态,单类型

字符串替换

<?php

// Only accept string as subject and returns a string
PcreUtils::replace('/bar/', 'foo', 'foobarbaz'); 

// Only accept array as subject and returns an array
PcreUtils::replaceMultiple('/foo/', 'bar', ['foo', 'foo']); 

// Only accept string as subject and returns a string
PcreUtils::replaceArray(['/foo/' => 'bar'], 'foo'); 

// Only accept array as subject and returns an array
PcreUtils::replaceArrayMultiple(['/foo/' => 'bar'], ['foo', 'foo']); 

回调替换

<?php

// Only accept string as subject and returns a string
PcreUtils::replaceCallback('/\d/', $callback, '123'); 

// Only accept array as subject and returns an array
PcreUtils::replaceCallbackMultiple('/\d/', $callback, ['1', '2']); 

// Only accept string as subject and returns a string
PcreUtils::replaceCallbackArray($patternsAndCallbacks, '123');

// Only accept array as subject and returns an array
PcreUtils::replaceCallbackArrayMultiple($patternsAndCallbacks, ['1', '2']);

过滤器替换

<?php

// Only accept string as subject and returns a string
PcreUtils::filter('/bar/', 'foo', 'foobarbaz');

// Only accept array as subject and returns an array
PcreUtils::filterMultiple('/foo/', 'bar', ['foo', 'foo']);

// Only accept string as subject and returns a string
PcreUtils::filterArray(['/foo/' => 'bar'], 'foo');

// Only accept array as subject and returns an array
PcreUtils::filterArrayMultiple(['/foo/' => 'bar'], ['foo', 'foo']);

其他方法

<?php

// Always returns a boolean or throws on error
PcreUtils::match('/bar/', 'foobarbaz');

// Returns number of hits that matched or throws on error
PcreUtils::matchAll('/foo/', 'foobarbaz');

// Split string by a regular expression
PcreUtils::split('/\d/', 'foo1bar2baz');

// Quote regular expression characters
PcreUtils::quote('foo$bar');

作者

提及 团队和贡献者