Caution: You are browsing the legacy 1.x part of this website.
This version of symfony is not maintained anymore. If some of your projects still use this version, consider upgrading.

Master Symfony fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
training.sensiolabs.com

Discover SensioLabs' Professional Business Solutions

Peruse our complete Symfony & PHP solutions catalog for your web development needs.
sensiolabs.com
Blackfire Profiler Fire up your PHP Apps Performance

PHP Project Quality Done Right
Jobeet

Giới thiệu

Framework symfony là dự án mã nguồn mở cách đây 3 năm và đã trở thành một trong những frameworks PHP phổ biến nhất nhờ tính năng tuyệt vời và tài liệu phong phú.

Tháng 12-2005, sau khi symfony ra phiên bản đầu tiên, chúng tôi đã ra mắt "Askeet tutorial", gồm 24 bài hướng dẫn, được đưa lên từng ngày từ 1/12 đến giáng sinh.

Hướng dẫn này là một tài liệu hữu ích đối với những người mới bắt đầu làm quen với symfony. Rất nhiều lập trình viên thích thú với askeet, và nhiều công ty vẫn dùng askeet làm tài liệu đào tạo.

Chúng ta vừa chào đón symfony 1.2 và askeet tutorial trở nên lạc hậu. Vì thế chúng ta cần một loạt bài hướng dẫn mới.

Chào mừng đến với Jobeet, loạt bài hướng dẫn của năm 2008!

Thử thách

Đúng vậy, chúng tôi lại thực hiện nó. Mỗi ngày, kể cả cuối tuần, một bài hướng dẫn mới sẽ được đưa lên. Mỗi bài hướng dẫn sẽ mất khoảng một giờ để thực hành, và là cơ hội để học symfony bằng cách code một website thực sự, từ đầu đến cuối.

1 giờ/1 bài hướng dẫn x 24 bài hướng dẫn = 1 ngày, đó chính là khoảng thời gian mà chúng tôi nghĩ một lập trình viên cần để học cơ bản về symfony. Mỗi ngày, các tính năng mới sẽ được thêm vào ứng dụng, đồng thời các chức năng mới của symfony cũng được giới thiệu.

Với askeet, ngày thứ 21 là "get-a-symfony-guru-for-a-day". Chúng tôi không có kế hoạch cho ngày này, cộng đồng sẽ đề xuất một tính năng để thêm vào askeet. Và cộng đồng quyết định chúng ta cần một search engine cho ứng dụng. Và chúng tôi đã làm nó.

Với Jobeet, chúng tôi dự định ngày thứ 21 sẽ là "design day". Sau ngày thứ 4, bạn sẽ có tất cả thông tin cần thiết về HTML và CSS để bắt đầu design cho website Jobeet. Vì vậy, nếu bạn là designer, hoặc công ty bạn có bộ phận về design, bạn có thể đóng góp. Vào ngày thứ 21, chúng tôi sẽ tổ chức bầu chọn và cộng đồng sẽ chọn giao diện chính thức cho Jobeet. Tất nhiên, nếu được chọn bạn sẽ nhận được thẻ thanh toán và cả sự nổi tiếng!

Sự khác biệt của hướng dẫn này

Hãy nhớ lại những ngày còn PHP4. Ah, la Belle Epoque! PHP là 1 trong những ngôn ngữ đầu tiên có mục đích chính là web và là một trong những ngôn ngữ dễ học nhất.

Nhưng công nghệ web phát triển rất nhanh, người lập trình web cần luôn cập nhật những công cụ và công nghệ mới. Cách tốt nhất để học là đọc blog, tutorial, & ebook. Chúng tôi đã đọc rất nhiều, với nhiều ngôn ngữ khác nhau PHP, Python, Java, Ruby, Perl...

Chắc bạn thường gặp những cảnh báo như:

"Với một ứng dụng thực sự, đừng quên kiểm tra sự hợp lệ (validation) và điều khiển lỗi (proper error handling)."

hoặc

"Security is left as an exercise to the reader."

