So sánh Laravel và Phalcon

So sánh Laravel và Phalcon

Bài viết được sự cho phép của tác giả Adnan Bakakan, các bạn có thể tham khảo link gốc tại đây

Gần đây tôi đang thực hiện một dự án cá nhân và một dự án thương mại. Vì đã từng dùng và có một số kiến ​​thức cơ bản về Laravel nên tôi quyết định lấy Laravel làm framework sử dụng cho dự án thương mại của mình và Phalcon cho dự án cá nhân. Trong bài viết này tôi sẽ so sánh Laravel và Phalcon để các bạn có thể lựa chọn framework phù hợp cho dự án sắp tới của mình.

Laravel là một trong những framework nối tiếng và phổ biến nhất hiện nay, trong khi đó Phalcon được đánh là framework có tốc độ thực thi nhanh nhất cho nền tảng PHP. Vì vậy, 2 framework này chắc chắn là một trong những sự lựa chọn tốt nhất ở thời điểm hiện tại. Symfony, Yii, Cake hay Code Igniter và các framework khác đều có điểm mạnh và yếu nếu mang ra so sánh cùng, tuy nhiên trong phạm vi bài viết này tôi sẽ chỉ so sánh Laravel và Phalcon do đã từng sử dụng cả hai.

Tại thời điểm viết bài này, tôi sẽ sử dụng Laravel 6 và Phalcon 3.4. Việc so sánh sẽ dùng phương pháp chấm điểm để thực hiện việc đánh giá, không thiên vị bất cứ một framework nào mà hoàn toàn từ góc nhìn & sử dụng của lập trình viên. Đây không phải là một sự so sánh chuyên sâu, tôi sẽ cố gắng tóm tắt để mang lại thông tin hữu ích nhất cho các bạn.

Cài đặt và bắt đầu

Chúng ta hãy bắt đầu bằng việc setup môi trường làm việc để hiện thực hóa ý tưởng (thực sự tôi rất ghét việc phải push thư mục .idea lên GIT repo LOL)

Cài đặt Laravel khá dễ dàng và việc bạn cần làm là cài đặt các gói sử dụng composer và dùng câu lệnh laravel để khởi tạo project. Nếu không có composer, thậm chí bạn chỉ cần copy & paste Laravel files và bắt đầu code.

Phalcon hơi khác biệt một chút, bởi vì nó được build là một C-extension (mặc dù bạn sẽ viết mã PHP 100%), bạn phải cài đặt trên server hoặc máy local để có thể bắt đầu sử dụng. Bạn có thể compile hoặc sử dụng các bản pre-compiled. Ngoài ra, Phalcon cung cấp công cụ Phalcon DevTools giúp bạn tạo project và bắt đầu code.

Laravel sử dụng câu lệnh laravel new sẽ mất một chút ít thời gian hơn phalcon create-project bởi vì Laravel sẽ cần cài đặt một số package để chạy, trong khi Phalcon gần như tức thời tạo sẵn cho bạn mọi thứ cần thiết.

Bởi vì việc thiết lập Phalcon mất nhiều thời gian và phức tạp hơn, do vậy ở phần này, chiến thắng thuộc về Laravel

Laravel: 1

Phalcon: 0

File structure

Một thứ rất quan trọng đối với hầu hết lập trình viên là cấu trúc của framework khi khởi tạo mặc định.

Laravel được tổ chức rất tốt, tuy nhiên theo ý kiến của tôi có một vài vấn đề. Models được lưu trong thư mục app, cùng với nhiều folders khác sử dụng cho controllers và nhiều thứ khác, không được thực sự gọn gàng. Laravel cũng là một framework khá nặng khi bao gồm rất nhiều file được mặc định tạo ra.

Phalcon thì khác so với Laravel và các framework khác. Bởi vì nó là một C-extension, nên bạn sẽ không thấy Phalcon trong thư mục project, do vậy cấu trúc thư mục rất gọn gàng và đơn giản. Bạn có thể thiết kế cấu trúc riêng hoặc sử dụng cấu trúc mặc định cung cấp bởi Phalcon DevTools. Vì vậy, bạn sẽ chỉ có các files bạn cần cho project, sẽ dễ dàng hơn nhiều khi cần upload hoặc transfer project.

