Bắt đầu học CakePHP bằng cách xây dựng một ứng dụng(Phần 1)

CakePHP là một PHP framework rất phổ biến hiện nay, nó có nhiều ưu điểm khá nổi bật so với các framework khác, việc tiếp cận và sử dụng Cake cũng khá dễ dàng và nhanh chóng. Trên Internet có khá nhiều bài viết dạng như thế này nhưng theo nhìn nhận ban đầu của tôi đó là còn khá sơ sài, chưa đưa ra được một cách nhìn dễ dàng hơn về cakephp, đặc biệt có những bài viết sao chép còn không có thể chạy được các đoạn code trong hướng dẫn. Vì vậy tôi quyết định viết một chuỗi bài về CakePHP để các bạn có thể nắm rõ được Cake , chuỗi bài viết này được tôi dịch và phát triển thêm từ tài liệu chính thống của CakePHP, nó dùng cho tất cả các bạn từ mới bắt đầu cho đến chuyên nghiệp...Hi vọng theo chuỗi bài viết của tôi các bạn có thể nắm bắt CakePHP một cách dễ dàng.
   Đây là bài viết đầu tiên trong chuỗi bài viết, tôi sẽ không giới thiệu về Cake, cũng không hướng dẫn cài đặt về cake vì nhũng cái đó đầy rẫy trên internet rồi, Trong bài đầu tiên này tôi sẽ hướng dẫn các bạn xậy dựng một ứng dụng CakePHP truy xuất vào database để xuất danh sách dữ liệu ra trình duyệt. Chỉ đơn giản vậy thôi...
   Để bắt đầu với cake chúng ta sẽ tưởng tượng như mình đang làm bánh vậy...các thành phần được làm tươi, thái lát lên, và đặt vào một chỗ. Lò được mở, nước nóng, và lửa cháy đỏ. Đó là thời gian để chúng tôi đặt trên mũ nấu ăn, và bắt đầu thực hiện một số công thức nấu ăn bánh ngon. Vì vậy, bạn đã sẵn sàng thành một người thợ làm bánh chưa?
    Trong bài viết này, chúng ta sẽ phát triển một ứng dụng nhỏ mà tôi gọi là "CakeTooDoo". Nó sẽ là một ứng dụng đơn giản thể hiện danh sách các công việc cần làm (Nhiệm vụ), và lưu trữ chi tiết các nhiệm vụ này. Chúng ta sẽ có thể xem tất cả nhiệm vụ, thêm nhiệm vụ mới, và đánh dấu vào các công việc được thực hiện ...  Đây là ví dụ về một danh sách công việc phải làm, những điều mà chúng ta sẽ thực hiện trong bài này:

  • Chắc chắn là Cake được cài đặt đúng cho CakeTooDoo
  • Hiểu được các tính năng của CakeTooDoo
  • Tạo cơ sở dữ liệu và hiệu chỉnh CakeTooDoo
  • Viết được Cake model đầu tiền
  • Viết được Cake controller đầu tiền
  • Xây dựng một danh sách cho thấy tất cả các nhiệm vụ trong CakeTooDoo
  • Tạo một form để thêm nhiệm vụ mới để CakeTooDoo
  • Tạo một form để chỉnh sửa nhiệm vụ trong danh sách công việc phải làm
  • Có một ràng buộc xác nhận dữ liệu để đảm bảo rằng người dùng không để trống tiêu đề của sản phẩm nào
  • Thêm chức năng để xóa một công việc từ danh sách
  • Lập danh sách riêng biệt cho hoàn thành và đang chờ giải quyết công việc
  • Làm cho việc tạo ra và chỉnh sửa thời gian của nhiệm vụ trông đẹp hơn
  • Tạo một trang chủ cho CakeTooDoo

