Công nghệ phát triển web luôn luôn thay đổi. Các lập trình viên server-side đang có một sự bối rối trong việc chọn một ngôn ngữ có trọng lượng và đã tồn tại lâu dài như Java, C, và Perl cho những người mới hơn, hay các ngôn ngữ tập trung vào web như Ruby, Clojure và Go. Việc bạn lựa chọn ngôn ngữ nào hiếm khi quan trọng, mà điều quan trọng là ứng dụng của bạn có thể làm việc tốt hay không.
Nhưng làm thế nào để những người mới bước vào lĩnh vực phát triển web có thể đưa ra một sự lựa chọn chuẩn xác?
Tôi hy vọng mình không bắt đầu một cuộc thánh chiến, nhưng tôi sẽ tiến hành so sánh những ưu nhược điểm của 2 công nghệ này với nhau:
PHP
PHP được tạo ra bởi Rasmus Lerdorf vào năm 1994. Nó được xử lý bởi một trình thông dịch thường được cài đặt như là một mô-đun trong một máy chủ web như Apache hoặc Nginx.
Code PHP có thể xen kẽ được với HTML. Đó không phải là cách viết code tốt nhất, nhưng những người mới tiếp xúc với ngôn ngữ này có thể tạo ra những phần code hữu ích một cách rất nhanh chóng. Điều đó góp phần vào sự phổ biến của ngôn ngữ này, và PHP hiện đang được sử dụng ở hơn 80% máy chủ web trên thế giới. Kết quả đó có được nhờ một phần không nhỏ bởi WordPress – đó là một hệ quản trị nội dung PHP được sử dụng khoảng 1/4 trong số tất cả các trang web.
Node.js
Node.js được tạo ra bởi Ryan Dahl vào năm 2009. Nó sử dụng
engine V8 JavaScript của Google để tạo ra sức mạnh cho client-side code trong trình duyệt web Chrome. Nền tảng này có các thư viện built-in để xử lý các web request và response – bạn không cần một máy chủ web riêng biệt hoặc những thành phần phụ thuộc khác.
Node.js còn tương đối mới nhưng đã nhanh chóng thu hút được sự quan tâm của cộng đồng. Nó được sử dụng bởi các công ty như Microsoft, Yahoo, LinkedIn và PayPal.
C#, Java, Ruby, Python, Perl, Erlang, C++, Go, Dart, Scala, Haskell, v.v… ở đâu?
Một bài viết mà đi so sánh tất cả các công nghệ sẽ rất dài. Liệu bạn sẽ dành thời gian để đọc nó? Bạn có nghĩ rằng có một lập trình viên nào đó thành thạo tất cả chúng? Bởi vậy tôi sẽ giới hạn lại bài so sánh này chỉ giữa PHP và Node.js vì:
- Đó là một so sánh tốt. Chúng đều là mã nguồn mở, chủ yếu nhằm vào phát triển web và áp dụng cho các dự án tương tự.
- PHP là một ngôn ngữ được hình thành đã lâu nhưng Node.js là một công nghệ mới nổi hiện đang nhận được nhiều sự quan tâm. Liệu các lập trình viên PHP có nên tin vào sự thổi phồng về Node.js? Họ có nên chuyển đổi sang công nghệ mới này?
- Tôi biết là mình rất yêu thích những ngôn ngữ lập trình này. Tôi đã phát triển với PHP và JavaScript kể từ cuối những năm 1990, và một vài năm kinh nghiệm Node.js. Tôi cũng đã học các công nghệ khác, nhưng không thể làm cho chúng được công bằng trong bài đánh giá này.
Bên cạnh đó, việc tôi so sánh bao nhiêu ngôn ngữ là không quan trọng. Một người nào đó, ở một nơi nào đó, sẽ phàn nàn rằng tôi đã không đưa vào ngôn ngữ yêu thích của họ!
Về mục đích của cuộc so găng
Các lập trình viên dành nhiều năm để mài giũa kỹ năng của họ. Một số người có ngôn ngữ “ruột” của mình, nhưng những người đã đạt đến cấp độ Ninja thường lựa chọn công nghệ dựa trên rất nhiều yếu tố. Điều đó cũng mang tính chủ quan; bạn thường sẽ bị thúc đẩy và bảo vệ quyết định công nghệ của mình.
Điều đó nói lên rằng, bài viết này không phải sẽ đưa ra lời khuyên kiểu “hãy sử dụng bất cứ công nghệ nào phù hợp với bạn, anh bạn thân mến ạ”. Tôi sẽ đưa ra các lời khuyên dựa trên những kinh nghiệm, nhu cầu và thành kiến của bản thân mình. Bạn sẽ đồng ý với một số điểm và không đồng ý với những điểm khác; đó mới là điều tuyệt vời – những ý kiến của bạn sẽ giúp ích cho những người khác đưa ra được những quyết định chính xác hơn.
Phương pháp đánh giá
PHP và Node.js sẽ được so sánh trong mười hiệp đấu. Mỗi hiệp đấu là một thách thức phát triển chung có thể được áp dụng cho bất kỳ công nghệ web nào. Chúng ta sẽ không đi quá sâu vào chi tiết; rất ít người sẽ quan tâm đến những giá trị của bộ sinh số ngẫu nhiên (random number generator) hoặc các thuật toán sắp xếp mảng.
Kẻ chiến thắng chung cuộc sẽ là công nghệ chiến thắng ở nhiều hiệp đấu nhất. Bạn đã sẵn sàng chưa? Hãy để cho trận đấu bắt đầu nhé!…
Hiệp 1: Bắt đầu
Làm thế nào để xây dựng một trang web xuất ra chữ “Hello World” nhanh chóng? Trong PHP:
<?php
echo 'Hello World!';
?>
Phần code này có thể được đặt ở bất kỳ tập tin nào được thông dịch bởi engine PHP – thường với phần mở rộng .php. Nhập URL đã ánh xạ tới tập tin đó trong trình duyệt của bạn và như vậy là đã hoàn thành.
Phải thừa nhận rằng, mọi thứ không chỉ đơn giản như vậy. Phần code đó sẽ chỉ chạy thông qua một máy chủ web với PHP đã được cài đặt. (PHP có một built-in server, mặc dù vậy nhưng bạn nên sử dụng một cái gì đó mạnh mẽ hơn). Hầu hết các HĐH đều cung cấp các phần mềm máy chủ như IIS trên Windows hoặc Apache trên máy Mac và Linux, mặc dù chúng cần phải được kích hoạt và cấu hình. Nếu muốn đơn giản hơn bạn có thể sử dụng một pre-built set-up như XAMPP hoặc một virtual OS image (như Vagrant). Thậm chí dễ dàng hơn: chỉ việc tải các tập tin của bạn lên bất kỳ máy chủ web nào cũng được.
So sánh với ở trên, việc cài đặt Node.js rất là dễ dàng. Bạn có thể tải về bản cài đặt hoặc sử dụng một trình quản lý gói. Sau đó, hãy tạo ra trang web Hello World trong file hello.js:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World!');
}).listen(3000, '127.0.0.1');
Bạn cần khởi động ứng dụng đó từ terminal với lệnh node hello.js trước khi bạn có thể xem kết quả tại địa chỉ http://127.0.0.1:3000/ trong trình duyệt của bạn. Chúng ta đã tạo ra một máy chủ web nhỏ trong 5 dòng code, điều này thật tuyệt vời, nhưng ngay cả những người có nhiều kinh nghiệm trong lập trình client- side JavaScript cũng sẽ phải khá vất vả để hiểu nó.
PHP có khái niệm đơn giản hơn và chiến thắng ở hiệp này. Những người biết một vài câu lệnh PHP có thể viết ra một cái gì đó hữu ích. Nó phụ thuộc nhiều vào các phần mềm, nhưng khái niệm của PHP dễ hiểu hơn đối với các lập trình viên mới.
Có một khoảng cách khá lớn giữa việc biết một chút về JavaScript và việc lập trình các ứng dụng Node.js. Các cách tiếp cận phát triển của nó khác với hầu hết các công nghệ phía máy chủ khác, và bạn cần phải hiểu một số khái niệm khá phức tạp như các function closures và callback.
Hiệp 2: Sự giúp đỡ và hỗ trợ
Bạn sẽ không thể tiến xa được nếu không có một số hỗ trợ phát triển từ các tài liệu chính thức và các tài nguyên như các khóa học, các diễn đàn và StackOverflow. PHP chiến thắng vòng này một cách dễ dàng; nó có một hướng dẫn tuyệt vời và những kiến thức hỏi đáp Q&A tích lũy trong 20 năm vừa qua. Dù bạn đang làm gì, thì trước đây một người nào đó đã gặp phải một vấn đề tương tự giống như bạn.
Node.js có tài liệu rất tốt nhưng vì nó còn khá mới và có ít sự trợ giúp. JavaScript cũng có tuổi đời như PHP, nhưng phần lớn các trợ giúp chỉ liên quan đến phát triển trong trình duyệt. Điều đó không giúp ích được gì nhiều.
Hiệp 3: Cú pháp ngôn ngữ
Các câu lệnh và cấu trúc có hợp lý và dễ sử dụng không?
Không giống như một số ngôn ngữ và các framework khác, PHP không bắt buộc bạn phải làm việc một cách chính xác theo hướng nào đó. Bạn có thể bắt đầu với một chương trình bằng vài dòng code, bổ sung thêm các function, viết code theo lối đơn giản như các đối tượng trong PHP4 và cuối cùng viết các ứng dụng đẹp mắt theo hướng đối tượng MVC trong các phiên bản PHP5+. Code của bạn có thể rất lộn xộn, nhưng nó sẽ làm việc và phát triển cùng với sự hiểu biết của bạn.
Cú pháp PHP có thể thay đổi giữa các phiên bản, nhưng tính tương thích ngược nói chung là rất tốt. Thật không may, điều này dẫn đến một vấn đề: PHP sẽ trở thành một mớ hỗn độn. Ví dụ, làm thế nào để đếm số ký tự trong một chuỗi? Bạn sử dụng count? str_len? strlen? mb_strlen? Có hàng trăm function và chúng được đặt tên không nhất quán. Bạn hãy thử viết một vài dòng code mà không tham khảo hướng dẫn mà xem.
JavaScript tương đối súc tích hơn, với một vài chục câu lệnh cốt lõi. Điều đó nói rằng, cú pháp của nó thu hút các nhà phát triển, bởi vì mô hình đối tượng nguyên mẫu của nó có vẻ quen thuộc nhưng không hẳn là như vậy. Bạn cũng sẽ tìm thấy những lời phàn nàn về các lỗi toán học (0.1 + 0.2 != 0.3) và sự nhầm lẫn về kiểu khi thực hiện chuyển đổi ('4' + 2 == '42' và '4' - 2 == 2) – nhưng những tình huống này hiếm khi gây ra vấn đề, và tất cả các ngôn ngữ khác đều bị những vấn đề tương tự.
PHP có những lợi ích của nó, nhưng tôi trao phần thưởng chiến thắng vòng 3 đến Node.js. Vì những lý do sau đây:
- JavaScript vẫn ngôn ngữ bị hiểu sai nhiều nhất thế giới – nhưng một khi các khái niệm được làm sáng tỏ, nó khiến cho các ngôn ngữ khác có vẻ cồng kềnh.
- Code JavaScript ngắn gọn hơn so với PHP. Ví dụ, bạn sẽ không cần phải dịch sang/từ JSON và – may mắn thay – cả UTF-8 nữa.
- Các lập trình viên full-stack có thể sử dụng JavaScript trên cả máy khách và máy chủ. Bộ não của bạn sẽ không cần phải chuyển đổi chế độ.
- Việc hiểu JavaScript làm cho bạn muốn sử dụng nó nhiều hơn. Tôi không thể nói như vậy đối với PHP.
Hiệp 4: Công cụ phát triển
Cả hai công nghệ này có rất nhiều editor, IDE, debugger, validator và các công cụ khác. Tôi định xem đây là một hiệp đấu hòa nhưng có một công cụ mà khiến Node.js giành chiến thắng, đó là:
npm – Node Package Manager. npm cho phép bạn cài đặt và quản lý các dependencies, thiết lập các biến cấu hình, định nghĩa các script và nhiều hơn thế nữa.
Dự án Composer của PHP chịu ảnh hưởng của npm và là tốt hơn ở một số khía cạnh. Tuy nhiên, nó không được cung cấp với PHP theo mặc định, có một active repository nhỏ hơn và có ít ảnh hưởng trong cộng đồng.
npm chịu trách nhiệm một phần cho sự phát triển của các công cụ xây dựng như Grunt và Gulp đã cách mạng hóa việc phát triển ứng dụng. Các lập trình viên PHP có lẽ sẽ muốn/cần cài đặt Node.js tại một số điểm. Điều ngược lại là không đúng.
Hiệp 5: Môi trường
Các công nghệ này có thể được sử dụng và triển khai ở đâu? Những nền tảng và hệ sinh thái nào được hỗ trợ? Các nhà phát triển web thường cần tạo ra các ứng dụng mà không bị giới hạn chỉ cho trang web đó, ví dụ như các công cụ xây dựng, công cụ chuyển đổi, script chuyển đổi cơ sở dữ liệu, v.v…
Có nhiều cách để sử dụng PHP trong việc phát triển các ứng dụng desktop và command-line. Nhưng bạn sẽ không sử dụng chúng. Bởi vì, PHP là một công nghệ phát triển phía server. Nó là tốt nhất khi làm công việc đó và hiếm khi vượt ra ngoài những ranh giới này.
Một vài năm trước đây, JavaScript thường bị coi là nhiều hạn chế hơn. Có một vài công nghệ râu ria khác nhưng chức năng chính của nó là chạy trong các trình duyệt. Node.js đã thay đổi nhận thức đó và đã có một sự bùng nổ các dự án JavaScript. Bạn có thể sử dụng JavaScript ở khắp mọi nơi – trong trình duyệt, trên máy chủ, thiết bị đầu cuối, desktop và thậm chí là cả các hệ thống nhúng. Node.js đã khiến cho JavaScript trở nên phổ biến.
Hiệp 6: Tích hợp
Các công nghệ phát triển sẽ bị hạn chế trừ khi chúng có thể tích hợp với các cơ sở dữ liệu và driver. PHP rất mạnh trong lĩnh vực này. Nó đã được phát triển trong nhiều năm và các hệ thống mở rộng của nó cho phép truyền thông trực tiếp với một loạt các API phổ biến hoặc ít người biết đến.
Node.js đang phát triển rất nhanh, nhưng bạn có thể phải rất vất vả để tìm thấy các thành phần tích hợp đủ độ chín cho các công nghệ cũ và ít phổ biến hơn.
Hiệp 7: Hosting và triển khai
Việc triển khai một ứng dụng mới của bạn lên một máy chủ web thì cái nào dễ hơn? Rõ ràng kẻ chiến thắng là PHP. Hãy lựa chọn ngẫu nhiên một vài công ty web hosting và liên hệ với họ, bạn sẽ phát hiện ra phần lớn họ đều hỗ trợ PHP. Bạn sẽ có thể được khuyến mãi thêm MySQL với một mức giá hời. PHP được xem là dễ dàng hơn để thử nghiệm và có thể giúp giảm thiểu được nhiều rủi ro.
Node.js là một sinh vật hoàn toàn khác và các ứng dụng server-side có thể hoạt động một cách lâu dài. Bạn sẽ cần một real/virtual/cloud hoặc môi trường máy chủ chuyên biệt, lý tưởng với truy cập SSH root. Đó là một yêu cầu quá cao cho một số nhà cung cấp, đặc biệt là trên shared hosting, nơi bạn có thể làm sập toàn bộ hệ thống.
Node.js hosting sẽ trở nên đơn giản hơn, nhưng tôi nghi ngờ rằng nó sẽ chẳng bao giờ được dễ dàng như việc dùng FTP tải lên một vài tập tin PHP.
Hiệp 8: Hiệu suất
PHP không quá nặng nề và có những dự án và các tùy chọn làm cho nó nhanh hơn. Ngay cả các nhà phát triển PHP đòi hỏi khắt khe nhất cũng hiếm khi lo lắng về tốc độ, nhưng hiệu suất của Node.js nói chung là tốt hơn. Tất nhiên, hiệu suất phần lớn là kết quả của kinh nghiệm và sự chăm sóc được thực hiện bởi đội ngũ phát triển, nhưng Node.js có khá nhiều ưu điểm…
Ít dependencies hơn
Tất cả các request tới một ứng dụng PHP phải được định tuyến thông qua một máy chủ web rồi trình thông dịch PHP mới bắt đầu chạy đoạn code đó. Node.js không cần quá nhiều các dependencies, trong khi bạn gần như chắc chắn sẽ sử dụng một server framework như Express, nó khá nhẹ và là một phần trong ứng dụng của bạn.
Trình thông dịch nhỏ hơn và nhanh hơn
Node.js nhỏ hơn và lẹ hơn so với trình thông dịch PHP. Nó ít bị cản trở bởi di sản ngôn ngữ hỗ trợ và Google đã đầu tư rất lớn để nâng cao hiệu suất của engine V8.
Các ứng dụng là Permanently On
PHP tuân theo mô hình client-server điển hình. Mọi page request khởi tạo ứng dụng của bạn; bạn nạp các thông số cấu hình, kết nối với một cơ sở dữ liệu, lấy thông tin và xuất ra dạng HTML. Một ứng dụng Node.js chạy vĩnh viễn và nó chỉ cần khởi tạo một lần duy nhất. Ví dụ, bạn có thể tạo ra một đối tượng kết nối cơ sở dữ liệu duy nhất và được tái sử dụng bởi tất cả mọi người trong mọi request. Phải thừa nhận rằng, có nhiều cách để làm điều tương tự trong PHP bằng cách sử dụng các hệ thống như Memcached nhưng nó không phải là một tính năng chuẩn của ngôn ngữ này.
Một Event-driven, Non-Blocking I/O
PHP và các ngôn ngữ phía máy chủ khác sử dụng một mô hình thực thi blocking rõ ràng. Khi bạn phát ra một lệnh như lấy thông tin từ một cơ sở dữ liệu, lệnh đó sẽ thực hiện hoàn thành trước khi tiến hành các câu lệnh tiếp theo. Còn Node.js sẽ không chờ đợi. Thay vào đó, bạn cung cấp một callback function sẽ được thực thi một khi hành động đó hoàn thành, ví dụ:
// fetch records from a NoSQL database
DB.collection('test').find({}).toArray(process);
console.log('finished');
// process database information
function process(err, recs) {
if (!err) {
console.log(recs.length + ' records returned');
}
}
Trong ví dụ này, cửa sổ console sẽ xuất ra dòng chữ ‘finished’ trước ‘N records returned’ bởi vì function process được gọi khi tất cả dữ liệu đã được lấy ra. Nói cách khác, trình thông dịch được tự do làm việc khác trong khi những tiến trình khác đang bận rộn.
Lưu ý rằng có nhiều tình huống phức tạp và có những sự khác biệt:
- Node.js/JavaScript chạy trên một thread duy nhất, trong khi hầu hết các máy chủ web là đa luồng (multi-threaded) và xử lý các yêu cầu đồng thời.
- Các tiến trình JavaScript chạy quá lâu cho một người dùng sẽ cản trở phần code chạy cho tất cả những người sử dụng khác, trừ khi bạn chia ra nhiều tác vụ hoặc sử dụng Web Workers.
- Việc benchmark tốc độ là chủ quan và thiếu sót; bạn sẽ tìm thấy các ví dụ mà Node.js đánh bại PHP và các ví dụ ngược lại là PHP đánh bại Node.js. Các nhà phát triển chuyên nghiệp luôn thử nghiệm bất cứ điều gì họ tin tưởng!
- Việc viết code bất đồng bộ hướng sự kiện (asynchronous event-driven) là phức tạp và phải chịu đựng những thách thức riêng của nó.
Tôi chỉ có thể đi từ kinh nghiệm bản thân: ứng dụng Node.js của tôi là nhanh hơn đáng kể so với ứng dụng PHP tương đương. Trải nghiệm của bạn có thể không giống như vậy nhưng bạn sẽ chẳng bao giờ biết cho đến khi bạn thử nó.
Hiệp 9: Đam mê của lập trình viên
Điều này có thể được mở rộng thành mục tiêu “thách thức phát triển web nói chung” và nó là quan trọng. Một công nghệ là tốt hay xấu sẽ không quan trọng nếu bạn sợ viết code mỗi ngày.
Có một chút khó khăn để so sánh nhưng tương đối ít các nhà phát triển PHP có đam mê về ngôn ngữ này. Lần cuối cùng bạn đọc một bài viết về PHP hoặc thấy một bài thuyết trình làm say đắm khán giả là khi nào? Có lẽ tất cả mọi thứ đã được nói hết rồi? Có lẽ có quá ít sự bộc lộ? Có lẽ tôi tôi đã không tìm đúng chỗ? Có một số tính năng tốt đẹp trong phiên bản PHP7 sắp tới nhưng công nghệ này đã bị ngâm nước trong một vài năm. Điều đó nói lên rằng, một số nhà phát triển PHP đã trách móc ngôn ngữ này.
JavaScript góp phần chia nhỏ cộng đồng. Có những người yêu thích nó và những người ghét nó; một số nhà phát triển thuộc loại “ba phải” không đứng về phe nào cả. Tuy nhiên, những phản hồi về Node.js phần lớn là tích cực và công nghệ này đang cưỡi trên những ngọn sóng. Điều này một phần là vì nó mới và những lời khen ngợi cũng không thể kéo dài mãi, nhưng giờ đây Node.js sẽ thắng hiệp đấu này.
Hiệp 10: Tương lai
Việc bạn sử dụng ngôn ngữ server-side nào không đặc biệt quan trọng; nó sẽ tiếp tục làm việc ngay cả khi dự án phát triển nó bị hủy (ví dụ như ColdFusion!). Cách sử dụng có thể khác nhưng nhiều người vẫn tiếp tục sử dụng PHP. Người ta đánh cược vào sự an toàn của nó và hoàn toàn yên tâm để tìm kiếm sự hỗ trợ trong vòng 20 năm nữa.
Sự đi lên của Node.js là như diều gặp gió. Nó cung cấp một phương pháp tiếp cận phát triển hiện đại, sử dụng các cú pháp tương tự như phát triển phía client-side và hỗ trợ các tính năng HTML5 mang tính cách mạng như web sockets và các sự kiện server-sent. Hiện nay đã xảy ra một số nhầm lẫn về việc phân nhánh của ngôn ngữ này, nhưng cộng đồng sử dụng nó vẫn tiếp tục tăng lên theo hàm số mũ.
Node.js chắc chắn sẽ ăn vào thị phần của PHP nhưng tôi ngờ rằng nó thậm chí sẽ vượt qua. Cả hai công nghệ này đều có một tương lai tươi sáng. Tôi tuyên bố hiệp đấu này hòa.
Chiến thắng chung cuộc
Tỷ số cuối cùng: Node.js chiến thắng ở 5 hiệp đấu, PHP chiến thắng 4 hiệp và có một hiệp đấu hòa. Kết quả là gần hơn với mong đợi của tôi và có thể có một trong hai cách.
Node.js khá khó học và không phải là lý tưởng cho các nhà phát triển web mới vào nghề nhưng nó chiến thắng trong trận đấu này. Một chiến thắng rất xứng đáng. Nếu bạn là một lập trình viên JavaScript có năng lực và đã yêu quý ngôn ngữ này, thì Node.js không làm bạn thất vọng. Nó mang lại cảm giác tươi mới và cung cấp một kinh nghiệm phát triển web phóng khoáng – nhưng bạn sẽ không bỏ quên PHP.
Và đừng coi thường nó. PHP còn sống và có ít lý do để nhảy trên con thuyền Node.js chỉ vì trông nó nhanh hơn, mới hơn, hay hợp thời hơn. PHP là dễ học hơn và hỗ trợ kỹ thuật lập trình chuyên nghiệp một cách hiệu quả. Sự trợ giúp có ở khắp mọi nơi và việc triển khai nó là khá đơn giản. Ngay cả các nhà phát triển “ruột” của Node.js cũng nên xem xét đến PHP cho các trang web và các ứng dụng đơn giản.
Lời khuyên của tôi là: hãy đánh giá các lựa chọn và chọn một ngôn ngữ lập trình dựa trên yêu cầu của bạn. Điều đó sẽ thực tế hơn nhiều so với việc dựa trên các bài viết đấu đá như thế này!