sci / assert
可扩展的轻量级断言库。
1.0.2
2016-02-03 16:27 UTC
Requires
- php: >=5.4.0
Requires (Dev)
- humbug/humbug: ~1.0@dev
- phpunit/phpunit: ^4.7
- squizlabs/php_codesniffer: ^2.3
This package is auto-updated.
Last update: 2024-09-09 00:48:30 UTC
README
PHP库,灵感主要来自 beberlei/assert。
目的是一个轻量级的PHP库,主要用于验证方法参数。库的API类似于领域特定语言。
安装
使用 composer
composer require sci/assert dev-master
动机
例如,PHP无法对类似于数组的参数进行类型提示,即数组或 \Traversable
function foobar($values) { foreach ($values as $value) { // ... } } $a = array(1, 2, 3); $b = new \ArrayIterator($a); $c = 'not that iterable'; foobar($a); // fine foobar($b); // fine, too foobar($c); // Invalid argument supplied for foreach()
忽略这一点并依赖于 @param-Annotations(《@param int[]》或《@param array|\Traversable》)是非常不好的。
显式保护会变得冗长,并且需要一个单独的单元测试来达到代码覆盖率
function foobar($values) { if (!is_array($values) && !$values instanceof \Traversable) { throw new \InvalidArgumentException(/* ... */); } // ... }
解决方案可能是这样的
use Sci\Assert\Assert; function foobar($values) { Assert::that($values)->isTraversable(); // ... }
示例
use Sci\Assert\Assert; // be it a string, matching a regular expression Assert::that($value)->isString()->machesRegExp('/[A-Z][a-z+]/'); // be it a collection of strings, matching a regular expression Assert::that($values)->all()->isString()->machesRegExp('/[A-Z][a-z+]/'); // be it a \DateTime and in year 2015 ('2015-01-01' <= $date < '2016-01-01') Assert::that($date) ->isInstanceOf('\DateTime') ->greaterThanOrEqual(new \DateTime('2015-01-01')) ->lessThan(new \DateTime('2016-01-01')); // ... or, in a different way: Assert::that($date) ->isInstanceOf('\DateTime') ->between(new \DateTime('2015-01-01 00:00:00'), new \DateTime('2015-12-31 23:59:59')); // be it a collection of \DateTime objects, each beeing in future Assert::that($dates)->all()->isInstanceOf('\DateTime')->greaterThan(new \DateTime('now')); // be it null, or a collection ... Assert::that($dates)->nullOr()->isInstanceOf('\DateTime');
扩展库
可以通过子类化来扩展 Assert 库。这里有一个例子:NumberAssert
,它向 Assert
基类添加了两个更改。首先,当使用数值时,通过 delta/tolerance 参数扩展了 Assert::equal()
基方法:NumberAssert::equal()
。其次,添加了一个素数断言:NumberAssert::prime()
。
use Sci\Assert\NumberAssert; NumberAssert::that(3.1415)->equal(M_PI, .001); NumberAssert::that(997)->prime();
或者,为了更好的可读性
use Sci\Assert\NumberAssert as Assert; Assert::that(3.1415)->equal(M_PI, .001); Assert::that(997)->prime();
完整的断言列表
use Sci\Assert\Assert; // base assertions Assert::that($value)->isString(); Assert::that($value)->isInteger(); Assert::that($value)->isNumeric(); Assert::that($value)->isScalar(); Assert::that($value)->isResource(); Assert::that($value)->isTrue(); Assert::that($value)->isTraversable(); Assert::that($value)->isInstanceOf('\DateTime'); // comparison assertions Assert::that($value)->equal($valueRepeated); Assert::that($value)->strictEqual($valueRepeated); Assert::that($value)->lessThan(10); // Assert::that($value)->lt(10); Assert::that($value)->lessThanOrEqual(10); // Assert::that($value)->lte(10); Assert::that($value)->greaterThan(10); // Assert::that($value)->gt(10); Assert::that($value)->greaterThanOrEqual(10); // Assert::that($value)->gte(10); Assert::that($value)->between(10, 20); // same as Assert::that($value)->gte(10)->lte(20); Assert::that($value)->between('aaaa', 'bbbbb'); // string assertions Assert::that($value)->hasMinLength(8); Assert::that($value)->matches('/^[A-Z][a-z]+$/'); // meta assertions Assert::that($value)->all()->isString(); Assert::that($value)->nullOr()->isString();
use Sci\Assert\StringAssert; StringAssert::that($value)->isIpAddress(); StringAssert::that($value)->isIpAddress(FILTER_FLAG_IPV4); StringAssert::that($value)->isUrl(FILTER_FLAG_QUERY_REQUIRED | FILTER_FLAG_PATH_REQUIRED); StringAssert::that($value)->isEmail(); StringAssert::that($value)->isMac();
use Sci\Assert\FileSystemAssert; FileSystemAssert::that($filename)->exists(); FileSystemAssert::that($filename)->isFile(); FileSystemAssert::that($filename)->isDir(); FileSystemAssert::that($filename)->isLink();
差异
虽然 beberlei 的流畅 API 是基于函数的(《\Assert\that()`),但 sci/assert 的 API 使用了静态方法(《Assert::that()`)。
\Assert\that(1)->integer()->min(-10)->max(10);
use Sci\Assert\Assert; Assert::that(1)->isInteger()->greaterThanOrEqual(-10)->lessThanOrEqual(10); Assert::that(1)->isInteger()->gte(-10)->lte(10);
尽管看起来是一个不重要的细节,但后一种解决方案更容易通过子类化进行扩展。请参阅这里。
许可证
此包的所有内容均受MIT 许可证的许可。