Thứ Năm, 16 tháng 7, 2009

Sử dụng CakePHP để viết web application

Giới thiệu về cakePHP

CakePHP là một framework cho php, mục đích của nó là cung cấp một framework cho người sử dụng php phát triển những ứng dụng web nhanh, mạnh mà không mất tính linh hoạt của nó. Việc viết web trở nên đơn giản và nhanh hơn rất nhiều so với cách viết truyền thông bằng việc dựa trên các thư viện, lớp có sẵn thêm vào đó nó cũng hổ trợ Ajax, Javascript và CSS. Và điều quan trọng là CakePHP is free.Trang chủ cakephp: http://cakephp.org. Để sử dụng nó, yêu cầu người làm phải biết những kiến thức cơ bản về PHP và HTML, ... Có thể đọc nội dung chi tiết về nội dung cũng như ví dụ của nó tại http://manual.cakephp.org

Download cakephp framework

Click vao lien ket sau de download cakephp framework ve: http://cakeforge.org/frs/?group_id=23&release_id=343.

Cài đặt và cấu hình cakephp

Cài đặt

Để sử dụng nó, cần phải đáp ứng những yêu cầu sau:
  • Một HTTP Server (vd như Apache, IIS)
  • CakePHP chỉ support trong PHP ver 4 trở lên.
  • Database: cake hổ trợ các hệ cơ sở dữ liệu sau: MySql, PostgreSQL.
Trong hướng dẫn này tôi sử dụng "AppServ Version 2.5.7 for Windows" gồm
  • Apache Web Server Version 2.2.3
  • PHP Script Language Version 5.1.6
  • MySQL Database Version 5.0.24a
  • phpMyAdmin Database Manager Version 2.9.0.2
Sau khi download cakephp về các bạn extract file đó ra (.zip) và copy vào thư mục chứa Apache Server (vd: C:\AppServ\www\MyCake). VD:

Code:
     /MyCake

/app
/cake
/vendors
.htaccess
index.php
Cấu hình

Để cake có thể làm việc được với database, cần cấu hình lại trang database.php, mặc định trang này không có, để cấu hình ta làm như sau: Mở file database.php.default ở /app/config và Save As lại thành file database.php. Điều chỉnh lại các thông số:

PHP Code:
var $default = array('driver' => 'mysql',
'connect' => 'mysql_connect',
'host' => 'localhost',
'login' => 'user',
'password' => 'password',
'database' => 'project_name',
'prefix' => );
Với user, password, database lần lượt là: tên user, password và database ở trong MySql

Quy ước về đặt tên bảng trong database

  • Tên bảng trong cake nên ở dạng tiếng Anh số nhiều (vd: users, customers, students, ... )
  • Bảng phải có primary key tên là 'id'
  • Nếu có sử dụng quan hệ trong các bảng vd: user_id (user không có s và dấu _ cộng id)

Ví dụ dùng CakePHP để viết modul quản lý khách hàng

Tôi sẽ nói đến tính năng, cũng như mô hình hoạt động của CakePHP, cách viết một web application bằng cakephp tôisẽ nói dần với các bạn qua ví dụ: Sau khi cài đặt và cấu hình CakePHP, kiểm tra CakePHP đã setup chưa, bạn test thử bằng cách mở web browser lên go http://localhost/MyCake/ bạn sẽ thấy giao diện như sau

This image has been resized. Click this bar to view the full image. The original image is sized 903x679.

Cần chú ý đến 2 dòng
  • Your database configuration file is present.
  • Cake is able to connect to the database.
Xác định xem bạn đã kết nối được Cake với database của bạn hay chưa.

Tạo bảng cơ sở dữ liệu

Ta tạo bảng customers với những field như sau:

  • id: INT, AUTO_INCREMENT, PRIMARY KEY
  • name: NVARCHAR
  • age: INT
  • address: NVARCHAR

Code của ứng dụng Customers Manager

Mở trình soạn thảo và tạo các file và nội dung như sau lưu theo đường dẫn chỉ định

File customer.php -> C:\AppServ\www\MyCake\app\models\

PHP Code:
class Customer extends AppModel
{
var
$name = 'Customer';
}
?>
File customers_controller.php -> C:\AppServ\www\MyCake\app\controllers

PHP Code:
class CustomersController extends AppController
{
var
$name = 'Customers';
function
index()
{
$this->set('customers', $this->Customer->findAll());
}
}
?>
File index.thtml -> C:\AppServ\www\MyCake\app\views\customers\

Chú ý tạo thư mục customers trong /app/views

PHP Code:

Customer Manager






foreach ($customers as $cust): ?>







