6 ms·
PHP Frameworks Code Complexity Comparison
- Avalaxy 10y agoI'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 10y agoTBH not sure how they got that count. https://github.com/illuminate/queue/blob/master/Worker.php#L69 https://github.com/illuminate/queue/blob/master/Worker.php#L... 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.
- Avalaxy 10y agoYou're right. Checked out some non-illuminate parts, because maybe they excluded that, but even in the core classes there are functions that are longer: https://github.com/laravel/framework/blob/5.3/src/Illuminate/Database/Connection.php#L561 https://github.com/laravel/framework/blob/5.3/src/Illuminate...
- EspadaV9 10y agoThe tests were run on 5.4 and it looks like that file has been refactored and the method no longer exists.
- amilios 10y agoIf you don't count comments that method is 13 LOC
- tyingq 10y agoLaravel also pulls in several big pieces from symfony...so it's a framework that uses big pieces of another framework. I don't think that was counted in the statistics either.
- bpicolo 10y agoYeah. That one's a bit more understandable though. Illuminate is a direct subtree split of Laravel, so it's what I would think they'd actually measure =/
- tyingq 10y agoI guess. But if I make my own framework by pulling in an existing one via composer and subclassing, I can make a pretty low "method complexity" and LOC count. I guess I'm just not clear on the actual purpose of this exercise.
- unculture 10y agoThe tool used is: https://github.com/sebastianbergmann/phploc https://github.com/sebastianbergmann/phploc Maybe it's doing things like contracting method calls to one line and making single statement if blocks one line.
- bpicolo 10y agoYeah, might be using the 'lloc'. Though really, it should add + 1 every time someone uses inline declaration in a conditional by a similar metric, hah
- rc_bhg 10y agoI don't think this is a good argument for or against any framework. It's just an interesting side note.
- zapt02 10y agoIn 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 10y agoLaravel 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?
- realityking 10y agoThey're not. From the article: > The primary goal of this comparison is to compare how I personally write code vs. how other projects are writing code.
- zapt02 10y agoGood 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.)
- deweller 10y agoFrom time to time, I need to understand what is going on under the hood of a framework to debug a problem or understand the best way to do things. I find Laravel easy to understand when browsing code because of the short methods. There are tradeoffs, of course, as sometimes it can take several hops through the code to trace down some functionality. But I prefer more short methods vs. one long method any day for readability.
- ehnto 10y agoIt'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.
- bpicolo 10y agoYeah, I've had this same complaint trying to get through it. Digging through Laravel internals can be rough. Here's a small example where things are pretty segregated: https://github.com/illuminate/support/blob/master/Traits/CapsuleManagerTrait.php https://github.com/illuminate/support/blob/master/Traits/Cap... https://github.com/illuminate/queue/blob/master/Capsule/Manager.php https://github.com/illuminate/queue/blob/master/Capsule/Mana... And then the queue capsule manager is not to be confused with the database capsule manager: https://github.com/laravel/framework/blob/master/src/Illuminate/Queue/Capsule/Manager.php https://github.com/laravel/framework/blob/master/src/Illumin... When you're looking through a bunch of things similar to that, it can be a bit confusing to take it all in and remember what is what.
- camus2 10y agoLaravel is actually relatively simple, compared to Symfony "framework edition" where everything is compiled and cached into something else.You'd a dynamic language wouldn't need YAML or XML files for configuration like Struts or Spring... But the truth is that PHP isn't declarative enough to make it unnecessary. In fact Java is more declarative than PHP. The other problem with anything built with Symfony components is that Symfony components never come with good defaults, they are a pain in the ass to instantiate manually, with huge object graphs because "decoupling". That's shouldn't be the case, one shouldn't have to create 15+ objects just to use a form factory for instance. Even Doctrine which is much more complicated than Symfony comes with acceptable defaults. Arrays/Maps of options passed as arguments of class constructors is a blatant demonstration that something is broken.
- throwaway2016a 10y agoBulleted 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 10y agoDoctrine 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.
- grimmdude 10y agoWould be nice to put this data in a chart.
- mywittyname 10y agoIMHO, 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 10y ago> "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.
- pan69 10y agoNot 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..