Download the PHP package fab2s/dt0 without Composer
On this page you can find all versions of the php package fab2s/dt0. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package dt0
Short Description Dt0, a DTO PHP implementation than can both secure mutability and implement convenient ways to take control over input and output in various format
License MIT
Homepage https://github.com/fab2s/laravel-dt0
Informations about the package dt0
Dt0
Dt0
(DeeTO or DeTZerO) is a DTO (Data-Transfer-Object) PHP implementation that can both secure mutability and implement convenient ways to take control over input and output in various formats.
Any class extending Dt0
will have its public properties, including readonly
ones, hydrate-able from all formats supported: array, json string, and instances.
The logic behind the scene is compiled once per process for faster reuse (single reflexion and attribute logic compilation).
Dt0
achieves full immutability when it hydrates readonly
properties. As a best practice, all of your Dt0
's should only use public readonly
properties as part of their public interfaces.
But why another DTO package
It is clear that there are many DTO packages available already, with some really good ones. But none of them (so far) made it to handle full immutability.
Mutable DTOs, with writeable public properties
, kinda missed the purpose of providing with trust that no accidental property update occurred and the peace of mind that comes with it.
It also seems to be a good practice to promote some thinking by design when you would find yourself in the need to update a DTO in any way, instead of just allowing it in a way that just seem to be ok with the implementation.
Some could argue that no one can prevent Dt0 swapping with new instances, but since you can track object ids when it matters, you can actually achieve complete integrity, being just impossible with other solutions.
Should the need for even more insurance arise, you can easily add a public readonly property
to store a cryptographic hash based on input values to sign each of your Dt0
s and use it to make sure that nothing wrong happened.
Laravel
Laravel users may enjoy Laravel Dt0 adding proper supports for Dt0
's with Dt0 validation and model attribute casting.
Installation
Dt0
can be installed using composer:
Once done, you can start playing :
Casting
Dt0
comes with two Attributes
to implement casting: Cast
Cast
is used to define how to handle a property as a property attribute and Casts
is used to set many Cast
at once as a class attribute.
Casts can be added in two ways:
-
using the
Casts
class attribute: `` - using the
Cast
property attribute: ``
Combo of the above two are permitted as illustrated in DefaultDt0
.
In case of redundancy, priority will be first in
Casts
thenCast
. Dt0 has no opinion of the method used to define Casts. They will all perform the same as they are compiled once per process and kept ready for any reuse.
Available Casters
Dt0
comes with several CasterInterface
They are documented in Casters Documentation
Usage
Dt0
has full support out of the box without any Caster
for Enums including UnitEnum.
Dt0
is as well aware of its inheritors without any casting. You can though find some usage for Dt0Caster
when property typing cannot be specific enough (read the target Dt0
class).
Dt0
supports in
and out
casting. For example, you can cast any DateTimeInterface
or stringToTimeAble
strings to a Datetime
property and have it output in Json format in a specific format:
``
Every Caster
will also support for default values as well as input/output renaming:
``
The Cast
's renameFrom
argument can also be an array to handle multiple incoming property names for a single internal property.
``
Default values
Casts
can carry a default value, even in the absence of hard property default (being impossible on readonly properties that are not promoted).
As php does not implement the Nil
concept (never set as opposed to being null
or actually set to null
), Dt0
uses a null byte ("\0"
) as default for Caster->default
value in order to simplify usage. The alternative would be to require to set an extra boolean argument hasDefault
to then set a default or to not allow null
as an actual default value.
This implementation detail result in allowing any
value except the null byte
as a default property value from Caster
.
Should you find yourself in the rather uncommon situation where you would actually want a null byte
as a defaults property value, you would then need to either use a non readonly
property with this hard default, but this would break immutability, or to set this property as a promoted one in your constructor to preserve readonly
and thus immutability of your Dt0
.
All considered, this extra attention for a very particular case seems entirely neglectable compared to the burden of one extra argument in every other case.
What about constructors
Dt0
's can have a constructor with promoted props given they properly call their parent:
``
make
and other static factory methods vs new
When dealing with readonly
properties, there are of course some gotchas as they indeed can only be initialized once. If your Dt0
uses a constructor with public readonly
promoted properties, no Casting will be used when you create your Dt0
instance with the new
keyword as everything will be done before anything can happen.
On the other hand, using the make
method will always work as expected with the full Casting capabilities of the package as in this case, all the magic will happen before the constructor is even called.
As a conclusion, it is always best practice to create your instances using any of the static factory method (make
, from
, tryFrom
, fromArray
, fromString
and fromJson
) which in the end is no big deal considering this can achieve fully immutable DTOs and the peace of mind that comes with it.
It does not mean that you should not use public readonly
promoted properties as this is also the only way to provide with a hard default value for public readonly
properties. It's just something to keep in mind when working with this package.
Validation
Dt0
comes with full validation logic but no specific implementation. For a fully functional implementation example, see Laravel Dt0
Exceptions
Dt0
's exception all extends ContextException
and do carry contextual information that can be used in your exception logger if any.
Requirements
Dt0
is tested against php 8.1 and 8.2
Contributing
Contributions are welcome, do not hesitate to open issues and submit pull requests.
License
Dt0
is open-sourced software licensed under the MIT license.