I. Chắc chắn là "lò" đã sẵn sàng:
   Trước khi chúng ta bắt đầu với CakeTooDoo, hãy đảm bảo rằng "lò" của chúng ta đã sẵn sàng. Sau đây là danh sách các yêu cầu cần phải kiểm tra lại trên máy tính của bạn:

  • 1. Apache được cài đặt đúng và đang chạy.
  • 2. Cơ sở dữ liệu MySQL server được cài đặt và đang chạy.
  • 3. PHP, phiên bản 4.3.2 hoặc cao hơn, được cài đặt và làm việc với Apache.
  • 4. Phiên bản mới nhất của CakePHP đang được sử dụng.
  • 5. Module Apache mod_rewrite được bật.
  • 6. AllowOverride được thiết lập để tất cả cho thư mục gốc web trong Apache bằng cách chỉnh sửa file httpd.conf.
  • 7. CakePHP được giải nén và đặt vào trong thư mục gốc web của Apache.
  • 8. Apache đã viết truy cập cho thư mục tmp của CakePHP.

 Như chúng ta đã biết, ứng dụng CakeTooDoo sẽ là một danh sách các nhiệm vụ, công việc đơn giản. Danh sách sẽ bao gồm nhiều nhiệm vụ mà chúng ta muốn làm. Mỗi nhiệm vụ sẽ bao gồm 2 thuộc tính: tiêu đề và tình trạng. Tiêu đề cho biết những điều mà chúng ta cần làm, và tình trạng sẽ cho ta biết rằng nhiệm vụ đã được hoàn thành hay chưa. Cùng với tiêu đề và tình trạng này, mỗi công việc sẽ cũng ghi lại thời gian khi nhiệm vụ đã được tạo ra và đã chỉnh sửa lần cuối. Sử dụng CakeTooDoo, chúng ta sẽ có thể thêm nhiệm vụ mới, thay đổi trạng thái của công việc, xóa một nhiệm vụ, và xem tất cả các nhiệm vụ. Cụ thể hơn, CakeTooDoo sẽ cho phép chúng ta làm những điều sau đây:
  • 1. Xem tất cả các nhiệm vụ trong danh sách
  • 2. Thêm một nhiệm vụ mới vào danh sách
  • 3. Chỉnh sửa một nhiệm vụ để thay đổi tình trạng của nó
  • 4. Xem tất cả các nhiệm vụ hoàn thành.
  • 5. Xem tất cả nhiệm vụ đang chờ giải quyết hoặc không thực hiện được.
  • 6. Xóa một nhiệm vụ.
  • 7. Một trang chủ cho phép truy cập vào tất cả các tính năng.

II. Tùy chỉnh CakePHP để làm việc với một database (Configuring Cake to Work with a Database)

 Điều đầu tiên chúng ta cần làm là tạo ra cơ sở dữ liệu mà ứng dụng của chúng ta sẽ sử dụng. Tạo cơ sở dữ liệu cho các ứng dụng CakePHP không khác biệt so với các ứng dụng PHP khác. Nhưng, chúng ta cần tuân theo một quy tắc đặt tên đơn giản trong khi tạo bảng cho cơ sở dữ liệu của chúng ta. Khi cơ sở dữ liệu đã được tạo, bước tiếp theo kết nối  CakePHP với cơ sở dữ liệu vừa tạo.
 Các bước làm như sau:
1. Tạo một database tên là caketoodoo trong Mysql server, bạn có thể tạo bằng PHPMyAdmin hoặc dùng lệnh sau:
   CREATE DATABASE caketoodoo;
2. Sau đó bạn tạo một bảng tasks để lưu các nhiệm vụ trong database vừa tạo ở trên:

    CREATE TABLE tasks (
      id int(10) unsigned NOT NULL auto_increme
      title varchar(255) NOT NULL,
      done tinyint(1) default NULL,
      created datetime default NULL,
      modified datetime default NULL,
      PRIMARY KEY (id)
    );

3. Đổi trên thư mục chính của CakePHP thành CakeTooDoo (Thực ra nếu bạn không đổi thì cũng không ảnh hưởng gì ở đây tôi chỉ muốn có một sự thống nhất!)
4. Di chuyển đến thư mục CakeTooDoo/app/config. trong thư mục config
tìm đến file database.php.default. Đổi tên file này thành database.php

5. Mở file database.php với trình soạn thảo của bạn, và di chuyển đến  một mảng có tên là $default. Mảng này chứa các tùy chọn kết nối cơ sở dữ liệu. Chỉ định người dùng đăng nhập vào cơ sở dữ liệu bạn sẽ được sử dụng và mật khẩu để mật khẩu của người dùng. Chỉ định cơ sở dữ liệu là caketoodoo. Nếu chúng ta đang sử dụng cơ sở dữ liệu người dùng ahsan với sims mật khẩu,
các confguration sẽ như thế này:

