- Notifications
You must be signed in to change notification settings - Fork11
An easy-to-use generic DTO package for PHP.
License
PHPExpertsInc/SimpleDTO
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
SimpleDTO is a PHP Experts, Inc., Project meant to facilitate easy Data Transfer Objects.
Basically, any protected property on the DTO can be set as an array element passed in tothe __constructor and/or as a default value on the property itself.
The DTOs are immutable: Once created, they cannot be changed. Create a new object instead.
Via Composer
composer require phpexperts/simple-dto
As of version 2, youmust define class-level @property docblocks for each one of your properties.
You also must define the data type.
useCarbon\Carbon;usePHPExperts\SimpleDTO\SimpleDTO;/** * @property-read string $name * @property-read Carbon $date */class BirthdayDTOextends SimpleDTO{/** @var string */protected$name;/** @var Carbon */protected$date;}$birthdayDTO =newBirthdayDTO(['name' =>'Donald J. Trump','date' =>'1946-06-14',]);// Access as a property:echo$birthday->name;// Donald J. Trump// Properties with the data type of "Carbon" or "Carbon\Carbon"// are automagically converted to Carbon objects.echo$birthday->date->format('F jS, Y');// June 14th, 1946// Easily output as an array:$birthday->toArray();// Copy from one to another:$newDTO =newBirthdayDTO($birthdayDTO->toArray());// Copy from one to another, with new properties:$newDTO =newBirthdayDTO($birthdayDTO->toArray() + ['date' =>'2020-11-03',]);// Easily output as JSON:echojson_encode($birthdayDTO);/* Output:{ "name": "Donald J. Trump", "date": "1946-06-14T00:00:00.000000Z"}*/
But what if you aren't ready / able to dive into strict PHP data types yet?
Well, just instantiate the parent class like this:
usePHPExperts\DataTypeValidator\DataTypeValidator;usePHPExperts\DataTypeValidator\IsAFuzzyDataType;/** * @property int $daysAlive * @property float $age * @property bool $isHappy */class MyFuzzyDTOextends SimpleDTO {publicfunction__construct(array$input) {parent::__construct($input,newDataTypeValidator(newIsAFuzzyDataType()); } }$person =newMyFuzzyDTO(['daysAlive' =>'5000','age' =>'13.689','isHappy' =>1, ]);echojson_encode($person,JSON_PRETTY_PRINT);/* { "daysAlive": "5000", "age": "13.689", "isHappy": 1 } */
Sometimes, you may need to initialize one or more values of a DTO after it has been created. This is particularlycommon for stateful DTOs via multiple round-trips in certain APIs (particularly Zuora's).
To overcome the stateless nature of traditional Data Type Objects, you can use theWriteOnce
trait.
This will enable you to initialize a DTO withnull anduninitialized properties, and set themonce and only.
Also, you must set every property before you can serialize orjson_encode()
the object, send it totoArray()
, etc.
/*** @property string $name*/class CityDTOextends SimpleDTO{use WriteOnce;protectedint$population;}$cityDTO =newCityDTO(['name' =>'Dubai']);dd($cityDTO);
If you are using PHP 8.0 and above, you can have SimpleDTO ignore any particularprotected
property (PHP will treat itlike any regular protected property) using the#[IgnoreAsDTO]
Attribute:
$testDTO =newclass(['name' =>'Sofia','birthYear' =>2010])extends SimpleDTO { #[IgnoreAsDTO]protectedint$age;protectedstring$name;protectedint$birthYear;publicfunctioncalcAge():int {$this->age =date('Y') -$this->birthYear;return$this->age; }};
You can nest DTOs inside of each other.
$myDTO =newMyTestDTO(['name' =>'PHP Experts, Inc.','age' =>7.01,'year' =>2019, ]);/** * @property MyTestDTO $myDTO */$dto =newclass(['myDTO' =>$myDTO])extends NestedDTO { };/* PHPExperts\SimpleDTO\NestedDTO@anonymous { -dataTypeRules: array:1 [ "myDTO" => "?MyTestDTO" ] -data: array:1 [ "myDTO" => PHPExperts\SimpleDTO\Tests\MyTestDTO {#355 -dataTypeRules: array:3 [ "name" => "?string" "age" => "?float" "year" => "?int" ] -data: array:3 [ "name" => "PHP Experts, Inc." "age" => 7.01 "year" => 2019 ] } ] } */
PHPExperts\SimpleDTO\SimpleDTO
✔ Properties are set via the constructor
✔ Properties are accessed as public properties
✔ Constructor assigns default values of typed properties
✔ Public, private and static protected properties will be ignored
✔ Each DTO is immutable
✔ Setting any property returns an exception
✔ Concrete properties can be used to set default values
✔ Properties with the type carbon become carbon dates
✔ Can easily output to array
✔ Can easily be JSON encoded
✔ Can easily be JSON decoded
✔ Nullable properties are allowed
✔ Every property is nullable with permissive mode
✔ Can be serialized
✔ Can be unserialized
✔ Extra validation can be added
✔ Can get the internal data
✔ Can identify if it is permissive or not
✔ Can ignore protected properties with the #[IgnoreDTO] Attribute.
PHPExperts\SimpleDTO\NestedDTO
✔ Will construct nested DTOs
✔ Can construct arrays of nested DTOs
✔ Can retrieve the stored DTOs.
✔ Will convert array data into the appropriate Nested DTOs
✔ Will convert stdClasses into the appropriate Nested DTOs
✔ Nested DTOs use Loose typing
✔ Nested DTOs can be built using Typed Properties
✔ Nested DTOs with Typed Properties use Strict typing
✔ All registered Nested DTOs are required
✔ Optional, unregistered, Nested DTOs are handled gracefully
✔ Can be serialized
✔ Can be unserialized
✔ Can validate the DTO manually
✔ Can get the internal data
PHPExperts\SimpleDTO\WriteOnceTrait
✔ Can accept null values
✔ Can be serialized
✔ Will validate on serialize
✔ Will validate on to array
✔ Can write each null value once
✔ Write-Once values must validate
SimpleDTO Sad Paths
✔ Cannot initialize with a nonexisting property
✔ Accessing a nonexisting property throws an error
✔ A DTO must have class property docblocks -or- typehint for each concrete property
✔ Carbon date strings must be parsable dates
✔ Properties must match their data types
✔ Will not unserialize DTOs with invalid data
✔ Cannot overwrite a non-existing property
phpunit --testdox
Theodore R. Smiththeodore@phpexperts.pro
GPG Fingerprint: 4BF8 2613 1C34 87AC D28F 2AD8 EB24 A91D D612 5690
CEO: PHP Experts, Inc.
MIT license. Please see thelicense file for more information.
About
An easy-to-use generic DTO package for PHP.