[Part 2/100] Laravel encourages poor programming practices

verystrongfingers

Mitchell

Posted on June 10, 2021

[Part 2/100] Laravel encourages poor programming practices

Part 2 (of 100)

Skip to the last half overall if you just want to see specifics.

"Poor programming"?

Obviously the meaning behind "poor programming practices" is subjective, there is no clear-cut laws of "good programming".
However, to a degree there some level of mutual agreement throughout the internet with what defines "bad programming".

My perspective of how "poor programming" can occur is:

  • When someone understands their tooling more than the underlying language
  • Implementations using frameworks that lack consistency
  • Code has been writing to make something work (instead of writing code that enables functionality)
  • Codebase developed with tight coupling
  • Complex code is being developed (typically looks impressive, but sucks to work with)

Why is Laravel a popular framework?

Could it be due to...

  • Ease of use? (Small learning curve)
  • Due to good or lucky SEO for "PHP Framework"
  • It's not, PHP is popular and Laravel has the most internet points
  • Because it is a proven, mature, general purpose (web) framework
  • Something else, or a combination of above?

I speculate the reason Laravel has gained so much traction is due to a combination of PHP being on the forefront of web development (plus its loosly typed nature), combined with Laravel being a general-purpose framework that really is easy to learn and build with.

Laravel ❤️'s poor programming

In the current state of the world in technology, it's very clear that:

  • Web technology & development has really blown up in the last 10 years
  • PHP is relatively very easy to run, write and learn (compared to other languages)
  • Laravel is popular and commonly associated with PHP

We’re encountering a wave development where we have lots of people becoming Laravel developers. Not PHP developers, not "developers”. Just Laravel specialists.

Laravel provides a wrapper for every conceivable & commonly used data type, and abstract concept so that these developers never have to leave the ecosystem.
We have thousands of composer packages that exist for Laravel specifically, instead of being a package that provides an optional Laravel service provider.

Obviously for any given framework this is somewhat expected, but Laravel is in a league of its own and does not really teach developers anything beyond using magical clan code.

Specifics

Facades

Facades are an absolute sin. They should never have been.

We know with certainty that:

  • global state is bad
  • service-locators are an anti-pattern
  • magic sucks and is not reliable
  • phpDoc type-hinting is not necessarily true

Facades violate all four. When you use a facade, you are asking:

// Please oh magic eight ball, magically find my Cache service and fetch this cached item
$value = Cache::get('my-cache-key');
Enter fullscreen mode Exit fullscreen mode

Congratulations, you're lazy and have just admitted that you have absolutely no idea where your cache service lives.

Justified as “beautiful code”, facades have an unseen cost.

  • code has become extremely less testable
  • you have unnecessarily tightly coupled yourself with the framework
  • your reliance on the framework greatly increases due to requiring test helpers to manipulate implementations.

Magical service resolution is not a good idea.

Helpers functions

https://laravel.com/docs/8.x/helpers#available-methods

Any global helper function that can provide application specific insights is pure magic evil.

  • session() function may be used to get or set session values:
  • request() returns the current request instance or obtains an input field's value from the current request
  • there are many more... I'm too lazy to reference

How can a function that has no context of your bootstrapped application resolve things?
By using static variables.

Static variables essentially bring forward most of the points from Facades.
Beautiful code comes at a cost.

P.S. dd() is not a debugging tool.
P.P.S. tap() is really dumb and I refuse to understand it

Chained methods

$data = tap($data, fn($paginator) => $paginator->getCollection()
    ->transform(function(ProcessAppointment $apptService) use ($request) {
        $person = $request->user->getName();
        $appointment = $apptService->scheduleAppointment($request->input('appt_time_requested'));

        return $apptService->bookIt($appointment, $person);
    }
));
Enter fullscreen mode Exit fullscreen mode

🤮 We're all aware that Laravel fully embraces the usage of callbacks & chained methods (ie. return $this;).

Chained methods... look sort of cool I guess? Maybe slightly nicer to read at a glance?
Go back to 2008 and write some JavaScript if you want to see where this story ends up.

Chained methods result in complicated code (lots of function calls) that is not fun to work with, it makes testing harder and offers nothing of value other than writing less code.

Late Intermission

If you're into "Wave" music (you're probably not), check out Yedgar.

Caveats

This 100 part series is quite literally revolved around "Laravel bad", which to be honest is pretty dumb because Laravel isn't "bad" - I just disagree with some of the principles & features on offer.

Laravel exists to be easy, and there's absolutely demand for it. The issue is that Laravel developers are increasingly turning into some weird cult.

You shouldn't be proud to master a framework that exists to be easily mastered.
Nor should you be defensive of your precious framework just because you've hinged your entire career off it.

At very least be open minded enough to consider alternatives, learn why parts of Laravel is (or isn't) bad, don't assume anything, especially do not assume the documented Laravel way is the right way.

Just because it’s original doesn’t mean it’s good.

💖 💪 🙅 🚩
verystrongfingers
Mitchell

Posted on June 10, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related