hoặc

"Bạn cần phải viết tests."

Những thứ đó cũng quan trọng như là code vậy. Không có nó, mã nguồn có thể chạy không đúng như dự định. Thật là tệ! Tại sao vậy? Bởi vì security, validation, error handling, & test giúp code của bạn trở nên đúng đắn.

Trong hướng dẫn này, bạn sẽ không bao giờ phải thấy những câu như chúng ta phải viết tests, kiểm soát lỗi, validation code, mà vẫn đảm bảo rằng ứng dụng của chúng ta hoàn toàn bảo mật. Đó là bởi vì symfony không chỉ để viết code, mà còn là môi trường tốt nhất để phát triển các ứng dụng chuyên nghiệp. Symfony cung cấp tất cả các công cụ cần thiết để thực hiện những việc này mà không cần phải viết nhiều code.

Validation, error handling, security, và tests là những ưu tiên hàng đầu trong symfony. Đó là một trong những lý do chúng ta sử dụng framework trong một dự án thực tế.

Toàn bộ mã nguồn trong hướng dẫn này bạn có thể sử dụng trong dự án thực tế. Bạn có thể thoải mái sử dụng một phần hoặc toàn bộ mã nguồn.

Dự án

Ứng dụng được thiết kế trên symfony. Mục đích để chứng tỏ rằng symfony có thể sử dụng để phát triển một ứng dụng chuyên nghiệp một cách dễ dàng và ít tốn công sức.

Hôm nay, nội dung của dự án sẽ được bí mật. Chúng ta chỉ biết tên của dự án là: Jobeet.

Công việc hôm nay?

24 giờ là đủ để phát triển 1 ứng dụng với symfony, hôm nay chúng ta sẽ không viết dòng code PHP nào. Tuy không viết code, nhưng bạn sẽ bắt đầu hiểu lợi ích của việc sử dụng một framework như symfony, bằng cách khởi tạo một project mới.

Mục tiêu của ngày hôm nay là cài đặt môi trường phát triển và hiển thị một trang của ứng dụng trên trình duyệt web. Công việc bao gồm: cài đặt , khởi tạo một ứng dụng, và cấu hình web server.

Yêu cầu

Trước tiên, bạn phải có một web server (Apache chẳng hạn), một hệ quản trị cơ sở dữ liệu (MySQL, PostgreSQL, hoặc SQLite), và PHP 5.2.4 trở lên.

Chúng ta sẽ sử dụng dòng lệnh rất nhiều, tốt nhất là sử dụng hệ điều hành họ Unix, nhưng nếu bạn dùng Windows, bạn cần gõ các lệnh từ cửa sổ cmd.

note

Có thể sử dụng các lệnh của Unix trên môi trường Windows. Nếu bạn muốn sử dụng các công cụ như tar, gzip, hay grep trên Windows bạn có thể cài đặt Cygwin. Tài liệu hướng dẫn không nhiều, hướng dẫn cài đặt bạn có thể xem ở đây. Bạn cũng có thể thử khám phá Windows Services for Unix.

Hướng dẫn này chủ yếu đề cập đến framework symfony, chúng tôi giả định rằng bạn đã có hiểu biết về PHP 5 và lập trình hướng đối tượng.

Cài đặt Symfony

Đầu tiên, tạo một thư mục để chứa các file của project Jobeet:

$ mkdir -p /home/sfprojects/jobeet
$ cd /home/sfprojects/jobeet

Ở Windows:

c:\> mkdir c:\development\sfprojects\jobeet
c:\> cd c:\development\sfprojects\jobeet

note

Người dùng Windows nên chạy symfony và khởi tạo project ở thư mục không chứa dấu cách. Tránh sử dụng thư mục Documents and Settings , hay My Documents.

Tạo thư mục để chứa thư viện symfony:

$ mkdir -p lib/vendor

Để cài đặt symfony, download file nén trên trang web symfony. Hướng dẫn này được viết trên symfony 1.2, hãy download phiên bản mới nhất của symfony 1.2.