var $default = array(
         'driver' => 'mysql',
          'persistent' => false,
          'host' => 'localhost',
          'port' => '',
          'login' => 'ahsan',
          'password' => 'sims',
          'database' => 'caketoodoo',
          'schema' => '',
          'prefix' => '',
          'encoding' =>
     );
6. Bây giờ bạn có thể vào địa chỉ http://localhost/CakeTooDoo/ để kiểm tra xem cakePHP đã chạy chưa. - Có thể bạn sẽ gặp những cảnh báo màu da cam, bạn hãy làm theo các hướng dẫn trên các thông báo này , sau này tôi sẽ có một bài tổng hợp về các warning này.

III. Xây dựng Model đầu tiên:
  Trong CakePHP, mỗi bảng cơ sở dữ liệu cần phải có một Model tương ứng. Các Model sẽ có trách nhiệm truy cập và sửa đổi dữ liệu trong bảng. Như chúng ta tạo ban đầu cơ sở dữ liệu caketoodoo của chúng ta chỉ có một bảng tên là Tasks. Vì vậy, ta sẽ cần phải định nghĩa chỉ có một Model. Sau đây là cách làm nó:

1. Tạo một file PHP có tên là task.php (Viết thường) và lưu trong thư mục CakeTooDoo/app/models.Nội dung của file task.php như sau:
<?php
class Task extends AppModel {
       var $name = 'Task';
  }
?>
2. Giải thích:
 - Chúng ta vừa tạo ra một Model task cho bảng dữ liệu tasks. Tất cả các Model trong CakePHP đều nằm trong thư mục App/Models. Thông thường, mỗi bảng cơ sở dữ liệu sẽ có một file model tương ứng trong thư mục này. Tên file cho một model là số ít của tên bảng dữ liệu tương ứng, và tất nhiên theo sau là phần đuôi mở rộng .php . Ở đây, file Model cho bảng tên là tasks nên tên của Model là task.php.
 - Các Model về cơ bản được chứa trong một lớp PHP. Tên của lớp cũng là số ít của tên bảng nhưng nó được viết hoa chữ cái đầu. Ở đây tên lớp trong ví dụ này là Task
 - Tất cả các lớp Model trong CakePHP đều được kế thừa từ lớp AppModel
 - Chúng ta định nghĩ một biến có tên là $name , và giá trị là tên của lớp chứa nó. Điều này không bắt buộc , như là Cake có thể xuất ra tên của Model một cách tự động. Nhưng là một cách thực hành tốt khi đặt tên cho nó một cách thủ công.

IV. Xây dựng Controller đầu tiên:
  Khi một yêu cầu được tạo ra từ ứng dụng web, các controller là nơi mà nó được quyết định những gì cần phải thực hiện. Nói cách khác, Controller là nơi mà dòng ứng dụng được kiểm soát. Nếu dữ liệu cần phải được truy cập, Controller sẽ gọi các Model và duyệt tìm dữ liệu. Các controller sau đó sẽ đưa ra để các view thực hiện hiển thị. Đối với CakeTooDoo, chúng ta chỉ cần một Controller được gọi là Tasks.

1. Tạo một file PHP có tên là tasks_controller.php và lưu file này trong thư mục CakeTooDoo/app/controllers. File tasks_controller.php có nội dung như sau:

    <?php
    class TasksController extends AppController {
      var $name = 'Tasks';
    }
    ?>
