One the hot topics that whenever you need to start a new tech project you dig into it, spend a lot of time comparing, searching, proving and testing which technology stack, framework, to use.
Generally speaking, the main factors that affect your decision for choosing any technology stack, depends on:
-
Size of the project (small, medium, enterprise).
-
Type of the project (User generated content, e-commerce, blog…etc.).
-
Timeframe given like is it only a POC or will be a core/base to implement on top of it.
-
Size of team, skillset, ability to learn new things.
-
Technology community in terms of size, support, and how often they release, development roadmap …etc.
Taking into consideration the above factors, will play a huge part in choosing which technology stack, framework to choose.
Why?
I’ve been hesitated a lot before starting today’s article (Yii2 vs Laravel a 2019 comparison), where a lot of battles, articles and discussions have been done in the last 2 years and keep going. To be fair, these discussions are healthy and provide a huge knowledge share part that keeps up and up.
When I’ve started this article, I decided to have it in a different way instead of having just a comparison table for features of Yii vs Laravel and try to discuss it from another point of view, from a person who has been working/dealing with Yii framework since 2011 until Today and have implemented huge parts of systems that handle 80M+ requests a day for one of its APIs. With a high availability / fault tolerance / and performance taken into consideration with each step of development.
This ended up by having a long article (~13 pages), as I need to share the comparison from a practical experience, and to be fair I’ve to cover as much parts from both frameworks to help you decide which one to choose. That’s why this discussion will be divided into 3 main parts where in each part I will focus on a topic, and at the end of the article there will be a simple comparison for pros/cons that hopefully will help you in deciding which one to choose.
Part 1
Not only a framework!
To clarify things, to be able to have a high available fault tolerance system, it does not only rely on which framework / programming language you use, as there’re a lot of factors play here, from architectural perspective, elasticity, infrastructure. So, you cannot judge that Yii2/Laravel only will give you a high available system, as there’re many factors effect on this.
As mentioned above after more than 8 years of continuous development using Yii/Yii2 I’ll share with you my notes about it in part 1 and 2, then on the last part I’ll share with you my experience with Laravel, and how it compares to Yii.
Why Yii 1?
When I’d started with Yii at 2011, while coming from a Zend / CodeIgniter background, my questions at that time were:
-
What’s Yii? A fast, secure, efficient, flexible, extensible, MVC framework.
-
What does it refer to? Yes It Is.
-
Why should I go with it?
o Small package size compared to Zend at that time.
o MVC support.
o A lot of extensions that will boost your getting started process.
o Very interactive, supportive community that does not leave a question without an answer.
-
Why should I move from Zend to Yii? Zend at that time was the top most used framework, the same company that develops PHP develops Zend. However, the larger size of the framework, and having to write tons of lines to achieve a simple CRUD system, and the long time spent for development, all these factors played a huge part of trying something new that can ease your work.
-
Many other questions like how and how and how? To be honest, my movement from Zend to Yii took me longer time and this reverts to many factors as I was still at my beginnings in development path and was thinking in Zend mindset of how to do things, in addition for not having a real business case that can be implemented in a standalone project.
Getting Started with Yii 1 took me around 3 months due to reasons mentioned above. Then I’d moved to another company where they were starting a new revamping for their site using Yii framework, where I’ve played a major role in implementing huge parts of the system and interacted almost with every component in the framework from MVC, to caching layers, to assets management, to restful APIs, to security and a lot of components / extensions.
To be honest, the documentation, community, and tutorials helped us a lot on how to get things done following best practices and in fast paced manner. However, during that time we followed an agile development strategy, and in 2013/2014 we’d faced issues on different parts like:
Yii 1 Issues
-
How Yii was managing database connections, for e.g. we needed to split read/write operations and at that time this was not supported by the framework itself, and we were enforced to extend the CDbConnection class and interrupt the query before being executed in order to split read queries to a connection and write queries to another connection (master/slave architecture).
-
How Yii was managing assets, as we were looking to serve assets from a CDN and needed an approach to combine assets and upload it to CDN in a convenient way to avoid latency and duplicate operations.
-
For restful APIs there’s no clear approach how to do versions of your API, how to do rate-limit, and this required us to implement our own approach.
-
During that time also, PHP as a language was developing, and major changes were coming, like namespace, traits, types that Yii 1 was not adapting 100%.
-
Whenever you need to use an extension, you’ve to download it, extract it, and copy it to your project, composer at that time was not commonly used in Yii 1.
Part 2
Lately in 2014, Yii had introduced Its second version of framework (Yii2), which was not a backward compatible with Yii1, and forced us to invest sometime reading and understanding the new changes that Yii has come up with, to start planning for a new revamp/rewrite process.
Not only the framework, also the language!
Good news that PHP also has come up with major changes for class autoloading and name-spacing, that encouraged us to speed up the movement to Yii2.
Introducing Composer
Yii2 default installation was via composer, and this was the first major change from Yii1, to restrict developers to start using composer and being familiar of how to adapt it in Yii. Yii2 came up with 2 different skeletons: one is for basic projects which was very similar to Yii1 skeleton, and the other was an advanced template that introduces multiple apps skeleton, more details can be found here https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide/2.0/en/start-comparison
Our use case was fitting more to the advanced template where there’re multiple apps (common, console, backend, frontend, api). More details can be found here https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide/2.0/en/structure-directories
Yii 1 issues has been solved in Yii 2
Yii2 came up with a solution for all major issues that faced Yii1 developers, like assets management, database read/write connections, extensions via composer, and huge effort on restful that gives you the confident that whatever your use case you’ll have it adapted in Yii2 (Yes, It Is) for e.g. (Versioning / Authentication / Rate-limit / Response formatting …etc.) are covered in a very convenient and smart way.
Seamlessly integration with jQuery/Bootstrap, what’s wrong?
On the front-end side Yii2 did a huge effort in providing widgets for manipulating data, how to represent it, and integrated seamlessly. This was a good/bad decision taken by Yii team as the framework become tightly coupled to jQuery/Bootstrap stack and make it difficult on the front-end side to use Yii2 with other front-end frameworks like React/Angular/Vue …etc.
This was one of the main factors why they started planning seriously for Yii 3, where it’s been decoupled from jQuery/Bootstrap stack and focusing completely on back-end side. However, for people who still prefer jQuery/Bootstrap they can still use it for sure, but it’s not enabled by default.
RESTful
Back to RESTful support by Yii2 framework, as mentioned further Yii2 came up with a full suite solution in terms of routing, response formatting, authentication, rate-limit, versioning, and error handling. I’ll expand more here as this was one the main areas I’ve worked intensively with it and implemented a solution that handles 80M+ requests per day, were in our case we’d multiple clients (Android App, iOS App, PWA) with different app versions and different features / behaviors.
In depth for RESTful support regarding:
- Routing, Yii2 has a class yii\rest\UrlRule
That by default will create a whole set of child URL rules to support routing based on verbs (GET, POST, PUT, DELETE, HEAD) and route it to the appropriate action to handle the request.
-
Response formatting, Yii2 has yii\filters\ContentNegotiator filter which is smart enough to understand clients accepted response formats and return the response in the required format, like JSON/XML/HTML/Text …etc. And what attributes/entities to have as well, fields&expand query params provide a very useful methodology for how to extend your current resource without the need to duplicate your work/code.
-
Authentication, Yii2 has authenticator behavior that works with different authentication methods like HTTP Basic Auth, Bearer Auth, Query Param Auth …etc. It can be configured to seamlessly authenticate requests and continue/reject request.
-
Rate limit, Yii2 has yii\filters\RateLimitInterfacethat is responsible to prevent API abuse and sending too many requests from the same user.
-
Versioning, this is really one of the topics that has a lot of debates, opinions, drawbacks, advantages, and everyone’s use case differs from other. However, Yii2 provides a solution that guarantees backward compatibility and continuous integration in the same time in a robust way.
-
Error handling, Yii2 follows HTTP standard codes for different errors, and this make it easier for clients to predict what kind of error is happening and behave accordingly, for e.g. unauthorized / internal server error / not found / validation error are of the top used errors in RESTful world.
Yii 2 Conclusion
That being said, as a framework Yii2 really did a great job, and fits in all web development functionalities. Moreover, it integrates with other components and services, be it database SQL/NoSQL, be it caching Redis/Memcached, be it authentication, be it response formatting, be it simple forms, be it unit testing …etc.
Emerging Architecture, different demands
Given Yii2 was launched in late 2014, and we’re now in 2019, a lot of changes / stacks / technologies have been evolved, and different mechanisms, software architecture have come to the surface, in addition to the evolution of micro-service/nano-service architecture, server-less architecture, mobile first products, and progressive web apps. Then the need has become to micro frameworks in order to implement a simple / standalone service that integrates/deploys independently. Hence big systems that are implemented as a single / fat unit is not recommended any more.
Yii 3?
Yii team took these changes / factors into their consideration, and started working on the 3rdversion of Yii, which is still in the drafting phase, there’s no clear date when it’ll be released, and more details can be found on the link https://www.yiiframework.com/wiki/2547/draft-understanding-yii-3
Having this into consideration, that if you’re going to start a new project based on Yii2 you should keep an eye on the draft of Yii3 to make sure you’re / will not using a deprecated feature, and this will add extra headache for you as a software architect to make sure that no breaking changes will happen when you upgrade to Yii3.
Part 3
Laravel
I’ll discuss Laravel, and my experience with it, advantages, drawbacks, concerns. However, it’s good to mention that I’m still a beginner to Laravel and cannot dig into all components, how it works and main use cases, but I will try as much as possible to provide a high-level analysis and will keep the discussion for you to hear from you as well.
Laravel Skeleton
Laravel based on their site they say that it’s a PHP framework for web artisan. It can be installed via composer, and provides a directory structure consists of (app, bootstrap, config, database, public, resources, routes, storage, tests, vendor) more details can be found here https://laravel.com/docs/5.8/structure
My first concern on this structure, where is the MVC? and it’s already questioned/answered by them on the link https://laravel.com/docs/5.8/structure
Where Is The Models Directory?
When getting started with Laravel, many developers are confused by the lack of a modelsdirectory. However, the lack of such a directory is intentional. We find the word “models” ambiguous since it means many different things to many different people. Some developers refer to an application’s “model” as the totality of all of its business logic, while others refer to “models” as classes that interact with a relational database.
For this reason, we choose to place Eloquent models in the app directory by default, and allow the developer to place them somewhere else if they choose.
In my point of view, for an MVC based framework it’d explicitly define its MVC structure and not leave it for the developers to define it by their needs. As you cannot implement a tool and ask users of this tool to use it however they want without at least a default setting to start from.
The other concern regarding project skeleton, the app directory contains (Broadcasting, Console, Events, Exceptions, Http, Jobs, Listeners, Mail, Notifications, Policies, Providers, Rules) again where’s controllers? It does not exist by default, and to be honest the above structure does not help you to predict how it works without digging into their documentation to learn about it. Convention over configuration is not followed here, and hence you’ve to do some efforts to learn about each of these components / directories and how to deal with.
Another concern about above structure, I cannot see any relationship between the above directories to have it all under one umbrella, and if I want to compare it with Yii2 structure, then Yii2 has a proper structure as each app by default consists of (model, view, controller, components, config, web, assets, runtime, tests), where you can know explicitly where your code should take place.
Laravel Documentation
One of the main factors for speeding up your getting started with a framework is to have guide tutorial that provide use cases and samples how they’re implemented using this framework. In Yii you’ve the guide tutorial that gives you like a tour on the main functionalities and how they can be used, on the other hand for Laravel, their documentation lacks this important feature, it gives you sample code snippets for general design patterns and how they’re applied in Laravel like Facades, Dependency Injection, Containers and Service Providers.
Having such guide will help any advanced developer to start up fast instead of spending too much time for doing routine or small tasks.
Laravel Contracts
One of the main architectural concepts that Laravel came up with is the contracts, based on their definition, contracts a set of interfaces that define the core services provided by the framework, more details can be found on https://laravel.com/docs/5.8/contracts
Laravel Contracts vs Yii2 Components
Contracts in Laravel are useful, and provide kind of abstraction to your code, however whenever you need to use contracts you’ve to require them in your class constructors / setter methods. For e.g. If you want to use Cache contract you need to explicitly ask for it in your class constructor to be provided, On the other hand in Yii they provide the component-based architecture, and components are part of the app instance and can be loaded via configuration, hence you can use any component anywhere by calling it simply like Yii::$app->componentName.
in Yii components usually based on interface, for e.g. the Cache component is an interface that has the below main methods (get, set, has, delete) and any cache class like Memcached / Redis implements Cache interface which is a convenient OOP standard, so when you need to change from Memcached to Redis it’s a matter of changing it from config without touching any code / logic. However, in Laravel contracts should be explicitly provided in each class using it and this adds overhead when having multiple classes using the same components / services and this leads to code duplication.
Laravel Routing
Routing in Yii is a matter of a configuration array that consists of a key => value structure, where the key is the pattern to match, and the value is the targeted controller/action to run. Simple, convenient, and straightforward style. Yii also provides default routing techniques where any controller’s action can be accessed via controller/action pattern, hence you don’t need to write every single action in your routes array. On the other hand, for Laravel, you’ve to write your routes as a function call style, which leads to writing too much code, and every single action in your controller should be defined in the routes.php to be able to expose it.
In Laravel there’s a convenient way for defining routes that render views only, so this saves you a lot of code when you want to define view only actions that does not have any logic. On the other hand, in Yii you cannot map routes to views directly.
Laravel Authentication
Authentication in Laravel comes up with built in implementation for Registration / Login / Forget Password / and Reset Password. Same thing also provided in Yii, and in most cases you don’t need to override the logic for it.
Secured routes in Laravel should be defined in the route config file, by calling middleware Auth right after route definition, more details can be found here https://laravel.com/docs/5.8/authenticationAnother technique to define authenticated routes inside controller’s __construct() method. For me I don’t prefer such approach, as constructing controllers is a framework job, and any customization should go in separate step not in the construction phase.
However, In Yii authenticated routes can be defined inside controller itself in authenticator behavior, where you can define which actions are public, and which actions require authenticated user and this can be defined in simple configuration arrays.
I’ve dealt with both Yii and Laravel authentication mechanism and found both do the job in a simple way, however it depends on tastes and preferences, for me I might prefer Yii’s way, for others might prefer Laravel’s way. In all cases this job should be simple and robust because it’s used almost in your whole application, and it’d be easy to maintain.
Laravel and Facades
One of the main things I’ve noticed during my journey with Laravel its intensive use of Façade design pattern. This provides you a lot of magic and enrich your classes dramatically. However, this kind of magic is not IDE friendly and makes it really hard for you to debug how’s your application work, and how these methods took place. On the other hand, Yii is fully IDE friendly and this makes development time boost dramatically, as you’ve auto-complete, and auto import missing classes …etc.
Another concern is that Laravel intensively using closures/callback functions like jQuery style, however this opens functional programming / OOP discussions which will not lead to a winner. But to help you judge you’ve to read about pros/cons of both functional and object-oriented programming to understand the side-effects of such approach.
Laravel Views
Regarding view rendering, I’ll not dig deep in both Yii/Laravel, since as mentioned before with the evolution of PWA most of web applications now render on the client side instead of using server-side rendering. There’re multiple frameworks to be used for this purpose like React / Angular / Vue and much more. However, it’s good to mention that both frameworks support templating like blade in Laravel and Twig/Smarty in Yii. And in case you need to dig deep you can refer to https://laravel.com/docs/5.8/views
And https://www.yiiframework.com/doc/guide/2.0/en/structure-views
Validation
Validation in Yii occurs in models, where you define a set of rules, a set of rules for specific scenarios, and define which attributes to be validated per scenario and this happens in a very clean / robust way.
On the other hand, in Laravel validation occurs in the controller, and could be written in separate classes / facades where you define all your validations logic. For most of validation cases both solutions work, however when you’ve scenarios for validation then in Laravel you’ll end up by tons of lines which are hard to trace and debug.
ORM in Laravel / Yii
Relational data in both Yii and Laravel works in a very similar way in terms of how to define it and how to call it. Yii2 uses ActiveRecord and Laravel uses Eloquent, both are handy and provide you control for whatever you want, and to be fair both documentations can help you a lot in case you’ve any questions on how to do something.
Summary
To summarize it up, both frameworks Yii and Laravel can give you whatever you want to achieve at the end of the day, it’s kind of different schools / different tastes for writing code. In terms of robust and well-designed architecture both frameworks are well supported by the teams behind it.
As mentioned before, with the emerging micro-service/nano-service architecture and the demand of having small services that are maintained / deployed independently then the need for large frameworks that do a lot of things is not recommended any more. As most of the services are focused on specific operations / functionalities and hence huge parts of the framework features might not be used. However, the common features like (Request / Response handling, routing, authentication, authorization, manipulating data in/out) are common tasks that you’ll use it in every service.
Yii is developing the 3rd version of the framework, where there’re features deprecated, there’re break changing features, and huge parts till now will keep the same. If you’re about to choose Yii2 as your framework then you’ve to take these factors in your concern.
Yii is an IDE friendly framework, and you can boost your development time significantly, on the other hand Laravel is not. However, Laravel’s syntax is simple and you can be familiar with it shortly.
Think of client-side rendering frameworks like React/Angular/Vue and think how it can be integrated with both frameworks, and what’s the best way for your case.
RESTful support in Yii from my experience with it, was pretty mature and robust, and Yii2 Serializer makes your resources extendible to the most without the need define separate versions on every api change.
Last note, the more your framework of choice helps you boost your development process, and helps you do routine tasks seamlessly, and the more its documentation will help you achieve what you want, then your choice will be most likely correct and robust.
Comments are more than welcomed, and to have it clear from the beginning there’s no winner in both frameworks, but there’s a better understanding on which can help you achieve your use case in a convenient way.