Phalcon fresh project file structure

Đây là cấu trúc thư mục tạo bởi Phalcon DevTools

Phalcon fresh project tree

Cấu trúc tree của project Phalcon giống như trên

Laravel fresh project file stricture

Đây là cấu trúc của Laravel project  sử dụng công cụ Laravel CLI

Rõ ràng đây là một thắng lợi dành cho Phalcon

Laravel: 1

Phalcon: 1

Tốc độ và hiệu năng

Đây là một trong những điều quan trọng nhất khi các bạn lựa chọn framework.

Hãy sử dụng một công thức tính toán đơn giản. PHP là ngôn ngữ được viết bằng C và C++ cho một số thành phần, tuy nhiên PHP chậm hơn nhiều khi so sánh với C và C++. Bởi vì Laravel được viết hoàn toàn bằng PHP, nên rõ ràng việc so sánh với Phalcon (C-extension) là một sự so sánh không cân xứng. Rõ ràng Phalcon rất nhanh, bạn có thể nhìn biểu đồ dưới đây

PHP Frameworks speed comparison

Bản quyền hình ảnh: https://systemsarchitectdotnet.wordpress.com/2013/04/23/performance-benchmark-of-popular-php-frameworks/

Chiến thằng trong phần này thuộc về Phalcon là tất yếu.

Laravel: 1

Phalcon: 2

Mức độ phức tạp

Điểm quan trọng tiếp theo với một framework là mức độ phức tạp. Mất bao lâu để bạn có thể học và viết một ứng dụng là một điều đáng để lưu tâm.

Laravel có một kho tài liệu gần như tốt nhât cho lập trình viên và hàng nghìn bài viết hướng dẫn, vì vậy sẽ giúp bạn tiếp cận và học rất nhanh, kể cả đối với các bạn mới học.

Phalcon cũng có một kho tài liệu được tổ chức tốt, tuy nhiên việc đọc hiểu Phalcon sẽ cần ở bạn một kinh nghiệm nhất định. Phalcon cũng không có được nhiều bài viết hay video hướng dẫn như Phalcon. Ngoài ra do không có files framework trong cấu trúc thư mục nên bạn cũng không thể đọc được những comment để hiểu cách thức hoạt động của chúng.

Điểm chiến thắng thuộc về Laravel.

Laravel: 2

Phalcon: 2

Kiến trúc

Hầu hết các framework hiện nay đều sử dụng kiến trúc MVC (model-view-controller) bởi vì độ phổ biến và dễ dùng trong cộng đồng lập trình viên.

Laravel sử dụng MVC một cách hoàn hảo. Tuy nhiên khi dự án của bạn trở nên lớn thì mô hình MVC sẽ gặp vấn đề, khi đó HMVC (Hierachical model-view-controller) sẽ trở nên cần thiết.

HMVC hiểu đơn giản là MVC tuy nhiên trên nền tảng component. Giả sử bạn có 1 website có 2 phần blog và diễn đàn, thì HMVC sẽ chia 2 phần này là 2 components MVC để bạn có thể phát triển độc lập.

Phalcon cho phép bạn triển khai theo mô hình HMVC một cách dễ dàng, và rõ ràng đây là một điểm cộng cho Phalcon.

Laravel: 2

Phalcon: 3

Tích hợp cơ sở dữ liệu

Cơ sở dữ liệu là một phần không thể thiếu trong mọi ứng dụng web và desktop. Cả Laravel và Phalcon đều cung cấp giải pháp ORM (Object-relational mapping) phù hợp để lưu và truy vấn dữ liệu một cách dễ dàng.

Laravel sử dụng Eloquent trong khi Phalcon cũng có một công cụ tương tự, tuy nhiên phải thú nhận rằng Eloquent dễ sử dụng và nhiều tính năng hơn.

