Hướng dẫn cách rewrite URL trong Codeigniter
Post on: 2016-09-20 10:58:43
Làm thế nào để viết lại đường dẫn trong Codeigniter (Rewrite URL). Chức năng này khá quan trọng khi làm web bởi vì nó thân thiện với người dùng và tốt cho SEO.
Tìm hiểu Route trong Codeigniter Mọi thứ liên quan đến
Rewrite URL trong Codeigniter đều nằm trong file application/config/routes.php, bạn mở file này lên nó sẽ có một số dữ liệu như sau:$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
Trong đó:
- default_controller: là controller mặc định, nếu bạn truy cập với URL ko có khai báo controller thì nó sẽ gọi tới controller mặc định này. Ví dụ: $route['default_controller'] = 'product/index';
- 404_override: Nếu bạn không khai báo thì nó sẽ lấy trang mặc định lỗi của CI, còn nếu ban khai báo thì nó sẽ gọi đến controller và action trong đó. Ví dụ: $route['404_override'] = 'error/show404';
- translate_uri_dashes: Cái này không phải là route mà nó là một option với giá trị là
TRUE
hoặcFALSE
. NếuTRUE
thìCI
sẽ chuyển đổi ký tự gạch ngang (-) thành gạch dưới (_) và ráp vào controller. Ví dụ bạn có controller tên Product_shop thì bạn sẽ gõ URL là http://domain.com/product-shop sẽ sai, nhưng nếu bạn khai báo $route['translate_uri_dashes'] = TRUE; thì sẽ được.
Thêm mới route như thế nào?
Để thêm mới một route thì bạn chỉ cần thêm bên dưới cùng của file với cấu trúc:$route['url-tren-trinh-duyet'] = 'controller/action/param1/param2...';
Các ký hiệu hay dùng trong Route
Route trong CI có các ký hiệu như sau:(:any)
- đại diện cho các ký tự bất kì(:num)
- đại diện cho các số tự nhiên
Trong route này nếu trình duyệt là http://domain.com/tuhocweb-blog
thì nó sẽ gọi tới blog
controller và user
action.
user
trong controller blog
sẽ có một tham số truyền vào và giá trị của nó là đằng sau tuhocweb-blog/
.
- Nếu bạn gõ URL là
http://domain.com/tuhocweb/thehalfheart
thì sẽ sai vì ký tự đằng sau được khai báo là(:num)
- Nếu bạn gõ URL là
http://domain.com/
tuhocweb
-blog/12
thì đúng
Sử dụng Regular Expression trong route
Bạn có thể sử dụng Regular Expression để sử dụng trong route. Thông thường chúng ta sử dụng các chuỗi regex sau:([0-9]+)
tương đương với(:num)
([a-zA-Z0-9]+)
gần tương đương với(:any)
Route Callback trong Codeigniter
Chức năng này mới được thêm từ Version CI3X, các versions trước không có nhé các bạn.Thay vì bạn khai báo là
$route['url'] = 'value'
thì bạn sẽ khai báo function cho nó với cú pháp như sau:
$route
[
'url'
] =
function
(){
return
'controller/action'
;
};
Tới đây bạn sẽ có thắc mắc là nếu có tham số truyền vào controller thì sao? Đơn giản là tuân theo capturing group nhé. Nghĩa là group1 tương đương tham số 1, group2 tương đương tham số 2.
return 'controller/action/' . $any . '/' . $num;
}
Có lẽ tới đây thôi vì lý thuyết hơi dài dòng, ta đi vào làm thực tế nhé.
Rewrite URL cho trang sản phẩm
Trước tiên bạn tạo một controller Product như sau:
{
public function index($page = '')
{
echo '<h1>Home page</h1>';
echo 'Page: ', $page;
}
public function category($cate_slug = '', $page = '')
{
echo '<h1>Category page</h1>';
echo 'Slug: ', $cate_slug, '<br/>';
echo 'Page: ', $page, '<br/>';
}
public function tag($tag_slug = '', $page = '')
{
echo '<h1>Tag page</h1>';
echo 'Slug: ', $tag_slug, '<br/>';
echo 'Page: ', $page, '<br/>';
}
public function detail($post_slug = '', $post_id = '')
{
echo '<h1>Detail page</h1>';
echo 'Slug: ', $post_slug, '<br/>';
echo 'ID: ', $post_id, '<br/>';
}
}
Trong controller này có tạo 4 action:
- index: trang chủ
- category: trang sản phẩm theo chuyên mục
- tag: trang sản phẩm theo tag
- detail: trang chi tiết sản phẩm
Rewrite trang chủ
Trang chủ ở đây không phải là trang home chính nha các bạn mà là trang hiển thị danh sách tất cả các sản phẩm nên nó sẽ có URL như sau:- domain.com/san-pham
- domain.com/san-pham/page/1
$route['san-pham'] = 'product/index';
Rewrite trang category
Trang danh sách sản phẩm mình muốn nhận slug của category để truy vấn database nên nó sẽ có dạng sau:- domain.com/slug-chuyen-muc
- domain.com/slug-chuyen-muc/page/1
$route['(:any)'] = 'product/category/$1';
Các bạn để ý các ký hiệu $1
và $2
nhé, nó là capturing group đấy.
Rewrite trang tag
Tương tự như trang danh sách chuyên mục, nhưng để phân biệt giữa tag và chuyên mục thì trên URL mình sẽ thêm chữ tag nữa.- domain.com/tag/slug-cua-tag
- domain.com/tag/slug-cua-tag/page/1
$route['tag/(:any)'] = 'product/tag/$1';
$route['(:any)'] = 'product/category/$1';
nên nó sẽ đúng với bất kì trường hợp nào, chính vì vậy nó sẽ ngưng và ko duyệt xuống dưới nên giải pháp là đặt tag lên trên category.$route['san-pham/page/(:num)'] = 'product/index/$1';
$route['san-pham'] = 'product/index';
// Tag
$route['tag/(:any)/page/(:num)'] = 'product/tag/$1/$2';
$route['tag/(:any)'] = 'product/tag/$1';
// Category
$route['(:any)/page/(:num)'] = 'product/category/$1/$2';
$route['(:any)'] = 'product/category/$1';
Rewrite trang detail
Trang chi tiết sản phẩm ở controller mình nhận hai tham số là slug của tin và id của tin, như vậy UR sẽ có dạng:- domain.com/{tieu-de-cua-san-pham}-{id}.html
// Detail
$route
[
'(:any)-(:num)\.html'
] =
'product/detail/$1/$2'
;
// Home
$route
[
'san-pham/page/(:num)'
] =
'product/index/$1'
;
$route
[
'san-pham'
] =
'product/index'
;
// Tag
$route
[
'tag/(:any)/page/(:num)'
] =
'product/tag/$1/$2'
;
$route
[
'tag/(:any)'
] =
'product/tag/$1'
;
// Category
$route
[
'(:any)/page/(:num)'
] =
'product/category/$1/$2'
;
$route
[
'(:any)'
] =
'product/category/$1'
;
Tổng kết
Làm theo hướng dẫn như trên mà áp dụng vào web thì nó chưa chạy được đâu các bạn à. Để chạy được chúng ta cần phải chỉnh sửa thêm 1 trường slug vào trong csdl(nó phải là duy nhất như id nhé). Trường này có thế là tên bài viết, tên category, tên tag được biến đổi theo dạng thân thiện với SEO như là: day-la-tieu-de-bai-viet. Chúng ta có thể dùng 1 hàm trong php để biến đổi tiêu đề thành slug như vậy.
Sau đó chúng ta cần phải thay đổi đường link trong code của web về dạng sử dụng slug thay vì dùng id như thông thường.
Bài này còn nhiều sai sót do nên ai có thắc mắc gì cứ hỏi mình sẽ sớm update lại.