Ở mục "Source Download", bạn sẽ tìm thấy file nén dạng .tgz hoặc .zip. Download file này và copy vào thư mục vừa tạo lib/vendor, sau đó giải nén:

$ cd lib/vendor
$ tar zxpf symfony-1.2-latest.tgz
$ mv symfony-1.2.0 symfony

Ở Windows, việc giải nén file zip có thể làm từ menu chuột phải. Sau khi đổi tên thư mục thành symfony, chúng ta có thư mục như sau c:\development\sfprojects\jobeet\lib\vendor\symfony.

Do cấu hình PHP có thể khác nhau, chúng ta cần kiểm tra lại cấu hình PHP để chắc chắn các yêu cầu tối thiểu để chạy symfony được đáp ứng. Chạy đoạn script kiểm tra từ dòng lệnh:

$ cd ../..
$ php lib/vendor/symfony/data/bin/check_configuration.php

Nếu có vấn đề, màn hình sẽ đưa ra gợi ý và cách sửa. Bạn có chạy file kiểm tra cấu hình PHP từ trình duyệt. Copy file vào thư mục gốc của web server và truy cập từ trình duyệt. Đừng quên xóa file đi sau khi đã kiểm tra xong.

Configuration check

Nếu đoạn script không hiện thông báo lỗi, hãy kiểm tra để chắc rằng symfony được cài thành công bằng cách sử dụng lệnh của symfony để xem phiên bản (chữ cái V viết hoa):

$ php lib/vendor/symfony/data/bin/symfony -V

Ở Windows:

c:\> cd ..\..
c:\> php lib\vendor\symfony\data\bin\symfony -V

Nếu bạn muốn xem tất cả các lệnh của symfony, gõ symfony để xem danh sách các lệnh:

$ php lib/vendor/symfony/data/bin/symfony

Ở Windows:

c:\> php lib\vendor\symfony\data\bin\symfony

Các lệnh của symfony rất hữu dụng. Nó cung cấp rất nhiều công cụ giúp cho việc phát triển sản phẩm của bạn tiện lợi như xoá cache, tự động sinh code, ...

Cài đặt Project

Trong symfony, các application có chung một cơ sở dữ liệu (data model) được nhóm lại trong một project. Với project Jobeet, chúng ta có 2 application: frontend và backend.

Tạo Project

Từ thư mục jobeet, chạy lệnh generate:project để tạo 1 project symfony:

$ php lib/vendor/symfony/data/bin/symfony generate:project jobeet

Ở Windows:

c:\> php lib\vendor\symfony\data\bin\symfony generate:project jobeet

Lệnh generate:project tạo ra cấu trúc file và thư mục mặc định cần cho một project symfony:

Thư mục Mô tả
apps/ chứa các application của project
cache/ chứa các file cache tạo bởi framework
config/ chứa các file cấu hình
lib/ chứa các lớp và thư viện
log/ các file log của framework
plugins/ chứa các plugin được cài đặt
test/ chứa các file unit và functional test
web/ thư mục web root (xem bên dưới)

note

Tại sao symfony tạo ra quá nhiều file vậy? Một trong những lợi ích của việc sử dụng full-stack framework là chuẩn hoá sự phát triển của bạn. Nhờ cấu trúc file và thư mục thống nhất của symfony, bất kì lập trình viên nào có hiểu biết về symfony cũng có thể thực hiện công việc bảo trì cho bất kì dự án symfony nào. Sau một thời gian ngắn, anh ta đã có thể bắt đầu code, sửa lỗi, và thêm tính năng mới.

Lệnh generate:project cũng tạo một shortcut symfony ở thư mục ngoài cùng của project Jobeet để giảm số kí tự phải gõ trong lệnh.

Vì thế, từ bây giờ, thay vì gõ đầy đủ đường dẫn, chúng ta chỉ cần gõ symfony.

Tạo Application

Bây giờ, tạo application frontend bằng lệnh generate:app:

$ php symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret frontend

tip