Tương tự ORM là ODM (Object-document mapping), thường sử dụng cho NoSQL database như MongoDB. Đáng tiếc là Laravel không hỗ trợ ODM từ đầu, tuy nhiên bạn có thể cài thêm các gói hỗ trợ. Trong khi đó, Phalcon cung cấp một vài công cụ giúp bạn thực hiện việc kết nối với MongoDB một cách nhanh chóng.

Bởi vì Laravel hỗ trợ rất tốt cho ORM, trong khi Phalcon hỗ trợ cả ODM và ORM, nên tôi nghĩ rằng phần này cả 2 đều có điểm.

Laravel: 3

Phalcon: 4

Điều hướng (Routing) và Điều khiển (Controller)

Nói về ứng dụng web, là chúng ta nói về routing (điều hướng)!

Cả hai framework cung cấp nhiều cách thức để xây dựng điều hướng cho ứng dụng. Cả 2 đều có khả năng xử lý tất cả các HTTP methods phổ dụng như POST và GET.

Routing của Laravel thực sự rất dễ sử dụng, cung cấp cho bạn mọi nguyên liệu để xây dựng routing theo ý bạn muốn. Trong khi đó Phalcon lại có phần khó sử dụng hơn. Tôi nghĩ vấn đề với Phalcon là thiếu tham số tùy chọn cho routing, làm cho tôi phải tạo ra 2 routes: 1 route với tham số, và 1 route không.

Cả 2 framework đều hỗ trợ tiền tố (prefixing) và nhóm điều hướng (grouping routes). Bên cạnh đó, Laravel còn hỗ trợ sub-domain routing, điều mà Phalcon không có.

Ví dụ routing với Phalcon:

<?php

use Phalcon\Mvc\Router\Group as RouterGroup;

$router = $di->getRouter(false);
$router->removeExtraSlashes(true);

//X User Routing Group
$x_user = new RouterGroup(['controller' => 'XUser']);
$x_user->setPrefix('/x');
$router->add('/x', ['controller' => 'XUser', 'action' => 'home']);
$x_user->add('/login', ['action' => 'login'])->setName('login');
$x_user->add('/logout', ['action' => 'logout'])->setName('logout');
$x_user->add('/sign-up', ['action' => 'signUp'])->setName('sign-up');
$x_user->add('/remember-me', ['action' => 'remember'])->setName('remember-me');
$x_user->add('/verify', ['action' => 'verifyAccount'])->setName('verify-account');
$x_user->add('/profile', ['action' => 'profile'])->setName('profile');
$router->mount($x_user);

 Ví dụ routing với Laravel:

<?php

use App\Category;
use App\Mail\ResetPassword;
use Illuminate\Support\Facades\Mail;
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;

Route::get('/', 'GeneralController@home');

Route::prefix('/user')->group(function () {
    Route::post('/sign-up', 'UserController@signUp');
    Route::post('/login', 'UserController@login');
    Route::get('/logout', 'UserController@logout');
    Route::post('/forget-password', 'UserController@forgetPassword');
    Route::get('/reset-password', 'UserController@resetPasswordLanding');
    Route::get('/verify-email', 'UserController@verifyEmail');
    Route::get('/profile/{username}', 'UserController@profile');
});

Rõ ràng, Laravel chiếm ưu thế hơn, thêm một điểm nữa dành cho Laravel.

Laravel: 4

Phalcon: 4

Template engines

Khi chúng ta nói về ứng dụng, chắc chắn một phần quan trọng là giao diện đối với người dùng cuối (front-end). Template engine là thành phần hỗ trợ bạn trong việc kết nối back-end logic với HTML/CSS hay Javascript một cách dễ dàng hơn.

Laravel cung cấp một template engine tên là Blade, trong khi Phalcon sử dụng Volt (tương tự như Twig của Symfony) nhưng đơn giản hơn và được compile trước.

Cả Blade và Volt đều mạnh mẽ, nhưng Blade dễ sử dụng và thuận tiện do có nhiều functions và methods có sẵn.

Volt nhanh hơn nhiều bởi vì nó được compile từ trước, tuy nhiên Blade cũng có thể cải thiện tốc độ bằng cách cache lại.

Ví dụ một file Volt template:

{% extends 'layouts/main.volt' %}