2. Giải thích:
- Cũng giống như các Model, Controller trong CakePHP được đặt trong một thư mục riêng biệt gọi là Controllers trong thư mục app. Tất cả các controller trong một ứng dụng Cake phải được đặt trong thư mục này.
- Mỗi Model trong ứng dụng có một Controller tương ứng trong Cake. Vì vậy, đối với Model Task của chúng ta, Controller tương ứng là  Tasks Controller. Không phải là tất cả các Model chỉ có một Controller tương ứng, hoặc ngược lại. Khi chúng ta làm cho các ứng dụng phức tạp hơn chúng ta sẽ thấy rằng một Controller có thể sử dụng nhiều hơn một Model nếu được yêu cầu
- Tên file của Controller là tasks_controller.php. Đó là một quy ước trong Cake rằng tên file của controller là số nhiều của tên Models, tiếp theo là một dấu gạch dưới rồi đến từ "controller", với phần mở rộng .php.
- Cũng giống như các lớp Model, tên lớp Controller cũng được viết hoa tất cả chữ cái đầu. Trong trường hợp này là TasksController. Chú ý rằng "Tasks" là số nhiều cho tên lớp controller như trong tên file controller. Mọi Controller trong Cake phải kế thừa từ lớp AppController.
- Cuối cùng, chúng ta định nghĩa biên $name trong controller Tasks và giá trị được gán là tên của controller chứa nó. Một lần nữa, giống như Model, Cake sẽ có thể xác định được tên của controller tự động.

V. Hiển thị tất cả các task trong CakeTooDoo

  Bây giờ Model Task và Controller Task đã được tạo, chúng ta hãy thêm một số chức năng vào ứng dụng của chúng ta. Điều đầu tiên chúng ta làm là để xem danh sách tất cả các nhiệm vụ. Để làm điều này, chúng ta sẽ cần phải thêm một hàm vào Controller task, và cũng thêm một view để hiển thị danh sách các nhiệm vụ.
 1. Viết hàm xem danh danh sách tất cả các Task
 - Mở file tasks_controller.php và thêm một phương phương thức có tên là index cho lớp TasksController với đoạn code sau đây. Bất kỳ hàm public nào bên trong lớp controller được gọi là các hành động. Vì vậy, sau khi thêm hành động index vào lớp TasksController, file tasks_controller.php của chúng ta sẽ giống như thế này:

<?php
class TasksController extends AppController{
    var $name= 'Tasks';
    function index(){
        $this->set('tasks',$this->Task->find('all'));
        //Hàm find() để lấy các record từ bảng của Model
        //Hàm set() gửi dữ liệu lấy được đến một mảng tên là tasks
    }
}
?>
 - Di chuyển đến thư mục CakeTooDoo/app/views. Tại đây bạn tạo một thư mục có tên là tasks
 - Trong thư mục tasks vừa tạo ở trên, bạn tạo một file có tên là index.ctp có nội dung sau

<h2>Tasks</h2>
<?php if(empty($tasks)): ?>
      There are no tasks in this list
<?php else: ?>
 <table>
     <tr>
        <th>Title</th>
        <th>Status</th>
        <th>Created</th>
        <th>Modified</th>
        <th>Actions</th>
     </tr>
<?php foreach ($tasks as $task): ?>
      <tr>
               <td>
                  <?php echo $task['Task']['title'] ?>
               </td>
                               <td>
                   <?php
                      if($task['Task']['done']) echo "Hoàn thành";
                      else echo "Đang chờ";
                   ?>
                </td>
                <td>
                   <?php echo $task['Task']['created'] ?>
                </td>
                <td>
                   <?php echo $task['Task']['modified'] ?>
                </td>
                <td>
                   <!-- actions on tasks will be added later -->
                </td>
         </tr>
        <?php endforeach; ?>
       </table>

    <?php endif; ?>

 - Bây giờ bạn có thể vào đường dẫn http://localhost/CakeTooDoo/tasks/index để xem danh sách các task có trong cơ sở dữ liệu của bạn. Sau khi thực hiện thành công sẽ dạng như hình sau:


2. Giải thích:

 - Chúng ta đã tạo ra một phương thức controller có tên là index. Các phương thức controller được gọi là 'action' (Hành động).  Chúng ta chỉ cần thêm, xử lý một yêu cầu bất cứ khi nào một yêu cầu được tạo ra tại URL  http://localhost/CakeTooDoo/tasks/index
 - Khi một yêu cầu được tạo từ một action index, dòng sau sẽ được thực hiện:
   $this->set('tasks', $this->Task->find('all'));
     Dòng này gọi hàm find() của Model Task, nó trả về tất cả task (nhiệm vụ) được lưu trữ trong bảng tasks
   Lưu ý: Tất cả cá Model trong CakePHP đều có hàm find(). Nó thực sự được định nghĩa trong lớp Model. Hàm này được sử dụng để lấy các record từ bảng của model. Bằng cách truyền tham số cho hàm này chúng ta có thể kiểm soát được các record mà chúng ta muốn lấy. Trong đoạn code trên, "all" đực truyền vào để lấy tất cả các record trong bảng task.