Khi chạy lệnh symfony, người dùng Unix có thể thay thế toàn bộ đoạn 'php symfony' bằng './symfony'.

Ở Windows bạn có thể copy file 'symfony.bat' vào project của bạn và sử dụng 'symfony' thay vì 'php symfony':

c:\> copy lib\vendor\symfony\data\bin\symfony.bat .

Một lần nữa, lệnh generate:app tạo cấu trúc thư mục mặc định cần thiết cho một application nằm trong thư mục apps/frontend:

Thư mục Mô tả
config/ chứa các file cấu hình cho application
lib/ các lớp và thư viện của application
modules/ chứa mã nguồn của ứng dụng (MVC)
templates/ chứa các file template toàn cục

tip

Tất cả các lệnh của symfony phải chạy dưới thư mục gốc của project trừ khi có chỉ dẫn khác.

Khi gọi lệnh generate:app , chúng ta đã cung cấp hai lựa chọn liên quan đến bảo mật:

  • --escaping-strategy: cho phép output escaping để chống tấn công XSS
  • --csrf-secret: cho phép session tokens in form để chống tấn công CSRF

Nhờ 2 tham số này, chúng ta đã bảo vệ được ứng dụng của mình khỏi 2 lỗ hổng bảo mật phổ biến trên web.

note

Nếu bạn không biết về XSSCSRF, hãy dành vài phút để tìm hiểu về những lỗ hổng bảo mật này.

Đường dẫn symfony

Bạn có thể xem phiên bản symfony sử dụng trong dự án của bạn bằng cách gõ:

$ php symfony -V

Lệnh này cũng hiển thị đường dẫn đến thư mục cài đặt symfony, được sử dụng trong file config/ProjectConfiguration.class.php:

// config/ProjectConfiguration.class.php
require_once '/Users/fabien/work/symfony/dev/1.2/lib/autoload/sfCoreAutoload.class.php';

để cho thuận tiện, thay đường dẫn tuyệt đối bằng đường dẫn tương đối:

// config/ProjectConfiguration.class.php
require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';

Bây giờ, bạn có thể copy project Jobeet đến bất kì đâu, nó vẫn chạy được.

Môi trường

Trong thư mục web/ , bạn có thể thấy 2 file PHP: index.phpfrontend_dev.php. Những file này được gọi là front controllers: mọi yêu cầu đến ứng dụng đều thông qua chúng. Nhưng tại sao chúng ta có 2 file front controllers trong khi chúng ta chỉ có 1 ứng dụng?

Cả hai file đều gọi cùng một ứng dụng nhưng trong những môi trường khác nhau. Khi bạn phát triển một ứng dụng, trừ khi bạn phát triển trực tiếp sản phẩm trên server, bạn cần vài môi trường:

  • development environment: môi trường sử dụng bởi web developers để thêm các tính năng, sửa lỗi, ...
  • test environment: môi trường sử dụng cho các ứng dụng test tự động.
  • staging environment: môi trường sử dụng bởi customer để test ứng dụng và thông báo lỗi và các tính năng thiếu.
  • production environment: môi trường tương tác với end user.

Trong môi trường development, ứng dụng cần log tất cả các request để dễ dàng tìm lỗi, nó phải hiển thị exception trên trình duyệt, và hệ thống cache phải được tắt để có thể thấy thay đổi khi thay đổi code. Vì thế, môi trường development phải được cấu hình cho phù hợp với lập trình viên:

An exception in the dev environment

Ở môi trường production, ứng dụng phải hiển thị một thông báo lỗi thay vì hiển thị lỗi cụ thể của hệ thống, và tất nhiêu, cache phải được bật. Vì thế, môi trường production phải được cấu hình cho phù hợp.

An exception in the prod environment

Mỗi môi trường trong symfony có một tập các cấu hình riêng và symfony có sẵn 3 môi trường: dev, test, và prod.

Nếu bạn mở các file front controller, bạn sẽ thấy chúng chỉ khác nhau về cấu hình của môi trường:

// web/index.php
<?php
 
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
 
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

note