endforeach; ?>
IdNameAgeAddress
echo $cust['Customer']['id']; ?>
echo $html->link($cust['Customer']['name'], '/customers/view/'.$cust['Customer']['id']);?>
echo $html->link(
'Delete',
"/customers/delete/{$cust['Customer']['id']}",
null,
'Are you sure?'
)?>
echo $html->link('Edit', '/customers/edit/'.$cust['Customer']['id']);?>
echo $cust['Customer']['age']; ?> echo $cust['Customer']['address']; ?>

echo $html->link("Add Customer", "/customers/add"); ?>

Xong 3 trang đó, chúng ta test chạy thử , mở webbrowser http://localhost/MyCake/customers Bạn sẽ thấy giao diện trang chính như hình sau:

This image has been resized. Click this bar to view the full image. The original image is sized 1086x421.

Như vậy là bạn đã tạo được ứng dụng đơn giản đầu tiên về việc sử dụng cakephp để viết ứng dụng web. Tiếp theo tôi sẽ giải thích cho các bạn mô hình hoạt động của CakePHP, cách viết các trang,cũng như cách sử dụng biến, hàm ...

Kiến trúc hoạt động

Như tôi đã giới thiệu CakePHP là một framework, nó hoạt động theo kiến trúc MVC (Model, View, Control). Trong Cake Model được thể hiện là một bảng dữ liệu, lưu trữ dữ liệu theo như các quy tắc mà Cake định nghĩa theo mặc định hoặc theo developer tự định nghĩa (chúng ta sẽ nói tính hợp lệ của dữ liệu qua phần Validate dữ liệu). View thể hiện các file view với code có thể là html và php. Controller sẽ thực hiện các yêu cầu từ server( ví dụ như buộc người dùng nhập dữ liệu vào input text), và sử dụng các Model để đọc, viết, hoặc thay đổi dữ liệu trong database và gởi dữ liệu đã được xử lý đến View.

Model

Trong ví dụ trên các bạn thấy trong file customer.php với cách viết code như trên, được Cake hiểu là ta muốn tạo một model tên là Customer để sử dụng trong CustomersController của chúng ta. Biến $name được chỉ định để tránh trường hợp model của chúng ta trùng với tên của các hàm của php. - Và lớp Customer sẽ được kế thừa các thuộc tính và phương thức từ lớp AppModel. Để có thể hiểu chi tiết về model và cách sử dụng các thuộc tính và hàm của model bạn có thể tham khảo tại http://manual.cakephp.org/chapter/models

Controller

Controller được sử dụng để quản lý việc giao tiếp với cơ sở dữ liệu, thiết lập các yêu cầu theo ý muốn của chúng ta để thể hiện lên view vidu như các hàm xử lý thêm, xóa, sữa và hiển thị, ..., là nơi mà tất cả các hoạt động của model ta sẽ quản lý nó được. Trong ví dụ trên (customers_controller.php)đoạn code trên được Cake hiểu rằng ta sẽ tạo một CustomersController dùng để quản lý việc sử dụng, các hoạt động của CustomerModel. Tương tự lớp CustomersController sẽ kế thừa từ lớp AppController. - Hàm index() sẽ được xử lý khi ta gọi trang index.thtml. Trong đó có phương thức set() được sử dụng để gán giá trị là một mảng được trả về từ phương thức findAll() tại của model Customer. Trong ví dụ trên thì biến $customers sẽ mang giá trị là mảng các customer được lấy từ bảng customers từ database. Để xem chi tiết về controller các bạn có thể tham khảo tại: http://manual.cakephp.org/chapter/controllers

View

View là nơi thể hiện dữ liệu đã được xử lý của chúng ta. Một view được xem như một trang template. Chúng ta có thể lấy dữ liệu từ model tương ứng. Dữ liệu được truyền qua một mãng $data. Trong ví dụ trên thì index.thtml là một view. Phần tiếp theo tôi sẽ nói đến chi tiết view thông qua ví dụ trên. Tiếp theo ta tìm hiểu đến các thuộc tính và phương thức trong index.thtml

PHP Code:
foreach ($customers as $cust): ?>
Biến $customers chính là biến mà ta đã thiết lập bằng phương thức set() ở CustomersController của ví dụ. Nó mang giá trị là một mãng như tôi đã nói.$html là một đối tượng của lớp helpers sẽ được đề cập trong phần tới. Phương thức link() được sử dụng để xuất ra một liên kết giống href trong HTML với tham số đầu tiên là tựa để của liên kết, tham số thứ 2 là url.

Hoàn chỉnh các chức năng của modul quản lý customer

Ta sẽ thêm các chức năng thêm, sữa, xóa, hiển thị trong view của chúng ta. Ta thêm các hàm trong customers_controller như sau:

