gabrielelana / precious
构建值对象的库
0.1.0
2019-10-27 17:29 UTC
Requires
- php: ~7.1
Requires (Dev)
- nikic/php-parser: ^4.1
- phpstan/phpstan: ^0.11
- phpunit/phpunit: ^8.0
Suggests
- nikic/php-parser: ^4.1
- phpstan/phpstan: ^0.11
This package is auto-updated.
Last update: 2024-09-16 18:07:48 UTC
README
构建值对象的库。
原因
- 值对象是 不可变的
- 值对象应该有一组众所周知的属性
- 如果两个值对象在结构上相等,即如果它们具有相同的属性和相同的值,则它们是相等的
在PHP中,没有原语来获取这一点,你可以做的是拥有具有私有属性、获取器的大量样板代码的对象。
用法
<?php use Precious\Precious; final class Point extends Precious { public static function from(int $x, int $y) : self { return new self(['x' => $x, 'y' => $y]); } protected function init() : array { return [ self::required('x', self::integerType()), self::required('y', self::integerType()), ]; } } $p1 = Point::from(1, 1); $p2 = Point::from(1, 1); $p3 = Point::from(2, 1); assert($p1 == $p2); assert($p1 != $p3); assert($p1->x === $p2->x); assert($p1->y === $p2->y); $p4 = $p3->set('x', 1); assert($p3 != $p4); assert(spl_object_hash($p3) !== spl_object_hash($p4)); assert($p1 != $p3); assert($p1 == $p4);
安装
composer require gabrielelana/precious
PHPStan
基于某种定义生成属性的解决方案的另一个问题是,你将失去对这些属性类型的引用(通过手动定义访问器方法,你不会失去,但你将不得不编写大量的样板代码)。
PHPStan
支持自定义扩展,可以使用这些扩展在两种解决方案之间取得最佳效果:避免样板代码并保留类型信息。
安装建议的依赖项以充分利用 Precious
。
composer require --dev phpstan/phpstan composer require --dev nikic/php-parser
如果你还安装了 phpstan/extension-installer 与
composer require phpstan/extension-installer
那么你就准备就绪了!
否则,请按照手动安装说明进行操作
如果你不想使用 phpstan/extension-installer
,将自定义规则添加到你的项目 phpstan.neon
文件中
includes:
- %currentWorkingDirectory%/vendor/gabrielelana/precious/rules.neon
parameters:
level: 7
然后,这是你应该期待的
<?php use Precious\Precious; final class Point extends Precious { public static function from(int $x, int $y) : self { return new self(['x' => $x, 'y' => $y]); } protected function init() : array { return [ self::required('x', self::integerType()), self::required('y', self::integerType()), ]; } } function doSomething() : void { $p = Point::from(1, 1); echo $p->x . PHP_EOL; echo $p->y . PHP_EOL; // Will raise: Access to an undefined property Point::$z echo $p->z . PHP_EOL; // Will raise: Property Point::$x is not writable $p->x = 2; // Will raise: Parameter #1 $s of function doSomethingWith expects string, int given doSomethingWith($p->x); } function doSomethingWith(string $s) : string { return $s; }