If you ever had developed in Java language, you certainly heard about Lombok which is a Java library that can generate usual methods and facilitate keeping source code clean.
Thanks to Lombok, repetitive getters, setters and such could be omitted.
And because every line of code you write is a line of code that needs to be maintained, using Lombok can help you to reduce bugs.
How does Lombok proceed to provide that wonderful feature ?
In fact, it’s simply code generation. During compile time, Lombok reads annotations and generates related code.
Therefore, compiled code will be exactly the same as if you written each method by yourself.
What a wonderful tool! I want it for my Symfony projects!
As written above, Lombok generates code during compilation. It’s possible because Java is a compiled language.
Unfortunately, PHP isn’t compiled. It’s executed as it’s written in PHP files. Lombok behavior seems to cannot be reproduced…
But thanks to PHP autoload and Symfony cache, a little trick could be done!
Say hi to Symbok :)
How does it works then ?
Symbok basically proceed an on-the-fly class generation.
In fact, when Symfony catches a request, it usually loads every PHP classes using autoload.
Thanks to the powerful
spl_autoload_register PHP method, Symbok bundle is able to access classes code before loading them and here is the trick! Then thanks to code reflection, Symbok will be able to update classes according to the specified annotations and load updated classes instead of original ones.
And which features does it provides ?
As you surely understood, Symbok generates source code for you.
Let’s suppose you wanna create a product class with id and sku properties that can be get and set.
You also want to have a method that converts the product to a readable string and you would like to be able to construct the product with initial values.
Without Symbok, you’ll have to write the code below:
Although with Symbok bundle installed, you’ll just need to write these few lines:
As you can see, the PHP file written without Symbok is 43 lines long whereas the Symbok one is only 19 lines. And the time you didn’t spent to write these repetitive methods could be spent by drinking a cup of coffee!
The previous example was a really basic one. Symbok provides some other features, such as doctrine integration which generates adders and removers for you. If you wanna discover all of these features, you may have a look at the documentation.
Runtime check… But what about performances ?
That’s a really good question, I’m glad you worry about performances ;)
Symbok process can be split into 2 main steps:
- Code generation
- Updated class loading
Each time Symfony is receiving a request, Symbok will generate the same code again and again. That’s when Symfony cache comes in! In fact, Symbok will generate updated class code and put it in Symfony cache so that the new code is just generated once. Therefore, since you haven’t cleared Symfony cache, the “Code generation” step will not be executed anymore.
What about “Updated class loading” step? Unfortunately, that step could not be bypassed… As the autoload is executed for each request, Symbok has to provide the updated class each time as well. And of course class loading time is slightly increased because of Symbok conditional loader.
Using a clean instance of Symfony Flex, 3 Symbok annotated classes and a command that get/set their respective id properties, I made a tiny performance benchmark:
- Without Symbok: ~0.143s
- With Symbok, cache generated: ~0.162s
- With Symbok, cache not generated: ~0.209s
As you can see, request is about 20ms slower because of Symbok loader.
Unfortunately, this uncompressible delay cannot not be reduced to 0. But for apps that do not require a really short response time, a delay like this isn’t significant at all.
One last thing, will IDEs be able to deal with Symbok ?
Because generated classes are located in Symfony cache, an IDE cannot know that Symbok generated methods are existing. That’s why at the end of the class compilation process, Symbok updates the original file in order to add a class doc block. The added doc block will contain several method tags that are listing and describing generated methods.
Then most of IDEs will be able to read these class doc blocks in order to provide appropriates hints.
If you are seduced by Symbok and you wanna give it a try, then just go on the official GitHub repository. You’ll find everything you need to leave endless classes alone forever.