Tạo một môi trường mới trong symfony đơn giản là tạo một file front controller mới. Chúng ta sẽ xem cách thay đổi các cấu hình cho một môi trường ở các phần sau.

Cài đặt Web Server: cách tối

Trong phần trước, chúng ta đã tạo một thư mục để chứa project Jobeet. Nếu bạn tạo thư mục này dưới thư mục gốc của web server, bạn đã có thể truy cập vào project trên trình duyệt.

Thật là dễ dàng và không cần phải cấu hình gì cả! Tuy nhiên, hãy thử truy cập file config/databases.yml từ trình duyệt để hiểu tác hại của sự lười biếng này.

Không bao giờ được sử dụng cách cài đặt này trên server cho một sản phẩm thực sự và hãy đọc phần tiếp theo để biết cách cấu hình web server đúng đắn.

Cài đặt Web Server: cách bảo mật

Tốt nhất là chỉ đặt trong thư mục web root các file mà trình duyệt cần truy cập trực tiếp như stylesheets, JavaScripts, hoặc file ảnh. Mặc định, chúng tôi để những file này trong thư mục web của symfony project.

Nếu bạn xem trong thư mục này, bạn sẽ thấy vài thư mục con như css, images, js và 2 file front controller. File front controllers là file php duy nhất cần đặt trong thư mục web root. Tất cả các file PHP khác có thể ẩn đi đối với trình duyệt, để bảo mật cho ứng dụng.

Cấu hình Web Server

Bây giờ cần thay đổi cấu hình Apache để có thể truy cập project.

Mở file cấu hình httpd.conf và thêm vào cuối file:

# Be sure to only have this line once in your configuration
NameVirtualHost 127.0.0.1:8080

# This is the configuration for Jobeet
Listen 127.0.0.1:8080

<VirtualHost 127.0.0.1:8080>
  DocumentRoot "/home/sfprojects/jobeet/web"
  DirectoryIndex index.php
  <Directory "/home/sfprojects/jobeet/web">
    AllowOverride All
    Allow from All
  </Directory>

  Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf
  <Directory "/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

note

/sf cho phép bạn truy cập các file ảnh và javascript cần để hiển thị các trang mặc định của symfony và thanh web debug toolbar.

Ở Windows, bạn cần sửa dòng Alias thành:

Alias /sf "c:\development\sfprojects\jobeet\lib\vendor\symfony\data\web\sf"

/home/sfprojects/jobeet/web sẽ được thay thế bởi:

c:\development\sfprojects\jobeet\web

Cấu hình này giúp Apache lắng nghe cổng 8080 trên máy bạn, vì thế website Jobeet có thể được truy cập được theo URL:

http://localhost:8080/

Bạn có thể đổi 8080 thành bất kì số nào nhưng nên lớn hơn 1024 để chắc rằng cổng này chưa được sử dụng.

sidebar

Cấu hình để tạo một tên miền cho Jobeet

Nếu bạn có quyền administrator trên máy, tốt nhất là tạo một virtual hosts thay vì thêm một cổng mới mỗi khi bạn tạo một project mới. Thay vì tạo một cổng và Listen , hãy chọn một tên miền và thêm ServerName:

# This is the configuration for Jobeet
<VirtualHost 127.0.0.1:80>
  ServerName jobeet.localhost
  <!-- same configuration as before -->
</VirtualHost>

Tên miền jobeet.localhost phải được khai báo. Nếu bạn dùng Linux, bạn cần thêm vào trong file /etc/hosts . Nếu bạn dùng Windows XP, file này nằm trong thư mục C:\WINDOWS\system32\drivers\etc\.

Thêm dòng sau:

127.0.0.1         jobeet.localhost

Kiểm tra cấu hình

Khởi động lại Apache, và kiểm tra xem bạn có thể truy cập ứng dụng từ địa chỉ http://localhost:8080/index.php/, hoặc http://jobeet.localhost/index.php/ tùy vào cấu hình bạn chọn ở mục trước.

Congratulations

note