{% block title %} - صفحه {{ page_number }}{% endblock %}

{% block content %}
    <div class="row">
        <div class="columns large-9 small-12">
            <div class="widget">
                <div class="widget-title"><span>آخرین مطالب - صفحه {{ page_number }}</span></div>
                <div id="recent-posts">
                    {% for post in posts.items %}
                        <div class="post{% if post.important %} important{% endif %}">
                            <a href="{{ post.postLink() }}"><img src="{{ post.featured_image }}" alt="{{ post.title }}"
                                                                 class="cover"/></a>
                            <div class="content">
                                <div class="post-type">
                                    {% if post.categories.parent_id != 0 %}
                                        <?php $parent_category = \iCriticize\Models\Categories::findFirst(["id = '{$post->categories->parent_id}'"]); ?>
                                        <a href="{{ parent_category.categoryLink() }}"
                                           class="category">{{ parent_category.name }}</a>
                                    {% endif %}
                                    <a href="{{ post.categories.categoryLink() }}"
                                       class="category">{{ post.categories.name }}</a>
                                </div>
                                <h3><a href="{{ post.postLink() }}">{{ post.title }}</a></h3>
                                <div class="info">
                                    <i class="la la-user"></i> {{ post.users.nickname }}
                                    <i class="la la-calendar"></i> {{ post.shortPublishDate() }}
                                    <i class="la la-clock-o"></i> {{ post.publishTime() }}
                                    <i class="la la-comments-o"></i> {{ post.commentsCount() }}
                                </div>
                                <p class="preview">
                                    {{ post.preview() }}
                                </p>
                            </div>
                        </div>
                    {% endfor %}
                </div>
                {% include 'UserEnd/includes/pagination.volt' %}
            </div>
        </div>
        <div class="columns large-3 small-12">
            <div class="widget full-height">
                {% include 'UserEnd/includes/sidebar.volt' %}
            </div>
        </div>
    </div>
{% endblock %}

{% block footer_scripts %}
    <script src="{{ settings.site_address }}/bundles/home.bundle.js"></script>
{% endblock %}

và đây là Blade template:

@extends('layouts.main')

@section('title')
    {{$user->first_name}} {{$user->last_name}} ({{$user->username}})'s Profile
@endsection

@section('content')
    <app-profile :user-info='{!! $user !!}' avatar="{{$user_private_info->getAvatar()}}"
                 member-since="{{$user_private_info->signUpDate()['month_name']}} of {{$user_private_info->signUpDate()['year']}}"
                 @if($user->account_type == "Employer"):user-projects='{!! json_encode(array_slice($user->employerProjects->toArray(), 0, 5)) !!} '
                 @endif
                 @if($user->account_type == "Freelancer"):user-projects='{!! json_encode(array_slice($user->freeLancerProjects()->toArray(), 0, 5)) !!}'@endif></app-profile>
@endsection

Thành thực mà nói, tôi thấy Volt gọn gàng và nhanh hơn Blade, do vậy tôi chấm điểm cho Phalcon ở mục này. Xin lỗi các fan của Laravel nhé!

Laravel: 4

Phalcon: 5

I18n

Ứng dụng có thể cần xây dựng với giao diện đa ngôn ngữ, và rõ ràng nếu không có các công cụ hỗ trợ sẽ khiến chúng ta mất nhiều thời gian để thực hiện. Rất may là cả Laravel và Phalcon đều cung cấp đầy đủ các phương tiện, do vậy cả hai đều đạt điểm ở hạng mục này

Laravel: 5

Phalcon: 6

Bảo mật

Khi viết ứng dụng, trách nhiệm của bạn là đảm bảo không ai có thể can thiệp vào các chức năng đã được thiết kế theo mục đích sử dụng của ứng dụng. Cả 2 framework đều cung cấp đầy đủ các công cụ bảo mật giúp bạn phòng chống các hình thức tấn công phỏ biển như XSS hay SQL Injection.

https://res.cloudinary.com/practicaldev/image/fetch/s--5X_3axm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/d1decd46dff0fa95788f5647a0c6edef23103e0f/fff15/assets/images/content/filter-sql.png

