Bài 3: Sử dụng Controller trong laravel
Sau khi route nhận được request thì sẽ chuyển hướng request đến cho controller và giao cho controller này xử lý. Controller sẽ gọi tới Model để tương tác với cơ sở dữ liệu (database) và đưa dữ liệu tới View và View sẽ nhận dữ liệu và chuyển thành những đoạn mã HTML rồi gửi về cho Client. Hiện tại tới bài này là chúng ta đang học Controller chứ chưa học Model và View nên mình chỉ giới thiệu Controller và cách sử dụng thôi nhé.
1. Tạo controller trong laravel
Tất cả controller trong laravel được chứa trong thư mục app/controllers
và việc tạo tên file
, đặt tên controller
cũng phải tuân theo nguyên tắc của nó như sau:
- Trước tiên tôi muốn giới thiệu với các bạn lớp Controller của Laravel, đây là một lớp xử lý controller chính của Laravel nên tất cả các Controller mới phải thừa kế (extends) từ lớp này.
- Nêu bạn muốn kế thừa từ một Controller khác thì lớp đó phải kế thừa từ lớp Controller của Laravel. Lúc này Controller mới tạo sẽ extends từ lớp Controller khác đó.
- Tên Controller phải trùng với tên File. Ví dụ bạn tạo Controller tên
DemoController
thì file phải tên làDemoController.php
Tạo Controller kế thừa trực tiếp từ Controller của Laravel
Bước 1: Bạn tạo file DemoController.php
nằm trong thư mục app/controllers
Bước 2: Bạn viết code tạo Controller trong file DemoController.php
như sau:
Bài viết này được đăng tại [free tuts .net]
<?php class DemoController extends Controller{ }
Lưu ý là trong đó mình có kế thừa từ lớp Controller của Laravel. Vậy là bạn đã tạo thành công một Controller rồi đấy.
Tạo Controller kế thừa từ một Controller khác
Bây giờ mình sẽ tạo một ExtController và DemoController, DemoController sẽ kế thừa từ ExtController.
Bước 1: Tạo ExtController, bạn tạo file ExtController.php
nằm trong folder app/controllers
với nội dung như sau:
class ExtController extends Controller{ }
Bước 2: Tạo DemoController, bạn tạo file DemoController.php
nằm trong folder app/controllers
với nội dung như sau:
class DemoController extends ExtController{ }
Tới đây bạn sẽ có thắc mắc rằng tại sao lớp ExtController
chưa load vào mà trong lớp DemoController
có thể kế thừa được? Lý do là Laravel đã load sẵn cho chúng ta nhé.
Việc sử dụng kế thừa qua controller khác như thế này nhằm mục đích tạo ra những hành động dùng chung cho một nhóm controller khác. Ví dụ bạn muốn filter trong các controller của backend xem đã đăng nhập chưa, thay vì bạn filter trong từng controller thì có thể tạo 1 controller AdminController
rồi cho các controller khác extends lại.
Tạo Controller trong thư mục con (sub folder)
Ngoài ra chúng ta cũng có thể tạo Controller nằm trong một subfolder. Ví dụ bạn tạo thư mục con backend
trong thư mục app/controllers
và tạo một controller AdminController
trong thư mục này và đặt tên controller tuân theo quy tắc trên là được. Nhưng để laravel có thể hiểu hiểu được AdminController
này thì ngay sau khi tạo controller bạn phải chạy lệnh sau (run command): php artisan dump-autoload
Như bạn thấy đó, việc tạo controller trong sub folder trong laravel rất đơn giản phải không.
2. Tạo Action Controller trong Laravel
Tạo action mới thì bạn cần lưu ý những điều dưới đây.
Khi làm việc với Route::controller thì bạn chú ý việc đặt tên action phải tuân theo quy tắc methodUri như sau:
- method là post, get, ... và viết thường
- Uri: Chữ cái đầu tiên của Uri sẽ bắt buộc viết in hoa, cứ 1 chữ in hoa sẽ được tính là 1 đoạn uri được phân cách bởi dấu
-
Ví dụ: action getDemoAction sẽ có method là get và Uri là demo-action
Khi làm việc với Route::resource thì controller laravel hỗ trợ 8 action: index, create, store, show, edit, update, destroy
nhưng trong controller không nhất thiết phải tạo đủ 8 action này.
Ngoại trừ những điều trên thì action bạn có thể đặt tên tùy ý.
Truyền tham số vào action
Làm việc với Route::controller:
Quay lại ví dụ trên mình viết action hiển thị chi tiết tin tức mà chưa truyền ID vào phải không nào? Bây giờ ta sẽ sửa lại một chút để nhận tham số ID trên URL để sử dụng nhé.
Bước 1: Bạn tạo một Route mới như sau:
Route::controller('/news','NewsController');
Bước 2: Bạn sửa lại file NewsController.php
như sau:
class NewsController extends Controller{ public function getDetailAction($id) { dd($id); } }
Bước 3: Bạn bạn truy cập URL: http://tênmiềnảocủabạn/news/detail-action/3
bạn sẽ nhận được kết quả $id=3
Làm việc với Route::resource:
Trường hợp này thì bạn xem lại phần cuối bài Sử dụng Route::controller và Route::resource trong laravel
Các trường hợp khác:
Ngoại trừ hai trường hợp trên thì thông thường khi truyền tham số vào Action bạn phải tuân theo cú pháp như sau:
- Tên tham số trong route đặt trong cặp thẻ
{}
, ví dụ{id}
- Trong action sẽ nhận tham số tương ứng. Ví dụ ta có route là
'/chitiet-{id}-{title}'
thì trong action sẽ nhận hai tham số tương ứng lànameAction($id, $title)
Ví dụ: Bạn thay đổi nội dung ở Route lại như sau:
Route::get('/chitiet-{id}','NewsController@detail');
Thì khi bạn truy cập URL: http://tênmiềnảocủabạn/chitiet-3
bạn sẽ nhận được biến $id = 3
.
3. Sử dụng filter trong controller.
Ngoài việc sử dụng filter ngay trong file routes.php thì khi khai báo route bạn có thể đặt nó trong controller, cụ thể là trong hàm khởi tạo function __construct
của controller bằng cách sử dụng con trỏ $this
trỏ tới function beforFilter
(filter trước khi bất kỳ action nào được quy định được gọi) hoặc afterFilter
(filter sau khi controller được gọi). Cu pháp như sau:
public function __construct(){ $this->beforeFilter( $filter, $options); }
Trong đó:
- $filter là tên của filter trong file filters.php
- $option là mảng các tùy chọn trong đó
- on: filter trên method nào
- except: filter trên tất cả các action của controller trừ action được khai báo
- only: chỉ filter trên các action được khai báo}
Ví dụ:
//gọi bộ lọc auth trên tất cả các action trong controller trừ action getLogin $this->beforeFilter('auth', array('except' => 'getLogin')); //gọi bộ lọc csrf trên tất cả các action trong controller có method là post $this->beforeFilter('csrf', array('on' => 'post')); //sau khi 2 action fooAction và barAction xử lý xong thì filter log được gọi $this->afterFilter('log', array('only' => array('fooAction', 'barAction')));
Bạn cũng có thể dùng action trong chính controller để sử dụng làm filter bằng cách sử dụng ký tự @ để khai báo, tuy nhiên cách này ít khi được sử dụng. Cú pháp như sau:
public function __construct(){ $this->beforeFilter('@filterRequests'); } public function filterRequests($route, $request){ // }
4. Kết luận
Như vậy trong bài này mình đã giới thiệu qua về cách khai báo và sử dụng controller một cách cơ bản. Ở bài sau mình sẽ giới thiệu cách bạn tương tác với View bằng Controller.