Nếu bạn có cài đặt module Apache mod_rewrite , bạn có thể bỏ đoạn /index.php/ trên URLs.

Bạn có thể truy cập ứng dụng trên môi trường development:

http://jobeet.localhost/frontend_dev.php/

Thanh web debug toolbar được hiển thị bên góc phải, bao gồm các biểu tượng nhỏ được cung cấp từ sf/ nếu bạn cấu hình đúng.

web debug toolbar

note

Cách cài đặt có khác chút nếu bạn chạy symfony trên IIS server ở Windows. Cách cấu hình có thể tìm ở hướng dẫn này.

Subversion

Tốt nhất là sử dụng một công cụ để quản lý phiên bản của mã nguồn khi phát triển một ứng dụng web. Nó cho phép chúng ta:

  • làm việc với sự tin cậy
  • chuyển lại phiên bản trước nếu sự thay đổi gây ra lỗi
  • cho phép nhiều người cùng làm việc trên một project
  • có thể truy cập tất cả các phiên bản của ứng dụng

Trong mục này, chúng tôi sẽ mô tả cách sử dụng Subversion với symfony. Nếu bạn sử dụng công cụ quản lý mã nguồn khác, nó cũng tương tự như những gì chúng tôi hướng dẫn với Subversion.

Chúng tôi giả sử rằng bạn có quyền truy cập Subversion server.

tip

Nếu bạn không có một Subversion server, bạn có thể tạo miễn phí trên Google Code hoặc gõ "free subversion repository" trên Google để có nhiều lựa chọn.

Đầu tiên, tạo một kho chứa mới cho project jobeet:

$ svnadmin create http://svn.example.com/jobeet
$ svn mkdir -m "created default directory structure" http://svn.example.com/jobeet/trunk http://svn.example.com/jobeet/tags http://svn.example.com/jobeet/branches

Sau đó, xóa các file trong thư mục cache/log/ vì chúng ta không muốn đưa nó lên kho chứa.

$ cd /home/sfprojects/jobeet
$ rm -rf cache/*
$ rm -rf log/*

Bây giờ, chúng ta chmod để chắc chắc rằng chúng ta có quyền ghi vào thư mục cache và logs để web server của bạn có thể ghi vào đó:

$ chmod 777 cache
$ chmod 777 log

Tiếp theo, đưa mã nguồn lên kho chứa:

$ svn import -m "made the initial import" . http://svn.example.com/jobeet/trunk

Chúng ta không bao giờ muốn commit những file trong thư mục cache//log , nên ta đưa nó vào danh sách cần bỏ qua:

$ svn propedit svn:ignore cache

Text editor mặc định để cấu hình SVN được mở. Subversion phải bỏ qua tất cả nội dung trong thư mục:

*

Lưu lại vào thoát.

Làm tương tự với thư mục log/:

$ svn propedit svn:ignore log

Và gõ:

*

Cuối cùng, commit những thay đổi lên kho chứa:

$ svn commit -m "added cache/ and log/ content in the ignore list"

tip

người dùng Windows có thể sử dụng TortoiseSVN client, một công cụ tuyệt vời để quản lý subversion.

Hẹn gặp lại ngày mai

Thời gian của hôm nay đã hết! Mặc dù chúng ta chưa thực sự bắt đầu với symfony, nhưng chúng ta đã cài đặt môi trường phát triển, chúng ta đã nói về web development best practices, và chúng ta đã sẵn sàng coding.

Ngày mai, chúng ta sẽ khám phá những yêu cầu của ứng dụng mà chúng ta sẽ thực hiện trong suốt hướng dẫn này.

note

Nếu bạn muốn xem mã nguồn của ngày hôm nay, và những ngày khác, bạn có thể lấy về từ kho chứa Jobeet SVN (http://svn.jobeet.org/propel/).

Ví dụ, bạn có thể lấy mã nguồn ngày hôm nay bằng cách checking out tag release_day_01:

  $ svn co http://svn.jobeet.org/propel/tags/release_day_01/ jobeet/