silvanus / structs
PHP 结构体。简单的数据传输对象。
v1.1.2
2023-04-23 07:00 UTC
Requires (Dev)
- infection/infection: ^0.18.2 || ^0.25.0
- phpunit/phpunit: ^9
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.4
README
PHP 结构体。简单的数据传输对象。
安装
通过 Composer
composer require silvanus/structs
为了使用自动加载机制,您必须在您的代码中包含 vendor/autoload.php 文件。
动机
PHP 没有真正的结构体。许多其他语言如 C++、Rust 或 Go 中都有这一特性。TypeScript 接口也与结构体相似。结构体对于具有形状的简单数据(如数据传输对象)来说是有用的。
在 PHP 中,您不能要求接口中的属性,只有方法。因此,结构体类似对象的接口并没有太大的意义。但是,如果您只使用一个具有公共属性的课程,您仍然会让客户端动态地声明新的属性。最好是保持数据的形状与结构体定义的方式相同。
这个库旨在通过提供具有合理默认值的 AbstractStruct 类来解决这个问题,以阻止动态分配新的或不正确的类属性/成员。
使用方法
声明新的结构体。
<?php namespace YourNameSpace\Structs; // Parent class. use Silvanus\Structs\AbstractStruct; class Employee extends AbstractStruct { public string $name; public string $department; public int $salary; }
使用新结构体
<?php use YourNameSpace\Structs\Employee; $employee = new Employee(); // Set up data by property. $employee->name = 'Eiríkr Blóðøx'; $employee->department = 'Norway'; $employee->salary = 954; echo $employee->name; // Eiríkr Blóðøx /** * You can only use properties set in class / struct level. */ $employee->hobbies = "Raiding"; // Throws CanNotSetPropertyException. echo $employee->hobbies // Throws CanNotGetPropertyException
您也可以在创建时直接填充结构体。
<?php use YourNameSpace\Structs\Employee; $data = array( 'name' => 'Eiríkr Blóðøx', 'department' => 'Norway', 'salary' => 954, // Setting incorrect fields here will likewise throw exceptions. ); $employee = new Employee($data);
不可变版本
您还可以使用一个不允许一旦设置就修改数据的结构体版本。
创建不可变结构体
<?php namespace YourNameSpace\Structs; // Different parent class use Silvanus\Structs\AbstractStructImmutable; class EmployeeImmutable extends AbstractStructImmutable { public string $name; public string $department; public int $salary; }
使用不可变结构体
<?php use YourNameSpace\Structs\EmployeeImmutable; $data = array( 'name' => 'Eiríkr Blóðøx', 'department' => 'Norway', 'salary' => 954, // Setting incorrect fields here will likewise throw exceptions. ); $employee = new EmployeeImmutable($data); // You can access the properties. echo $employee->name; echo $employee->department; echo $employee->salary; // ... But you cannot edit them. $employee->name = 'Eiríkr inn rauða'; // Throws CanNotSetPropertyException.
与直接使用默认类或数组相比的优势是什么
- 您可以锁定附加属性的创建。这样,您的数据保持您期望的形状。
- 您保护属性免受拼写错误的影响。
$employee->salary是有效的,但$employee->salayr会抛出异常。 - 类型提示
Employee $employee
它是如何工作的?
没有太多花哨的!只是在抽象父类上写 final __set 和 final __get 方法。它们阻止获取和创建未声明的属性。子类仍然可以添加公共属性,因为调用公共属性不会触发 __get 或 __set。
不可变版本的工作方式略有不同。它首先将给定的属性设置在公共属性中,以触发 PHP 类型验证(如果 7.4 或更高),但之后删除这些值,并将它们存储在单个数组中。 __get 自动使用此 $properties 数组来提供值。