
PHP Frameworks Code Complexity Comparison - sconxu
https://medium.com/@taylorotwell/measuring-code-complexity-64356da605f9#.hc0xvhpv5
======
ehnto
It's co-location is very low however. What you want is never nearby, and
thanks to the Facade system used for service location it also isn't always
clear which class is actually being used without digging through some
configuration files, and an IDEs autocomplete and click through has no hope
without a generated helper file.

This leaves you digging through dozens of tiny files, some barely longer than
the class definition itself, just to find even high level logic. I normally
learn frameworks by simply reading the code, but I can't help but feel
fatigued when having to try and find where a line of logic actually lives in
Laravel. It is almost always a journey.

~~~
sidlls
Why is the longest method size 13 lines? That to me is an indication that
functions are actually not doing enough themselves, and rely heavily on
delegation to other functions (e.g. far too many functions are simply a few
lines consisting of calls to other functions, possibly far-removed from the
context, with little or no logic "built-in" to the function itself). Usually
when I see that sort of thing it's because the functions were designed for
unit-testability instead of utility in a programming project.

~~~
ehnto
That is what I see going on. Lots of abstraction and glue code and very little
actual logic. There seems to be a tipping point where code goes from utilities
informed by best practice to a collection of best practices informed by
utility. I think Laravel can be an abstraction too far in some circumstances,
but it is a mostly clean and enjoyable framework to work with. Certainly in
the historic context of PHP frameworks.

------
rc_bhg
I don't think this is a good argument for or against any framework. It's just
an interesting side note.

~~~
zapt02
In the case of Laravel vs Symphony, I think it can. Laravel packs absolutely
everything you need to build a web app while still being less than half the
size of Symphony, which has a lot less out of the box and expects a litany of
third party packages to become functional.

~~~
tyingq
Laravel seems to pull in at least 9 pieces (probably more) of Symfony via
composer:
[https://github.com/laravel/framework/blob/5.3/composer.json](https://github.com/laravel/framework/blob/5.3/composer.json)

Are those pieces counted in these statistics or the "half the size" thought?

~~~
zapt02
Good observation. Some of them appear to be debug packages (console, debug,
var-dumper) and the others seem to be quite basic stuff (routing, http
handling) that is good to reuse, and is also likely something you'll have in
your Symfony projects.)

------
throwaway2016a
Bulleted lists are a terrible format for this. This is exactly what tables
were made for. It's hard to do a comparison if it's not side-by-side.

------
debacle
Doctrine is complex because it does a lot of magic. It's a good framework for
anyone who is willing to learn it.

Slim + Doctrine is a pretty good stack. Pick your favorite templating format
and away you go. I think anyone else in modern PHP is generally overkill.

------
mywittyname
IMHO, most of the metrics picked for this comparison are useless.

Longest Method: Sometimes the functionality provided by a method is
irreducible. And breaking off chunks of it into other one-time-use methods
just to reduce method length can be detrimental to readability and
understanding. This is a judgement call and it's not really "bad" unless it's
>1000LoC.

"Complexity": Cyclomatic complexity is a near-worthless metric, especially in
a language like PHP. It's easy to convert a series of 10 if statements into
one while loop by leveraging call_user_func and deterministic method names.
The resulting while statement is infinitely more complex than the if
statements and reduces the benefits of using an IDE. So unless your CC
algorithm treats this kind of programming as wildly complex, then it's not
giving you a true complexity value (in fact, it's actually lying to you).

% of non-static methods: Unless this metric also includes singleton patterns,
then it's useless. Foo::bar() is no different than Foo::getInstance()->bar()
or (new Foo())->bar(). Also, in PHP-land, static methods are considered
acceptable, as long as they have no side-effects or use static variables.

So I think the author is genuinely wasting his time capturing and optimizing
for these metrics, because I don't think they provide any meaningful
improvement to the product.

~~~
voidr
> "Complexity": Cyclomatic complexity is a near-worthless metric, especially
> in a language like PHP. It's easy to convert a series of 10 if statements
> into one while loop by leveraging call_user_func and deterministic method
> names. The resulting while statement is infinitely more complex than the if
> statements and reduces the benefits of using an IDE. So unless your CC
> algorithm treats this kind of programming as wildly complex, then it's not
> giving you a true complexity value (in fact, it's actually lying to you).

Just because you have a way of cheating it, doesn't make it worthless.

I agree that cyclomatic complexity is good, but it's not enough on it's own,
that's why you have other metrics, rules and manual reviews.

------
Avalaxy
I've never worked with these frameworks since I don't use PHP anymore, but I
must say I'm quite impressed by the average LOC per function and percentage of
static function. Especially Laravel surprised me... The longest method is only
13 LOC? Wow!

~~~
bpicolo
TBH not sure how they got that count.

[https://github.com/illuminate/queue/blob/master/Worker.php#L...](https://github.com/illuminate/queue/blob/master/Worker.php#L69)
Here's 17 LOC in the first file I checked.

Not to say that's excessive or a bad thing, just seems the count isn't quite
accurate.

If they aren't counting Illuminate components, seems somewhat unfaithful,
since that's really the Laravel nitty-gritty.

It's also worth noting that 'static' doesn't feel like a good metric in PHP.
There's certainly not a great correlation of static to pure when you're in
global-DI-container contexts. So why do we want statics? Global static
singletons, too, don't feel like a particularly good pattern.

If I'm writing PHP, I -do- try to make 'static' mean 'this function accesses
no globals and has no side effects', because in my opinion it can make PHP a
bit cleaner, but in most PHP frameworks that's not the pattern they're going
for.

In that context, the more statics the better!

Side note: The queue-related bits of Illuminate were pretty difficult to
decompose and work with outside of laravel context, though that's partly
because PHP is a kind of unfortunate language for worker processes in general
because of how the opcache works together with a kludged CLI.

~~~
amilios
If you don't count comments that method is 13 LOC

~~~
vog
Without comments it is 17 LOC, as GP wrote.

Maybe you meant "without closing brackets"?

------
pan69
Not to sure how "fair" this comparison is. You see, both Symfony and Zend
Framework are mostly components, doing kinda low-level-ish things. It probably
means that overall their complexity is probably higher.

A more fair comparison would be to compare Lavavel against both the Symfony
HttpKernel component (which is the framework part of Symfony) and the Zend MVC
module (which is framework part of Zend Framework). But then again, it's
probably not that straight forward.

I mean, when testing Laravel the Symfony HttpFoundation component is left out
but when testing Symfony it's included, not really fair..

------
grimmdude
Would be nice to put this data in a chart.

