cscfa_tool_division / csr3-dto
CSCFA csr 分区 PHP 实现
Requires (Dev)
- phpmd/phpmd: ^2.6@stable
- phpunit/phpunit: ^6.0@stable
- sami/sami: ^4.0@stable
- sebastian/phpcpd: ^3.0@stable
- squizlabs/php_codesniffer: >=2.8@stable
This package is not auto-updated.
Last update: 2024-09-18 20:07:20 UTC
README
本项目是 csr3 规范 的 PHP 实现。
数据传输对象是当数据必须通过应用中的多个元素时使用的元素。DTO 作为容器。
基本用法
CSR3 项目定义了一个通用的 DTO 对象
use CSDT\CSR3\CSR3GenericDTO; $dto = new CSR3GenericDTO();
Csr3GenericDTO 是一个实现 CSR3DTOInterface 的实例。此接口扩展了 ArrayAccess 和 Iterator 接口。
ArrayAccess 实现
通过使用 ArrayAccess 接口,CSR3GenericDTO 允许像数组一样使用。
// ... if (isset($user) && !empty($user)) { $dto['user_instance'] = $user; } // ... if (isset($dto['user_instance']) { $user = $dto['user_instance']; if ($user->isLocked()) { unset($dto['user_instance']); } }
Iterator 实现
通过使用 Iterator 接口,CSR3GenericDTO 允许像迭代器一样使用。
$dto['hell'] = 'o w'; $dto['or'] = 'ld'; foreach ($dto as $key => $value) { echo $key . $value; } // Output : "hello world"
Csr3DTOInterface 实现
Csr3DTOInterface 是 CSR3 DTO 的默认访问功能。它允许设置和获取属性。
$dto->setAttributes(['a' => 1, 'b' => 2]); var_dump($dto->getAttributes()); /* array(2) { ["a"]=> int(1) ["b"]=> int(2) } */ $dto->setAttribute('a', 3); var_dump($dto->getAttribute('b')); // int(2) var_dump($dto->getAttributes()); /* array(2) { ["a"]=> int(3) ["b"]=> int(2) } */
添加自定义方法
Csr3GenericDTO 是一个 final 类,不能直接扩展。但它扩展了一个抽象类:AbstractCSR3DTO,该类定义了实现 CSR3DTOInterface 所需的所有逻辑。
想象你想要创建一个存储特定上下文并可以通过方法调用来检索的 DTO。你可以创建一个如下所示的 DTO 类
use CSDT\CSR3\Abstracts\AbstractCSR3DTO; class ContextDTO extends AbstractCSR3DTO { public function setContext($context) { $this['context'] = $context; } public function getContext($context) { return $this['context'] ?? []; } }
使用自定义类属性
如自定义方法添加所示,你必须创建自己的类
use CSDT\CSR3\Abstracts\AbstractCSR3DTO; class ContextDTO extends AbstractCSR3DTO { protected $context = []; public function setContext($context) { $this->context = $context; } public function getContext($context) { return $this->context; } }
使用此自定义类时,你会遇到的问题是无法处理 $context
属性。为了避免这个问题,你需要扩展 AbstractCSR3PropertyDTO
而不是 AbstractCSR3DTO
。
use CSDT\CSR3\Abstracts\AbstractCSR3DTO; class ContextDTO extends AbstractCSR3PropertyDTO { protected $context = []; public function setContext($context) { $this->['context'] = $context; } public function getContext($context) { return $this['context']; } }
💢 注意 AbstractCSR3PropertyDTO 不能处理私有属性,这是 PHP 的 OOP 结构。
使用私有属性
为了能够管理 DTO 的私有属性,你必须覆盖 AbstractCSR3PropertyDTO
的三个方法
use CSDT\CSR3\Abstracts\AbstractCSR3DTO; class ContextDTO extends AbstractCSR3PropertyDTO { private $context = []; protected function getProperties() : array { return array_merge( parent::getProperties(), ['context'] ); } protected function setProperty(string $propertyName, $propertyValue) { if ($propertyName == 'context') { $this->setContext($propertyValue); return $this; } return parent::setProperty($propertyName, $propertyValue); } protected function getProperty(string $propertyName) { if (propertyName == 'context') { return $this->getContext(); } return parent::getProperty($propertyName); } public function setContext($context) { $this->context = $context; } public function getContext($context) { return $this->context; } }
❕ 这三个方法协同工作,不能单独覆盖,以启用完全的私有属性支持。
内部关键字及其覆盖方法
AbstractCSR3DTO
和 AbstractCSR3PropertyDTO
定义了 attributes 和 traversingPosition 属性。第一个存储 DTO 的属性,第二个存储内部迭代指针。可以通过设置存储要使用的属性名称的 attributeContainer 和 positionContainer 属性来覆盖它们,而不是使用两个初始属性。
💢 attributeContainer 和 positionContainer 属性是关键字,不能被覆盖。
在不使用 CSR3 接口的情况下使用逻辑
此实现的完整逻辑封装在 CSR3DTOTrait
和 CSR3PropertyDTOTrait
中。
use CSDT\CSR3\Traits\CSR3DTOTrait; class AttributeDTO { use CSR3DTOTrait; private $attributes = []; private $traversingPosition = 0; }
use CSDT\CSR3\Traits\CSR3DTOPropertyTrait; class ContextDTO { use CSR3DTOPropertyTrait; private $attributes = []; private $traversingPosition = 0; private $context = []; protected function getProperties() : array { return array_merge( parent::getProperties(), ['context'] ); } protected function setProperty(string $propertyName, $propertyValue) { if ($propertyName == 'context') { $this->setContext($propertyValue); return $this; } return parent::setProperty($propertyName, $propertyValue); } protected function getProperty(string $propertyName) { if (propertyName == 'context') { return $this->getContext(); } return parent::getProperty($propertyName); } public function setContext($context) { $this->context = $context; } public function getContext($context) { return $this->context; } }