PHP adaptation of some great concepts on which Rust was built.
Rust encourages developers to handle errors and non-values properly by design.
This leads to fewer non-logic bugs in production and the code might look cleaner as well.
The Oxidize library is written in pure PHP and has just adapted some concepts, which are also used in Rust. The method names are kept similar (snake_case to camelCase) for developers using both languages.
There are some additional wrapper methods, such as andThenContinue()
in both Result
and Option
to get rid of return statements. A new instance will then be returned automatically.
composer require vadage/oxidize
Exceptions don't have to be declared to be thrown in a method, which increases the likelihood of them not being handled.
This is where Result
s come in handy with their representation of Ok
and Error
. Calling unwrap
on Error
or unwrapError
on Ok
will lead to a ValueAccessError
.
$userResult = $this->userRpc->login($email, $password);
if ($userResult->isOk()) {
$user = $userResult->unwrap();
$this->messages->queue(sprintf('Hello %1$s.', $user->getUsername()));
}
It may not always be obvious if a method returns an object or null.
Instead of null
, an Option
can be used, which represents one of two states (Some
and None
). Calling unwrap
on None
will lead to a ValueAccessError
.
$terminationDateOption = $user->getTerminationDate();
if ($terminationDateOption->isSome()) {
$terminationDate = $terminationDateOption->unwrap();
$this->messages->queue(sprintf('Your login will be deactivated after %1$s.', $terminationDate->format(DateTimeInterface::RSS)));
}
Monads can improve the codes aesthetics by getting rid of some if
statements, variable declarations and unwrap
calls.
$this->userRpc->login($email, $password)->andThenContinue(function (User $user) {
$username = $user->getUsername();
$user->getTerminationDate()
->andThenContinue(function (DateTime $terminationDate) {
$formattedDate = $terminationDate->format(DateTimeInterface::RSS);
$this->messages->queue(sprintf('Hello %1$s. Your login will be deactivated after %2$s.', $username, $formattedDate));
})
->orElseContinue(function () {
$this->messages->queue(sprintf('Hello %1$s.', $username));
});
});