You think handling forms it’s the only way? But, is there any options?
Let’s consider how Value Object (VO) “design pattern” may help you in handling web forms and simplify your life.
Suppose we need handle HTTP request in PHP (both cases: “application/x-www-form-urlencoded” or “application/json” it’s super simple to convert parameters from both requests and use them to fill form in PHP).Usually we do something like this (here I’m going to use symfony/form
because it’s pretty straightforward, simple enough, popular and you can find it on github):
form
class:
Create form instance: $task = new Form();
Fill form with parameters from HTTP request:
$form->handleRequest($request);
And now we can deal with this form. Nothing difficult so far…But hold on… let’s answer next questions:
Answers:
$form->isValid()
Not sure. If someone missed (which is rare but technically possible): $form->handleRequest($request);
it means form contains blank initialized values, in our case $form->getName()
will return null
.
if ($form->isSubmitted() && $form->isValid()) {// ...}
Let’s handle same HTTP request:
$vo = new ValueObject($request);
And that’s it, no additional steps required. Let’s answer previous questions:
Answers:
__costruct
method. VO won’t be created if provided invalid parameters, exception will be thrown.
Yes! VO always valid and you can rely on it on any application layer, you can use it as type hint in methods, like:public function doSomething(ValueObject $vo)
and you don’t have to flood your code with redundant if
blocks (more declarative style).
You may consider that write all validation stuff in constructor might be overwhelming — I’ve used here just small simple example, with purpose to provide the main idea in a simplest way. But you may consider option to use something like kint/vo
more information you can find here.
Also you may consider exception during __construct
as flood your code with try-catch
blocks, but in real life you have to have only 1 such block for whole application (no matter how it’s big) which will catch your custom exceptions and will provide all errors into response, like in case with kint/vo
you have just catch ValueObject\Exception\ValidationException
in 1 place.
In case you don’t like to have all this stuff in Value Object’s constructor and don’t want to use new
keyword, you may consider next example:
the main idea stay the same, the only difference — is the way how you create ($vo = ValueObject::fromArray([‘namex’ => ‘bond’]);
) and use your Value Object.
Now you know how Value Object can help you to write more strict, robust, immutable code in declarative style.
Hope this article was helpful and you will use VO not only to handle HTTP requests but also to build whole interaction between your components, services, etc. in your application.