Bức tranh này được lấy từ tài liệu về lọc và kiểm soát dữ liệu của Phalcon

Laravel cung cấp cách thức tốt hơn Phalcon trong việc xử lý CSRF token. Do vậy, chiến thắng thuộc về Laravel.

Laravel: 6

Phalcon: 6

Middlewares

Bạn sẽ cần gì khi bạn muốn chạy một task khi người dùng gọi đến ứng dụng. Chắc chắn là một middleware!

Đối với một ứng dụng phức tạp thì middleware là một phần hết sức quan trọng. Ở mục này thì phần thằng 100% thuộc về Laravel bởi vì Phalcon không hỗ trợ middleware, ít nhất ở mức độ người dùng mong đợi.

Tất nhiên bạn có thể sử dụng controller để chạy một vài task trước khi route bằng cách định nghĩa một base controller và sử dụng hàm __construct(), nhưng thực sự đó không phải là cách tôi mong muốn.

Laravel: 7

Phalcon: 6

RESTful API

Một vài lập trình viên chỉ sử dụng back-end framework cho việc thiết kế API & hệ thống RESTful API.

Laravel hỗ trợ và cung cấp nhiều công cụ rất tốt để bạn thực hiện việc này, bao gồm hỗ trợ cả axios với csrf token. Đối với Phalcon, tôi phải tự xử lý response của API controller để chuyển đổi thành JSON (với Laravel là mặc đinh), cập nhật CSRF token để request tiếp theo sẽ không xảy ra lỗi.

Và đây là kết quả tôi làm với Phalcon:

<?php

namespace iCriticize\Controllers;

class ApiController extends BaseController
{

    public function beforeExecuteRoute()
    {
        $this->response->setHeader('Content-Type', 'application/json');

        if (!$this->security->checkToken()) {
            if ($this->dispatcher->getActionName() != "APITokenInvalid" and $this->dispatcher->getActionName() != "APITimeLimitReached") {
                $this->dispatcher->forward(["action" => "APITokenInvalid"]);
            }
        } else {
            if ($this->session->has('last_api_request_time')) {
                if ($this->session->get('last_api_request_time') < time() - 1) {
                    $this->session->set('last_api_request_time', time());
                } else {
                    if ($this->dispatcher->getActionName() != "APITimeLimitReached") {
                        $this->dispatcher->forward(["action" => "APITimeLimitReached"]);
                    }
                }
            } else {
                $this->session->set('last_api_request_time', time());
            }
        }
    }

    public function afterExecuteRoute()
    {
        $this->view->disable();
        $data = json_decode(json_encode($this->dispatcher->getReturnedValue()), true);
        $data["csrf_token_update"] = [$this->security->getTokenKey() => $this->security->getToken()];
        $data = json_encode($data);
        $this->response->setContent($data);
        return $this->response->send();
    }

    public function APITimeLimitReachedAction()
    {
        return ["status" => "ERR_API_REQUEST_TIME_LIMIT_REACHED"];
    }

    public function APITokenInvalidAction()
    {
        return ["status" => "ERR_API_TOKEN_INVALID"];
    }

}

Rõ ràng là một thắng lợi dành cho Laravel.

Laravel: 8

Phalcon: 6

Khả năng tùy biến

Khi bạn cần nhiều sự tùy biến hơn cho những ứng dụng phức tạp, Phalcon có lợi thế hơn nhờ Zephir, ngôn ngữ lập trình bậc cao được sử dụng để viết các thành phần mở rộng cho PHP mà không cần nhiều kiến thức về C.

Nếu sử dụng Phalcon bạn sẽ tận dụng được những lợi thế về tốc độ, còn nếu dùng Laravel, chắc chắn bạn sẽ phải thêm nhiều module, tasks khiến ứng dụng trở nên nặng nề, chậm chạp.

Phalcon chiến thắng !

Laravel: 8

Phalcon: 7

Cộng đồng