PHP Code:
class CustomersController extends AppController
{
var
$name = 'Customers';
function
index()
{
$this->set('customers', $this->Customer->findAll());
}
function
view($id)
{
$this->Customer->id = $id;
$this->set('customers', $this->Customer->read());
}
function
add()
{
if (!empty(
$this->data))
{
if (
$this->Customer->save($this->data))
{
$this->flash('Your customer has been saved.','/customers');
}
}
}
function
delete($id)
{
$this->Customer->del($id);
$this->flash('The customer with id: '.$id.' has been deleted.', '/customers');
}
function
edit($id = null)
{
if (empty(
$this->data))
{
$this->Customer->id = $id;
$this->data = $this->Customer->read();
}
else
{
if (
$this->Customer->save($this->data['Customer']))
{
$this->flash('Your customer has been updated.','/customers');
}
}
}
}
?>
Như vậy ta đã thêm 4 function trong CustomersController của chúng ta. Function sẽ được gọi ở view. Ví dụ trên ta click vào link Add Customer view add sẽ hiện lên cho ban nhập dữ liệu và khi ta click Save thì function add sẽ được thực hiện. Bạn tạo file add.thtml với nội dung như sau:

PHP Code:

Add Customer


echo $html->url('/customers/add')?>">


Name:
echo $html->input('Customer/name', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/name', 'Name is required.') ?>



Age:
echo $html->input('Customer/age', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/age', 'Age is required.') ?>



Address:
echo $html->input('Customer/address', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/address', 'Address is required.') ?>



echo $html->submit('Save') ?>


Trong view add, dòng

PHP Code:
echo $html->input('Customer/name', array('size' => '40'))?>
sẽ xuất ra một thẻ input text. Với dòng lệnh trên thì Cake sẽ hiểu rằng ta sẽ sử dụng trường name trong model Customer.Tham số thứ 2 là thuộc tính của thẻ input trong HTML. Tương tự với thẻ submit. Hàm tagErrorMsg() sẽ thông báo lỗi ở view trong trường hợp dữ liệu nhập của ta bị lỗi. Việc xử lý lỗi sẽ được nói trong phần sau. Tương tự ta tạo các file edit.thtml, view.thtml như sau:

edit.thtml

PHP Code:

Edit Your Customer


echo $html->url('/customers/edit')?>">
echo $html->hidden('Customer/id'); ?>


Name:
echo $html->input('Customer/name', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/name', 'Name is required.') ?>



Age:
echo $html->input('Customer/age', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/age', 'Age is required.') ?>



Address:
echo $html->input('Customer/address', array('size' => '40'))?>
echo $html->tagErrorMsg('Customer/address', 'Address is required.') ?>



echo $html->submit('Save') ?>


view.thtml

PHP Code:

Your Customer


Name :echo $customers['Customer']['name']?>


Age :echo $customers['Customer']['age']?>


Address:echo $customers['Customer']['address']?>

Như vậy các chức năng của ta đã được thực hiện hoàn chỉnh. Trong phần tới chúng ta sẽ tiếp tục tìm hiểu một số phương thức và thuộc tính được sử dụng phổ biến để viết ứng dụng

Components

Trong những trường hợp vì một lý do nào đó ta không thể viết được các hàm trong controller, thì components sẽ chúng ta giải quyết được vấn để đó, và đó cũng chính là một đặc tính rất hữu ích cho các developer trong việc kế thừa các function từ các nguồn khác.

Các files component được lưu giữ ở thư mục app/controllers/components/. Ví dụ ta tạo một file component tên là cpn.php, nội dung trang components đó sẽ tương tự như sau:

PHP Code:
class CpnComponent extends Object
{
var
$comp = null;
var
$controller = true;

function
startup(&$controller)
{
// controller initialization here.
}

function
doComp()
{
$this->comp = 'cpn';
}
}
Phương thức starup() sẽ tham chiếu đến controller mà đang sử dụng nó. Hàm startup() Dispatcher trong suốt quá trình load Cakephp. Nó là một contructor cho phép components truy xuất đến controller đó.

Để sử dụng components đó các bạn phải khai báo biến $components trong controller và gán giá trị cho nó chính là tên components. Ví dụ trong ví dụ về quản lý Customer trên bạn muốn sử dụng components cpn.php trong CustomersComtroller thì đoạn code như sau

PHP Code:
class CustomersController extends AppController{
var
$name = 'Customers';
var
$components = array('cpn');
...
}
?>
Và trong controller đó ta muốn sử dụng hàm doComp() trong components thì viết như sau: $this->Cpn->doComp();. Một ví dụ khác, nếu ai đã từng dùng json (nó là một lớp gồm các hàm để chuyển đổi định dạng dữ liệu bao gồm các phương thức chuyển đổi như encode(), decode(), ...) để sử dụng nó trong các ứng dụng, ta cũng khai báo như trên var $components = array(json); và đặt nó trong controller mà muốn sử dụng.