Thoughts on Laravel and best practice
What got me thinking
I was looking at a thread on Reddit's PHP sub, titled Laravel devs are slowly killing best practices.
Seems a little melodramatic, and I say that as someone who's not especially an advocate for Laravel.
The top-level poster says the following:
I feel like Laravel devs have a mission to make PHP the worst language ever exists and please stop repeating these nonsense tweets :
- Final is trash
- Types are useless
- Best practices are a myth
- Laravel is the best web framework (sorry it's not)
So naturally, being bored and loquacious, I decided to weigh in with my two cents. You can read my original comment on Reddit, but I've broken it up below as I felt it was a worthwhile entry in the oft-underused "musings" section of my blog.
Laravel vs Symfony
Symfony has been my framework of choice for the last decade. I don't very much like Laravel and I don't really use it.
But I'm not going to join in any hate for it either.
What Laravel is very good at is being expressive, and offering a low bar of entry to productivity and rapid development. This is a good thing; there's a valid reason Laravel is so popular.
What Symfony is very good at is being unopinionated, optimized and flexible. It has a considerably higher learning curve but a lot more power to be configured, overridden and selectively used pretty much any which way you want.
On the final keyword
A quick mention for final - in all the years I've been a developer (which is quite a few), I've never had a use for final. I've never marked a class as final myself, I've never seen a single, real world case where a class not being marked as final has caused a problem which would have otherwise been avoided.
As far as my personal views, if you can create an instance of a class, you should always be asking yourself if extending it might be a design smell. So final doesn't really add anything there, except to make it awkward on those occasions your best judgement (or someone else's consuming your code) says that yes, you really do have a good reason for overriding something.
On dynamic typing
"Types are useless" - I've said it repeatedly in conversations over the years, one of PHP's greatest strengths is that it's a dynamically typed language. It's not a bug, it's a feature, and a damned useful one at times.
That doesn't mean it isn't preferable to have disciplined design and operate with type safety and type-aware code where you can, but it does mean it's a hell of a lot less cumbersome to do a wide range of useful and common tasks in PHP when dealing with some data structures and APIs than it is in any language which enforces strict constraints around types.
And we accept the trade-off that sometimes we might get a bug because of a loose type check or an internal conversion we didn't intend. The trade-off in static languages is that it's harder, more verbose and more of a pain to achieve the same working result.
On the other side of the coin, of course dynamic typing makes it easy to write functional code with poor architecture (that is, offers a strong temptation to be lazy as a developer). But that's your responsibility as a developer and as a professional if you are one.
C makes it easy to write code which leaks memory and crashes computers, and Java makes it easy to write code which will gobble up your RAM like nobody's business. Those aren't the languages' problems to fix.
I've never understood why some people argue an onus is on PHP in particular to prevent people doing bad programming which they don't demand of any other language.
What's in a best practice, anyway?
And so on to "best practice" - I've always considered this more of a form, an ideal, than something which actually exists. If it does exist, I've never seen it and no one's ever been able to satisfactorily define it.
Lots of folk, myself included, consider much of Symfony to be a paragon of this nebulous "best practice", but have you ever looked at the Symfony source? Run it through your static analyser and code checkers with your standards, your rules, your levels?
It does a whole bunch of stuff in loads of places which would make you weep depending on what you consider to be "best practice." But it works brilliantly.
Rather than "best practice", I prefer to think and talk in terms of "what we've agreed we do here, in this place on this project, as a team." That's something you can pin down and be precise about, and justify.
The most important bit of advice about coding coming from me, as a so-called senior developer where I am, to someone with less knowledge, less experience of various projects and businesses and all that, would be that you need to learn that there are no inviolable rules.
"Always do this, never do that", it's utter nonsense. The "rules" you learn about programming are really guidelines, and many of them are good guidelines based on tens of thousands of people's experiences about what's worked and what hasn't. But even good guidelines aren't always going to be the best thing you can do in practice.
We don't write software to do nothing, we do it in some context or other, to achieve some goal or other, to be used by someone or other. The "best practice", then, goes well beyond anything to do with the code.
If Laravel works for you, use Laravel. If it works for your business, use Laravel. If you're learning programming and find it easier to start with Laravel than Symfony, start with Laravel.
All comments are pre-moderated and will not be published until approval.
Moderation policy: no abuse, no spam, no problem.
Why type hinting an array as a parameter or return type is an anti-pattern and should be avoided.
Leveraging the power of JSON and RDBMS for a combined SQL/NoSQL approach.
Musings from a Reddit thread
Life with a newborn baby aka why I sometimes go long periods of time without making any new posts.
Maximise performance with load once scripts, kept in long-running memory