The PHP ecosystem is full of frameworks: Symfony, Laravel, Yii, Zend, Phalcon, and so many, many, many more... All of them built by professionals and supported by big communities. So why on earth would a junior developer, who has just started his first job, try his hand in building yet another one?
Well, here’s why:
When I learned PHP, the URLs I knew how to build and use looked like this: /index.php?module=user&action=show&id=123
. I had no idea, how to make them nice like this: /user/show/123
. Symfony knew though, and I could just use it.
But I was used to coding things from scratch and understanding how they work internally, I didn’t like the magic of “it just works”. I know, stupid, if I were still doing that, I’d never finish any project. At the time it did make sense, though.
I was curious if I can replicate the behaviour. I stole the .htaccess
config from Symfony, I’ve expanded my knowledge about regular expressions, and eventually, I did it! It was buggy and ugly, but it worked and it was mine, and I was so proud of it!
And then I couldn’t stop. Every time I had had to dig into Symfony’s code and had gotten overwhelmed by its complexity, I realised how simple the overall logic actually is, even though it’s overblown by trying to keep it generic and open for modification/extension. So just like I did with the router, I also rewrote from scratch the event dispatcher, the security layer, the DI container and a couple of other components, eventually ending up with a fully usable framework.
I don’t think I have access to its source code anymore, but I think it was only 10 files or so. It was crappy, didn’t comply with PSR-4, wasn’t published as a Composer package, and probably was full of bugs that I’ve never found.
It didn’t really make much sense to further develop it. Nobody’s gonna use it anyway. It’s not gonna be better than any of the frameworks that have plenty of people working on them. I’ve already learned a lot, isn’t it enough to call it a day?
But I took some criticism for the version 0.0 from people who knew better how to code, so I had to address their advice and to make Micrus better. And it turned out to be a great decision because I still had a lot more to learn.
The biggest challenge was managing dependencies. I couldn’t put all the modules like “Mailer”, “Twig”, “Social login”, “CRUD” etc. in one huge package and still call it “Micrus”. But I was developing all of them at once! I had to learn more about the internals of Composer in order to treat local directories as if they were packages, without pushing or tagging them (only later I found out about Repository of type “path” – really useful!). I had to learn how to organise the code better so that adding or removing entire modules could be as seamless as possible. I had to keep them consistent, simple, powerful, extendable. I spent hours and hours, and days and days, on figuring out their architecture...
The second biggest challenge was the forms. They’re just awful. The form abstraction layer has to move data around between the actual object that holds data, a form and it’s HTML representation. It needs to map the data both ways, it needs to validate it, it’s just a mess. At work at Rocket Internet, even though we were using a Phalcon-based framework, many ventures decided to use the standalone Symfony Form component instead of Phalcon forms, because that was the least troublesome one.
Still, they weren’t simple enough for me. Sure, they’re way, way better than handling the forms without any framework, but whenever I needed to do anything even slightly non-standard, I really missed the option of just writing down some HTML. Instead, I had to learn about the internals of the framework. I didn’t like it, so, I’ve spent ages trying to prove to myself, that one can make the best of two worlds.
The same with the security layer. I really hate how Symfony implements it. It’s a piece of cake to configure the most simple cases, they hide everything behind a veil of magic. But as soon as you need something non-standard, you need to go through their documentation, get into their way of thinking, understand their ideas... You can’t just write down the simple logic you need, you need wrappers, voters, providers, listeners, etc. etc. I decided to try to implement it my way.
And it worked for me. I’ve released Micrus • Tiny, yet powerful, PHP framework that later become Micrus v4 • Beauty of simplicity. I’ve built a couple of projects based on Micrus (listed at micrus.avris.it). I had fun, seeing how easy it was for me to build apps with Micrus.
Whenever I would encounter something worth improving, I did so. How exhausting was that! On one hand disappointing (I wasn’t expecting anyone else to use it), on the other really rewarding (it is an accomplishment after all). When I discovered The non-magic of autowiring, I implemented that as well. I covered 100% of my code with unit tests (which was quite a challenging type of code to cover).
But then, Symfony has released its version four. And it’s amazing. It has Flex, it’s flexible, it’s fast... Maybe it’s not as simple as I would wish it to be, but it’s undeniably way better than anything I could ever create myself. Also, I simply got tired of building Micrus already. It grew bigger than I thought it would, it started resembling Symfony more and more, while I understood more and more of Symfony’s design...
So there I am: having learned an awful lot about standards, modularisation, architecture, framework internals, autoloading, autowiring, testing, managing dependencies, and much much more. Having created something irrelevant, but quite impressive nevertheless.
I’m still gonna keep putting Micrus in my CV, I’m still gonna keep most of my Micrus-based-projects running it, but I’m not gonna improve it anymore or start any new projects on it.
It’s been a wonderful adventure. Now it’s time to move on 😊