Điều gì bạn sẽ làm nếu gặp lỗi khi viết một ứng dụng? Khả năng cao bạn sẽ tìm kiếm trên Google và nhận được các câu trả lời trên StackOverflow, và đó là lý do mà một cộng đồng sử dụng Framework thực sự rất quan trọng. Với một cộng đồng lớn thì vấn đề của bạn sẽ trở nên đơn giản hơn nhiều.

Laravel chắc chắn có số lượng người dùng và một cộng đồng đông đảo hơn Phalcon. Do vậy, trong phần so sánh này, chiến thắng thuộc về Laravel

Laravel: 9

Phalcon: 7

Dễ sử dụng

Đây là một phần so sánh mà Laravel chiếm ưu thế. Laravel rất tốt cho lập trình viên để bắt đầu vì nó rất dễ dàng để học, và cung cấp nhiều chức năng, cách thức tiếp cập để code

Phalcon dành cho các lập trình viên có nhiều kinh nghiệm hơn, những người muốn hiểu rõ tận gốc cách thức vận hành, điều mà framework Laravel thường giấu đi để dễ dàng hơn cho người sử dụng.

Bởi vì chúng ta đang nói đến tính dễ sử dụng, rõ ràng là một chiến  thắng dành cho Laravel 

Laravel: 10

Phalcon: 7

Coding Style

Phần này mang tính chất góc nhìn cá nhân, và phụ thuộc vào từng lập trình viên, bởi vì tôi làm việc với Javascript hàng ngày, nên cảm thấy code style của nó khá gọn gàng. Phalcon đối với tôi cũng tương tự như vậy.

Phalcon gọn gàng và dễ hiểu hơn khi viết code, nếu ai đó nhìn vào lần đầu tiên. Các pattern của Phalcon cũng xúc tích hơn nhiều trong các file config cũng như các thành phần khác.

Điểm hạng mục này tôi dành cho Phalcon

Laravel: 10

Phalcon: 8

Triển khai

Điểm đánh giá cuối cùng là việc triển khai ứng dụng. Bước này đóng vai trò quan trọng nhất để phát triển một ứng dụng từ 0 đến 100%.

Laravel được hỗ trợ bởi hầu hết đến 90% các nhà cung cấp shared hosting, vì không yêu cầu nhiều đến cấu hình được cài đặt sẵn. Bạn chỉ cần tải lên Laravel, một vài nhà cung cấp có thể có các công cụ nâng cao như SSH để dễ hơn, tuy nhiên thực sự bạn cũng không cần nhiều.

Triển khai Phalcon thực sự không khó khăn hơn nhiều Laravel, thậm chí còn dễ hơn nếu như nhà cung cấp hosting đã cài đặt sẵn Phalcon extension trên máy chủ. Còn nếu không, bạn sẽ phải tìm đến VPS hoặc Dedicated Server để triển khai cài đặt hoặc compile.

Nói chung, triển khai Phalcon sẽ mất nhiều thời gian, cũng như chi phí so với ứng dụng Laravel.

Vì vậy tôi chấm điểm cho Laravel ở hạng mục này.

Laravel: 11

Phalcon: 8

Front-end Assets

Phần này thực ra không liên quan nhiều đến từng framework, tuy nhiên vẫn đáng để được nói đến.

Laravel cung cấp Laravel Mix cho phép đóng gói tài nguyên sử dụng Webpack, trong khi Phalcon không có công cụ nào tương tự.

Laravel cũng hỗ trợ Vue và React cùng với Bootstrap, Phalcon thì không :)

Thêm 1 điểm cộng nữa cho Laravel

Tổng kết

Kết quả cuối cùng:

Laravel: 11

Phalcon: 8

Kết quả chỉ ra Laravel là người chiến thắng, tuy nhiên không quá xa so với Phalcon. Tôi sẽ vẫn tiếp tục sử dụng Phalcon nếu làm rõ được khâu triển khai, vì lợi thế về tốc độ hơn hẳn rất nhiều framework.

Các bạn lưu ý đây là ý kiến cá nhân, đối với bạn có thể khác và tôi hoàn toàn tôn trọng ý kiến tất cả mọi người. Hãy cho tôi biết kinh nghiệm bằng cách gửi bình luận cuối bài viết