Một số lưu ý khi làm việc với CodeIgniter
Ngày 3 tháng 4 năm 2013
Nhiều trường hợp bạn phải xác định các đường dẫn tuyệt đối/tương đối tới vị trí của CI trên ổ đĩa (khi ghi file, upload, download chẳng hạn). Đừng bao giờ hardcode các đường dẫn này vì nếu có một ngày bạn phải upload code lên server bạn sẽ có thể phát khóc vì nó. Hãy dùng các hằng số cơ bản đã được CI định nghĩa sẵn:
Giả sử bạn lưu code ở D:\xamp\http\myproject\<CI ở đây>APPPATH: Đường dẫn tới thư mục application. Hằng này có giá trị là D:\xamp\http\myproject\application
FCPATH: Đường dẫn tới thư mục gốc của CI. Hằng này có giá trị là D:\xamp\http\myproject
VIEWPATH: Đường dẫn tới thư mục chứa views. Hằng này có giá trị là D:\xamp\http\myproject\application\views
2. Đừng bao giờ đổi giá trị $config['base_url'] trong config.php
Thông thường ở localhost bạn hay chạy CI với một thư mục con chứ ít khi chạy ở webroot, ví dụ đường dẫn là http://localhost/<myproject>.
Và bạn cũng hay đổi config như sau:
$config['base_url'] = 'http://localhost/<myproject>';
Điều đó là không cần thiết. CI tự động xác định được chính xác đường dẫn này nếu bạn để trống giá trị này của nó, điều đó bảo đảm bạn có thể copy và cài đặt mã nguồn của bạn ở bất kỳ đâu mà không cần phải quan tâm tới thư mục cài đặt hay đường dẫn thực tế. Vì vậy tốt nhất hãy để như sau:
$config['base_url'] = '';
3. Phân biệt site_url và base_url:
Function base_url() thì hầu như ai cũng nghe nói tới, nhưng site_url() thì mình thấy nhiều người còn không biết tới nó. Dẫn tới nhiều trường hợp site không chạy hoặc chạy nhưng css, js và hình ảnh không lên, các liên kết không click được.4. $config['compress_output'] và $config['minify_output'] trong config.php
Bây giờ quay lại file config/config.php, kiểm tra 2 dòng sau:$config['base_url'] = '';Giả sử giá trị của 2 dòng đó như trên, trong trường hợp này:
$config['index_page'] = 'index.php';$l = site_url() sẽ trả về: http://localhost/project/index.phpNhư vậy, nếu bạn muốn tạo một địa chỉ để đưa vào thẻ a hay vào ajax, bạn phải dùng site_url() thay vì base_url. Nếu không liên kết của bạn sẽ không hoạt động do thiếu "index.php";
$l = base_url() sẽ trả về: http://localhost/project/
Còn nếu bạn muốn tạo một địa chỉ để lấy file hình ảnh, js, css bạn phải dùng base_url nếu không sẽ không hoạt động do link tới những file này không thể có "index.php" ở giữa được.
Có bạn sẽ hỏi mình là làm vậy có được không:$l = base_url() . "index.php";Tất nhiên là được, nó vẫn sẽ chạy, nhưng đến một ngày nào đó bạn muốn rewrite để bỏ index.php trong url của bạn, và đổi config thành như sau:$config['base_url'] = '';Lúc này bạn sẽ phải quét toàn bộ mã nguồn của bạn, xem chỗ nào có dùng lệnh nối thêm cái đuôi "index.php" để xoá nó đi, đúng không nào?
$config['index_page'] = '';
Từ CI 2 trở lên bạn có thể dùng site_url với tham số bên trong:Thay vì viếtTừ CI 3 trở lên, base_url cũng hỗ trợ cách tương tự:$l = site_url() . 'index/action/param';Bạn có thể viết:$l = site_url('index/action/param');Thay vì viết$l = base_url() . 'index/action/param';Bạn có thể viết:$l = base_url('index/action/param');
CI mặc định hỗ trợ nén nội dung file đã render trước khi trả về client, điều này giúp website của bạn chạy nhanh hơn và ít tốn băng thông hơn do dữ liệu nén sẽ nhỏ hơn khi truyền tải từ server về client. Để thực hiện điều này, chỉ cần đơn giản chỉnh config như sau:5. Không nên lạm dụng $this->uri->segment(n)$config['compress_output'] = true;Ngoài ra, từ phiên bản CI 3.0 trở lên, CI còn hỗ trợ tính năng tự động tối ưu hoá mã HTML và javascript trả về, điều này sẽ tiết kiệm băng thông hơn, ngoài ra còn khiến cho mã trả về trở nên khó đọc hơn và khó bị ăn cắp hơn ;). Để bật tính năng này chỉ cần chỉnh:$config['minify_output'] = TRUE;
Nếu bạn đã từng làm việc với Zend, mình không ngạc nhiên khi trong code bạn lấy tham số bằng function $this->uri->segment(n). Tuy nhiên, khi sử dụng CI hãy theo phong cách của CI.
Ví dụ, bạn có thể viết:
class Index_Controller extends Base_Controller
{
function Index()
{
$id = $this->uri->segment(1);
$company = $this->uri->segment(2);
$region = $this->uri->segment(3);
$condition = $this->uri->segment(4);
.....
}
}
Vậy tại sao không theo phong cách của CI mà viết:
class Index_Controller extends Base_Controller
{
function Index($id, $company, $region, $condition)
{
.....
}
}
Với cách đưa toàn bộ tham số lên như vậy, người đọc có thể dễ dàng biết được đâu là tham số lấy từ URL, đâu là biến khai báo bên trong function. Một cách để làm code trở nên trong sáng hơn.
Thêm nữa, là nếu buồn buồn, có yêu cầu bổ sung thêm tham số nào ở giữa những tham số đã có thì bạn không phải đi tìm và sửa lại segment của tất cả các tham số sau nó. Và lỡ nếu bạn quên thì kết quả còn tệ hại hơn nhiều. Ví dụ với yêu cầu trên, bây giờ người ta muốn bỏ đi tham số $company không cần dùng nữa, với cách code của CI bạn chỉ cần xoá nó đi là xong, nhưng với cách lấy từ segment bạn sẽ phải sửa lại code của tất cả các tham số đầu vào.
Và tiện lợi hơn, là bạn không còn phải ngồi đếm thứ tự các tham biến, không phải lo về chuyện đổi trật tự của chúng nữa.
Trong trường hợp có những tham số có lúc có, lúc không cách code cũng rất đơn giản. Ví dụ đoạn phân trang như sau:
class Index_Controller extends Base_Controller
{
function Listing($start = 0)
{
.....
}
}
Nếu bạn vào link http://localhost/project/index/listing thì CI sẽ hiểu $start lúc này bằng 0.
Nếu bạn vào link http://localhost/project/index/listing/10 thì CI sẽ hiểu $start lúc này bằng 10.
Bạn không cần phải lấy segment(1) ra rồi check empty và gán mặc định nữa, CI đã làm điều đó.
Một thuận lợi nữa là với cách viết này, bạn có thể truyền tham số lên theo phương thức GET, CI sẽ tự động map vào các giá trị tương ứng. Cho nên các trang vừa nhận tham số từ link vừa nhận tham số từ một form hay ajax gửi lên theo phương thức GET sẽ không gặp trở ngại gì nữa. Ví dụ với function Index($id, $company, $region, $condition) đường link có thể là:
http://localhost/project/index?id=1®ion=3&company=4&condition=abcd
Đang tải dữ liệu...