- Sau đó sử dụng hàm set() của controller Tasks, nó gửi dữ liệu vừa lấy được đến view trong một mảng có tên là tasks. Chúng ta có thể truy cập mảng này thông qua biến $tasks.
   Lưu ý: Hàm set() được sử dụng dể chuyển dữ liệu từ action controller tới view. Có 2 tham số thường được truyền cho nó. Đầu tiên là tên của biến mà dữ liệu sẽ có trong view, và thứ 2 là dữ liệu thực cần được chuyển qua. Hàm set() thường được định nghĩa trong lớp Controller được thừa kế từ Appcontroller, lớp mà được thừa kế lại từ tất cả các controller trong cakePHP.

- Giống như Model và controller, Cake cũng có một thư mục riêng để chứa View. Trong thư mục Views chúng ta tạo một thư mục Tasks, thư mục này sẽ chứa tất cả các view của controller task. Một controller có thể có nhiều action, và mỗi action có thể có 1 view, Một controller cũng có thể có nhiều View.
- Trong thư mục views/tasks chúng ta đã tạo một file tên là index.ctp. Đây là file view của action index trong controller Tasks. Tên action và tên file view tương ứng của nó luôn giống nhau. Các view luôn luôn có phần mở rộng là .ctp , đây là chuẩn của một trang dao diện trong cake.
 - Trong file index.ctp, chúng ta đặt mã HTML với mã PHP được nhúng vào. Ở đây, chúng tôi có một bảng HTML để hiển thị tất cả các task(nhiệm vụ) hiện nay tại CakeTooDoo. Hãy nhớ rằng, chúng ta đã một mảng có teen là tasks tới view
bằng cách sử dụng hàm set() trong action index. Mảng này có thể truy cập từ view, và dùng code PHP đơn giản, chúng ta hiển thị tất cả các (task)nhiệm vụ mà CakeTooDoo lưu trữ

Trong bài sau chúng ta sẽ tạo ra các nút chức năng thêm xóa sửa trong ứng dụng CakeTooDoo này.

7 nhận xét:

  1. Tiếp phần 2 đi bạn :D Mình đang tìm hiểu về vấn đề này. Bạn có thể giúp mình một chút được không? Cảm ơn bạn thật nhiều. Trước thềm năm mới, chúc bạn luôn yêu đời, vui vẻ, và hạnh phúc nhé.

    Trả lờiXóa
  2. Cảm ơn bạn! mình sẽ hoàn thành phần 2 để mọi người tham khảo, dạo này việc cty bận quá, thông cảm nhé! Chúc các bạn năm mới vui vẻ, thành công!

    Trả lờiXóa
  3. em doc thay de hieu hon cac bai da co tren cac trang khac...giai thik cu the nua...hihi...cam on anh rat nhieu...hi vong bai tiep theo se nhanh chong duoc trinh lang...
    nhan tien cho em hoi: lam sao biet trong lop AppmMdel co nhung phuong thuc nao(vi du nhu fin())

    Trả lờiXóa
  4. Bác Minh bang Chủ ơi bác có cái project nào mà full như là 1 web bán hàng làm =cakephp bác có thể share cho e với mọi người đc ko ạ cảm ơn bác,có gì bác cho e xin vào mail :mr.qthien@gmail.com nha bác.thaks bác

    Trả lờiXóa
  5. cảm ơn bang chủ về bài viết!

    Trả lờiXóa
  6. mình đã làm như hướng dẫn nhưng sao vẫn không được nhĩ. xin các bạn chỉ dùm.và đây là lỗi:
    Fatal error: Class 'AppHelper' not found in C:\wamp\www\CakeTooDoo\lib\Cake\View\Helper\FormHelper.php on line 28
    Nhưng trong bài không đề cập đến Helper nhưng sao lại bị lỗi này ạh.

    Trả lờiXóa
  7. chổ function index() cần thêm public vào: public function index()

    Trả lờiXóa

Rất mong các ý kiến của các bạn khi đọc bài viết này !