Lớp Pagination

Nếu bạn không quen với khái niệm "pagination - phân trang", thì bản chất nó là tập hợp các link cho phép ta điều hướng từ trang này sang trang khác theo dạng như sau:

« First  < 1 2 3 4 5 >  Last »

Ví dụ

Dưới đây là một ví dụ đơn giản về cách phân trang, đoạn mã nằm trong một phương thức nào đó của controller:

$this->load->library('pagination');

$config['base_url'] = 'http://example.com/index.php/test/page/';
$config['total_rows'] = 200;
$config['per_page'] = 20;

$this->pagination->initialize($config);

echo $this->pagination->create_links();

Lưu ý

Mảng $config chứa các biến cấu hình của bạn. nó sẽ được truyền tới phương thức $this->pagination->initialize() như thể hiện ở ví dụ trên. Mặc dù có khoảng 20 mục bạn có thể cấu hình, nhưng tối thiểu bạn cần cấu hình ba mục sau đây:

  • base_url: Đây là URL hoàn chỉnh tới controller class/function chứa phần phân trang của bạn. Trong ví dụ trên thì nó trỏ tới controller "Test" và hàm "page". Cần nhớ rằng bạn có thể định tuyến lại URI của bạn nếu muốn có một URL khác.

  • total_rows: Cấu hình tổng số bản ghi trong tập kết quả mà bạn dùng để phân trang. Thông thường thì đó là tổng số bản ghi mà bạn đã truy vấn được từ database.

  • per_page: Cấu hình số bản ghi mỗi trang mà bạn muốn thể hiện. Trong ví dụ trên tôi để là 20 tức là mỗi trang sẽ show 20 bản ghi.

Phương thức create_links() trả về chuỗi rỗng nếu không phân trang được.

Thiết lập các lựa chọn

Nếu bạn không muốn thiết lập các lựa chọn giống như ví dụ trên thì bạn có thể làm theo ý bạn bằng cách tạo một tập tin mới gọi là pagination.php, sau đó thêm một mảng có tên $config vào file đó, rồi lưu trữ file đó vào application/config/pagination.php và sau đó nó sẽ được sử dụng một cách tự động, tức là bạn sẽ không cần phải sử dụng phương thức $this->pagination->initialize().

Tùy chỉnh việc phân trang

Dưới đây là một danh sách tất cả các lựa chọn ta có thể truyền tới hàm khởi tạo để thiết kế sự hiển thị.

$config['uri_segment'] = 3;

Hàm phân trang sẽ tự động xác định số lượng đoạn của URI của bạn chứa số trang.

$config['num_links'] = 2;

Xác định số lượng link mà bạn muốn trước và sau trang đã được click. Ví dụ như nếu bạn đặt là 2 như ở trên thì hệ thống sẽ đặt hai con số mỗi bên ở hai bên trang đã được click, chẳng hạn bạn đã click trang 3 thì trước đó sẽ hiển thị 1 và 2, sau đó sẽ hiển thị 4 và 5.

$config['use_page_numbers'] = TRUE;

Mặc định thì đoạn URI sẽ sử dụng chỉ số cho việc phân trang, nếu bạn muốn thể hiện số trang thực sự thì bạn thiết lập là TRUE giống như trên.

$config['page_query_string'] = TRUE;

Mặc định thì thư viện phân trang giả sử rằng bạn đang sử dụng  Các đoạn URI, và cấu trúc các link của bạn theo dạng sau:

http://example.com/index.php/test/page/20

Nếu bạn đặt $config['enable_query_strings'] thành TRUE thì các link của bạn sẽ tự động được chuyển sang dạng chuỗi truy vấn (Query Strings), khi đó link phân trang của bạn sẽ có dạng:

http://example.com/index.php?c=test&m=page&per_page=20

Lưu ý rằng biến "per_page" là biến mặc định, ta có thể thay tên bằng cách như sau:

$config['query_string_segment'] = 'your_string'

$config['reuse_query_string] = FALSE;

Mặc định các đối số của chuỗi truy vấn của bạn sẽ bị bỏ qua. Thiết lập cấu hình này thành TRUE sẽ thêm chuỗi truy vấn vào URL như sau:

http://example.com/index.php/test/page/20?query=search%term

Điều này sẽ giúp bạn kết hợp các đoạn URI với chuỗi truy vấn. Tuy nhiên, cấu hình này chỉ có từ phiên bản CI 3.0.

$config['prefix'] = '';

Thiết lập tiền tố vào đường dẫn. Tiền tố sẽ nằm ngay trước đoạn cuối cùng.

$config['suffix'] = '';

Thêm một hậu tố vào đường dẫn. Hậu tố sẽ được đặt ngay sau đoạn cuối cùng. Những hậu tố phổ biên như '.html', '.chn', ...

$config[‘use_global_url_suffix’] = FALSE;

Nếu đặt là TRUE thì nó sẽ ghi đè giá trị $config['suffix'] và thiết lập nó thành giá trị có trong $config['url_suffix'] trong tập tin application/config/config.php.

Thêm thẻ HTML

Nếu bạn muốn bao ngoài phần phân trang bằng một thẻ nào đó thì bạn làm như sau:

$config[‘full_tag_open’] = ‘<p>’;

Khi này thẻ mở sẽ được đặt ở bên trên phần phân trang.

$config[‘full_tag_close’] = ‘</p>’;

Còn thẻ đóng sẽ được đặt ở bên dưới phần phân trang.

Ẩn các trang

Nếu bạn không muốn liệt kê các trang cụ thể (ví dụ như bạn chỉ muốn hiển thị các liên kết “next” và “previous” chẳng hạn) thì bạn làm như sau:

$config['display_pages'] = FALSE;

Thêm thuộc tính cho các link

Nếu bạn muốn thêm một thuộc tính nào đó cho link thì bạn có thể thiết lập cặp key/value như sau:

// Sẽ tạo ra: class="myclass"
$config['attributes'] = array('class' => 'myclass')

Không cho phép dùng thuộc tính "rel"

Mặc định thì thuộc tính rel là thuộc tính động và được tạo cũng như thêm vào từng link một. Nếu bạn không muốn sử dụng thuộc tính này thì bạn làm như sau:

$config['attributes']['rel'] = FALSE;

Nguồn: https://codeigniter.com/user_guide/libraries/pagination.html

Giới thiệu

CI là một nền tảng ứng dụng web (web application framework) nguồn mở được dùng để xây dựng các ứng dụng web động tương tác với PHP. Nó cho phép các nhà phát triển xây dựng một ứng dụng web nhanh hơn - so với việc viết mã hỗn tạp - bằng cách cung cấp một bộ thư viện đầy đủ cho các tác vụ thông thường, cũng như cung cấp một mô hình tương tác đơn giản và dễ hiểu cho việc kết nối tới những bộ thư viện đó. Phiên bản chính thức đầu tiên của CI được công bố vào 28 tháng 2 năm 2006. Phiên bản mới nhất cho tới bây giờ là 3.0.6 (năm 2016).

CI khuyến khích các lập trình viên sử dụng mô hình Model-View-Controller cho các ứng dụng web của mình.

CI cũng mang một số các khái niệm đặc thù và các tính năng cơ bản của các mô hình MVC khác như ngôn ngữ Ruby on Rails:

* Hỗ trợ kết nối và tương tác đa nền tảng cơ sở dữ liệu.

* Tương tác với cơ sở dữ liệu thông qua active records.

* Session Management (quản lý Session).

* Định dạng và chuẩn hóa form và dữ liệu đầu vào.

* Hỗ trợ Caching toàn trang để tăng tốc độ thực thi và giảm tải tối thiểu cho máy chủ.

* Scaffolding.

* Hỗ trợ Template Engine hoặc sử dụng chính PHP tags để điều hướng trong Views.

* Hỗ trợ Hooks, các lớp ngoại (Class Extensions), và các Plugins.

So với các mô hình framework MVC khác, CI có các ưu điểm sau :

* Tương thích hoàn toàn với PHP 4. Nếu sử dụng PHP 5 sẽ dùng được các tính năng hữu ích khác như khả năng gọi phương thức dây chuyền (method chaining ability).

* Mô hình code nhẹ cho hệ thống, cải thiện tốc độ thực thi.

* Đơn giản trong việc cài đặt, cấu hình và cấu trúc thư mục.

* Error Logging.

* Mêm dẻo trong việc định tuyến URI (URI Routing).

Framework này tích hợp thêm vào một số lớp thư viện khác mà các framework khác chưa mặc định tích hợp:

* Bảo mật và XSS Filtering.

* Gửi Email, hỗ trợ đính kèm, HTML/Text email, đa giao thức(sendmail, SMTP, and Mail) và các thứ khác.

* Thư viện chỉnh sửa ảnh (cắt ảnh, thay đổi kích thước, xoay ảnh, v.v..). Hỗ trợ GD, ImageMagick, và NetPBM.

* Upload file.

* FTP Class - Tương tác với máy chủ thông qua giao thức FTP.

* Localization.

* Phân trang tự động.

* Mã hóa dữ liệu - Data Encryption.

* Đo lường tốc độ thực thi - Benchmarking.

* Application Profiling.

* Lịch - Calendaring Class.

* User Agent Class.

* Nén - Zip Encoding Class.

* Trackback Class.

* XML-RPC Library.

* Unit Testing Class.

* Search-engine Friendly URLs.

* Một lượng lớn các hàm hỗ trợ (Helpers).

Sơ đ ng dng:

Sơ đồ hoạt động của CodeIgnitor

Trong đó:

- index.php đóng vai trò tiếp nhận và điều khiển mọi hoạt động của ứng dụng.

- Routing để định tuyến tất cả các yêu cầu từ HTTP cho ứng dụng.

- Caching chỉ được sử dụng khi ứng dụng có sử dụng chức năng lưu bộ đệm (cache).

- Lớp xữ lý bảo mật của ứng dụng.

- Application Controller (và các models, libraries, helpers, plugins, ...) là các điều khiển, xử lý của ứng dụng.

- View trả về kết quả cho trình duyệt hiển thị. Nếu ứng dụng có sử dụng chức năng cache thì view coi như đã được kích hoạt.

Lớp Upload File

Lớp Upload File của CodeIgniter cho phép upload các tập tin. Ta có thể thiết lập các tùy chọn khác nhau, hạn chế kiểu và kích thước file.

Để upload một file ta thực hiện các bước sau đây:

  • Tạo một form upload, cho phép người dùng chọn 1 file để upload.

  • Khi submit form thì tập tin sẽ được upload tới đích bạn muốn.

  • Xác nhận tính hợp lệ của tập tin để đảm bảo rằng nó được phép upload dựa trên những tùy chỉnh mà bạn thiết lập.

  • Sau thi upload thành công thì đưa ra thông báo để người dùng biết.

Tạo form upload

Sử dụng text editor bạn tạo một form upload_form.php, đặt mã lệnh như sau và lưu nó trong thư mục application/views/:

<html>
<head>
<title>Upload Form</title>
</head>
<body>

<?php echo $error;?>

<?php echo form_open_multipart('upload/do_upload');?>

<input type="file" name="userfile" size="20" />

<br /><br />

<input type="submit" value="upload" />

</form>

</body>
</html>

Bạn lưu ý là ta đang sử dụng một form helper để tạo thẻ mở <form>. Để upload tập tin thì form cần phải có kiểu multipart, do vậy bộ helper đã tạo sẵn cú pháp này cho bạn. Bạn cũng sẽ lưu ý là ta có một biến $error. Biến này sẽ đưa ra thông báo lỗi nếu người dùng thực hiện sai điều gì đó.

Trang success

Tạo một form gọi là upload_success.php trong thư mục application/views/  và đặt đoạn mã sau vào:

<html>
<head>
<title>Upload Form</title>
</head>
<body>

<h3>Your file was successfully uploaded!</h3>

<ul>
<?php foreach ($upload_data as $item => $value):?>
<li><?php echo $item;?>: <?php echo $value;?></li>
<?php endforeach; ?>
</ul>

<p><?php echo anchor('upload', 'Upload Another File!'); ?></p>

</body>
</html>

Controller

Tạo một controller gọi là Upload.php trong thư mục application/controllers/ và đặt đoạn mã sau vao:

<?php

class Upload extends CI_Controller {

        public function __construct()
        {
                parent::__construct();
                $this->load->helper(array('form', 'url'));
        }

        public function index()
        {
                $this->load->view('upload_form', array('error' => ' ' ));
        }

        public function do_upload()
        {
                $config['upload_path']          = './uploads/';
                $config['allowed_types']        = 'gif|jpg|png';
                $config['max_size']             = 100;
                $config['max_width']            = 1024;
                $config['max_height']           = 768;

                $this->load->library('upload', $config);

                if ( ! $this->upload->do_upload('userfile'))
                {
                        $error = array('error' => $this->upload->display_errors());

                        $this->load->view('upload_form', $error);
                }
                else
                {
                        $data = array('upload_data' => $this->upload->data());

                        $this->load->view('upload_success', $data);
                }
        }
}
?>

Thư mục upload

Bạn tạo một thư mục để chưa file sau khi upload, đặt tên thư mục là uploads và đặt thư mục này cùng vị trí với tập tin index.php ngoài cùng, thiết lập quyền cho thư mục là 777.

Thử nghiệm

Bạn gõ đường link sau và thực hiện:

example.com/index.php/upload/

Tiến hành upload thử một file ảnh (dạng jpg, gif hoặc png). Nếu đường dẫn trong controller đúng thì nó sẽ làm việc.

Gợi ý

Khởi tạo lớp Upload

Lớp Upload được khởi tạo trong controller bằng cách sử dụng câu lệnh sau:

$this->load->library('upload');

Mỗi khi lớp này được load thì đối tượng sẽ được phép sử dụng: $this->upload.

Thiết lập tùy chọn

Trong controller đã xây dựng ở trên ta thiết lập các tùy chọn như sau:

$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size']     = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';

$this->load->library('upload', $config);

// Bạn cũng có thể thiết lập tùy chọn bằng cách gọi phương thức initialize(). Nó hữu dụng nếu bạn sử dụng lớp auto-load:
$this->upload->initialize($config);

Mô tả các tùy chọn

Bảng dưới đây trình bày và mô tả về các tùy chọn. Giá trị mặc định sẽ chỉ ra rằng nó sẽ được sử dụng nếu ta không đưa ra tùy chọn cụ thể.

Tùy chọn Giá trị mặc định Lựa chọn Mô tả
upload_path None None Đường dẫn tới thư mục nơi tập tin upload sẽ được đặt tại đó. Thư mục phải cho phép lưu trữ file và đường dẫn có thể là tuyệt đối hoặc tương đối.
allowed_types None None Kiểu mime tương ứng với kiểu của file mà bạn cho phép upload. Thường thì phần mở rộng của file sẽ được sử dụng cho kiểu mime. Ta cũng có thể sử dụng một mảng hoặc một chuỗi phân tách.
file_name None Desired file name Nếu được thiết lập thì CodeIgniter sẽ đổi lại tên tập tin được upload thành tên tương ứng. Đuôi mở rộng của tập tin bạn cũng được quyền thay đổi. Nếu không có đuôi mở rộng thì nó sẽ lấy phần đuôi mở rộng cũ.
file_ext_tolower FALSE TRUE/FALSE (boolean) Nếu đặt là TRUE thì đuôi mở rộng sẽ ở dạng chữ thường
overwrite FALSE TRUE/FALSE (boolean) Nếu đặt là TRUE thì nếu một file có cùng tên với một file khác trong thư mục thì file đó sẽ bị ghi đè. Nếu đặt là FALSE thì sẽ thêm vào tên một con số cho khác với tên file đã có.
max_size 0 None Kích thước tối đa (kilobyte) của file upload. Nếu đặt là 0 thì tương ứng là không giới hạn kích thước. Lưu ý là phần lớp các cài đặt PHP đều có những giới hạn của chính nó và được thể hiện trong tập tin php.ini, thường thì mặc định là 2 MB (2048 KB).
max_width 0 None Độ rộng lớn nhất (đơn vị là pixel) dành cho ảnh. Đặt là 0 thì tương ứng là không giới hạn độ rộng lớn nhất.
max_height 0 None Độ cao lớn nhất (đơn vị là pixel) dành cho ảnh. Đặt là 0 thì tương ứng là không giới hạn.
min_width 0 None Độ rộng nhỏ nhất (đơn vị là pixel) dành cho ảnh. Đặt là 0 thì tương ứng là không giới hạn độ rộng nhỏ nhất.
min_height 0 None Độ rộng nhỏ nhất (đơn vị là pixel) dành cho ảnh. Đặt là 0 thì tương ứng là không giới hạn.
max_filename 0 None Độ dài lớn nhất của tên file ảnh. Đặt là 0 thì tương ứng là không giới hạn.
max_filename_increment 100 None Nếu ghi đè thành FALSE thì sử dụng use this to set the maximum filename increment for CodeIgniter to append to the filename.
encrypt_name FALSE TRUE/FALSE (boolean) Nếu thiết lập là TRUE thì tên file sẽ được chuyển thanh chuỗi mã hóa ngẫu nhiên. Điều này có thể hữu dụng nếu ta muons file được lưu trữ với tên mà người dùng không thể biết khi upload nó.
remove_spaces TRUE TRUE/FALSE (boolean) Nếu thiết lập là TRUE thì bất kỳ một dấu cách nào trong tên file sẽ được chuyển thành dấu gạch dưới, và ta nên dùng tùy chọn này.
detect_mime TRUE TRUE/FALSE (boolean) Nếu được thiết lập là TRUE thì phía trình chủ (server side) sẽ nhận dạng kiểu file mà sẽ được thực hiện để tránh những tấn công kiểu chèn mã độc. Bạn không nên bỏ sử dụng tùy chọn này trừ khi bạn không còn lựa chọn nào khác vì nó sẽ ảnh hưởng đến vấn đề bảo mật.
mod_mime_fix TRUE TRUE/FALSE (boolean) Nếu được đặt là TRUE thì các phần mở rộng của các file sẽ có dấu gạch dưới để tránh kích hoạt. Không nên tắt tùy chọn này nếu thư mục upload của bạn là public vì nó sẽ ảnh hưởng đến vấn đề bảo mật.

Thiết lập các tùy chọn trong tập tin cấu hình

Nếu bạn không muốn các thiết lập các tùy chọn thông qua sử dụng phương thức khởi tạo thì bạn có thể thay thế bằng cách đặt chúng vào tập tin cấu hình, cụ thể là bạn tạo một tập tin mới và đặt tên là upload.php, sau đó đưa vào tập tin một mảng có tên $config, sau đó lưu vào config/upload.php và nó sẽ được sử dụng tự động mà không cần phải sử dụng phương thức $this->upload->initialize() nếu bạn tham chiếu tới tập tin config.

Tham chiếu lớp CI_Upload

initialize($config, $reset)

Tham số:
  • $config (array) – Các tùy chọn
  • $reset (bool) – Thiết lập lại các tùy chọn (không có trong $config) hay không
Trả về:

Thể hiện của lớp CI_Upload

Kiểu trả về:

CI_Upload

do_upload($field)

Tham số:

$field (string) – Tên của trường form

Trả về:

TRUE nếu thành công, FALSE nếu thất bại

Kiểu trả về:

bool

Phương thức này dùng để upload dựa trên những tùy chọn mà bạn đã thiết lập.

Lưu ý
Mặc định thì việc upload tập tin từ một trường của form sẽ được gọi là userfile, và form phải có kiểu "multipart"
<form method="post" action="some_action" enctype="multipart/form-data" />

Nếu bạn muốn thiết lập một trường chỉ đơn giản là để truyền giá trị của nó tới phương thức do_upload() thì bạn làm như sau:

$field_name = "tên_trường";
$this->upload->do_upload($field_name);

display_errors($open, $close)

Tham số:
  • $open (string) – Thẻ mở
  • $close (string) – Thẻ đóng
Trả về:

Các thông báo lỗi có định dạng

Kiểu trả về:

string

Phương thức này dùng để truy xuất bất kỳ một thông báo lỗi nào nếu như phương thức do_upload() trả về false. Lưu ý là phương thức này không hiển thị thông báo tự động mà nó chỉ trả về dữ liệu và ta có thể gán cho nó nếu cần.

Định dạng các lỗi

Theo mặc định thì phương thức trên sẽ gộp tất cả các lỗi trong thẻ <p>. Bạn có thể thiết lập các định dạng của riêng bạn.

$this->upload->display_errors('<p>', '</p>');

data($index)

Tham số:

$index (string) – Trả về phần tử cụ thể của mảng

Trả về:

Thông tin về tập tin đã upload

Kiểu trả về:

Hỗn hợp

Đây là một phương thức helper nó trả về mảng chứa tất cả các dữ liệu liên quan tới tập tin mà bạn đã upload. Dưới đây là nguyên mẫu của mảng:

Array
(
        [file_name]     => mypic.jpg
        [file_type]     => image/jpeg
        [file_path]     => /path/to/your/upload/
        [full_path]     => /path/to/your/upload/jpg.jpg
        [raw_name]      => mypic
        [orig_name]     => mypic.jpg
        [client_name]   => mypic.jpg
        [file_ext]      => .jpg
        [file_size]     => 22.2
        [is_image]      => 1
        [image_width]   => 800
        [image_height]  => 600
        [image_type]    => jpeg
        [image_size_str] => width="800" height="200"
)

Để trả về một phần tử của mảng thì ta làm như sau:

$this->upload->data('file_name'); //Trả về: mypic.jpg

Đây là những mô tả cụ thể cho từng chỉ số mảng trên:

Chỉ số Description
file_name Tên tập tin đã được upload, bao gồm cả phần mở rộng
file_type Kiểu MIME của bộ nhận dạng
file_path Đường dẫn tuyệt đối tới tập tin
full_path Đường dẫn tuyệt đối, bao gồm cả tên của tập tin
raw_name Tên tập tin không có phần mở rộng
orig_name Tên tập tin gốc. Nó chỉ hữu dụng nếu bạn sử dụng tùy chọn mã hóa tên
client_name Tên tập tin được cung cấp từ người dùng trước khi chỉnh sửa bất kỳ một tên file nào hoặc được tăng lên
file_ext Đuôi mở rộng của tập tin
file_size Kích thước tập tin theo đơn vị kilobyte
is_image Tập tin có phải ảnh hay không, 1 là ảnh, 0 không phải ảnh
image_width Độ rộng ảnh
image_height Độ cao ảnh
image_type Kiểu ảnh (thường là phần đuôi mở rộng)
image_size_str Chuỗi chứa độ rộng và độ cao ảnh (thường được đặt trong thẻ <img>

 Nguồn: https://codeigniter.com/user_guide/libraries/file_uploading.html

Lớp Shopping Cart

Lớp Cart cho phép ta thêm các sản phẩm vào session và nó sẽ vẫn ở đó trong khi người dùng duyệt site của ta. Những sản phẩm này có thể được truy xuất và hiển thị theo chuẩn định dạng "shopping cart", cho phép người dùng cập nhật số lượng hoặc xóa sản phẩm từ giỏ hàng.

Quan trọng
Thư viện Cart đã không còn được khuyến khích sử dụng và bạn không nên dùng nữa. Hiện tại nó vẫn còn được giữ lại để đảm bảo sự tương thích ngược.

Lưu ý rằng lớp Cart chỉ cung cấp những chức năng cơ bản về giỏ hàng, nó không cung cấp các chức năng như vận chuyển, ủy quyền thẻ tín dụng và các thành phần xử lý khác.

Khởi tạo lớp Shopping Cart

Quan trọng
Lớp Carts sử dụng lớp Session của CodeIgniter để lưu các thông tin về giỏ hàng vào cơ sở dữ liệu, vì thế trước khi sử dụng lớp Cart thì bạn phải thiết lập một bảng dữ liệu và thiết lập các ưu tiên về session trong tập tin application/config/config.php để sử dụng cơ sở dữ liệu.

Để khởi tạo lớp Shopping Cart trong hàm tạo controller thì ta sử dụng phương thức $this->load->library():

$this->load->library('cart');

Sau khi tải xong thì ta sử dụng lớp này như sau:

$this->cart
Lưu ý
Lớp Cart sẽ tải và khởi tạo tự động lớp Session, vậy nên trừ khi bạn sử dụng các session ở đâu đó trong ứng dụng thì bạn không cần phải tải lớp Session nữa.

Thêm sản phẩm vào giỏ hàng

Để thêm một sản phẩm vào giỏ hàng thì đơn giản là ta chỉ cần truyền một mảng chứa các thông tin về sản phẩm đó tới phương thức $this->cart->insert(). Ví dụ:

$data = array(
        'id'      => 'sku_123ABC',
        'qty'     => 1,
        'price'   => 39.95,
        'name'    => 'T-Shirt',
        'options' => array('Size' => 'L', 'Color' => 'Red')
);

$this->cart->insert($data);
Quan trọng
Bốn chỉ số đầu tiên của mảng (id, qty, price, và name) là bắt buộc. Nếu bạn bỏ qua một chỉ số bất kỳ nào thì dữ liệu sẽ không lưu được vào giỏ hàng. Chỉ số thứ 5 (options) là tùy chọn, ta có thể sử dụng nó trong trường hợp muốn đưa thêm thông tin về sản phẩm vào giỏ như kích thước, màu sắc như ở ví dụ trên.

Dưới đây là mô tả chi tiết cho các chỉ số:

  • id - Mỗi sản phẩm đưa vào giỏ hàng phải có giá trị nhận diện duy nhất (unique identifier), thường thì đó là một  “sku” hoặc một giá trị nhận diện do ta quy định.

  • qty - Số lượng (quantity) mỗi sản phẩm đặt mua.

  • price - Giá của mỗi sản phẩm.

  • name - Tên sản phẩm.

  • options - Các tùy chọn khác, chúng là các thuộc tính thêm vào để nhận diện sản phẩm như màu sắc, size, chúng phải được truyền thông qua một mảng.

Ngoài 5 chỉ số ở trên thì trong nội bộ lớp Cart còn có hai chỉ số nữa là rowid và subtotal, vì thế mà bạn cần tránh đặt tên trùng với những chỉ số này khi chèn dữ liệu vào giỏ hàng.

Ngoài ra bạn cũng có quyền thêm vào những chỉ số theo ý của bạn, và bất kỳ dữ liệu nào bạn đưa vào mảng thì đều sẽ được lưu vào session.

$data = array(
        'id'      => 'sku_123ABC',
        'qty'     => 1,
        'price'   => 39.95,
        'name'    => 'T-Shirt',
        'coupon'         => 'XMAS-50OFF'
);

$this->cart->insert($data);

Phương thức insert() sẽ trả về $rowid nếu bạn thêm vào giỏ hàng thành công một sản phẩm.

Thêm nhiều sản phẩm vào giỏ hàng

Bằng cách sử dụng mảng đa chiều như ví dụ dưới đây thì ta có thể thêm một lúc nhiều sản phẩm vào giỏ hàng, điều này rất thuận tiện nếu như gian hàng của bạn cho phép người dùng cùng lúc chọn nhiều sản phẩm và đưa vào giỏ hàng.

$data = array(
        array(
                'id'      => 'sku_123ABC',
                'qty'     => 1,
                'price'   => 39.95,
                'name'    => 'T-Shirt',
                'options' => array('Size' => 'L', 'Color' => 'Red')
        ),
        array(
                'id'      => 'sku_567ZYX',
                'qty'     => 1,
                'price'   => 9.95,
                'name'    => 'Coffee Mug'
        ),
        array(
                'id'      => 'sku_965QRS',
                'qty'     => 1,
                'price'   => 29.95,
                'name'    => 'Shot Glass'
        )
);

$this->cart->insert($data);

Hiển thị giỏ hàng

Ví dụ dưới đây sẽ cho thấy cách thức hiển thị giỏ hàng của bạn, lưu ý là bạn cần đặt đoạn mã dưới vào tập tin trong thư mục views (ví dụ này sử dụng Form Helper):

<?php echo form_open('path/to/controller/update/method'); ?>

<table cellpadding="6" cellspacing="1" style="width:100%" border="0">

<tr>
        <th>QTY</th>
        <th>Item Description</th>
        <th style="text-align:right">Item Price</th>
        <th style="text-align:right">Sub-Total</th>
</tr>

<?php $i = 1; ?>

<?php foreach ($this->cart->contents() as $items): ?>

        <?php echo form_hidden($i.'[rowid]', $items['rowid']); ?>

        <tr>
                <td><?php echo form_input(array('name' => $i.'[qty]', 'value' => $items['qty'], 'maxlength' => '3', 'size' => '5')); ?></td>
                <td>
                        <?php echo $items['name']; ?>

                        <?php if ($this->cart->has_options($items['rowid']) == TRUE): ?>

                                <p>
                                        <?php foreach ($this->cart->product_options($items['rowid']) as $option_name => $option_value): ?>

                                                <strong><?php echo $option_name; ?>:</strong> <?php echo $option_value; ?><br />

                                        <?php endforeach; ?>
                                </p>

                        <?php endif; ?>

                </td>
                <td style="text-align:right"><?php echo $this->cart->format_number($items['price']); ?></td>
                <td style="text-align:right">$<?php echo $this->cart->format_number($items['subtotal']); ?></td>
        </tr>

<?php $i++; ?>

<?php endforeach; ?>

<tr>
        <td colspan="2"> </td>
        <td class="right"><strong>Total</strong></td>
        <td class="right">$<?php echo $this->cart->format_number($this->cart->total()); ?></td>
</tr>

</table>

<p><?php echo form_submit('', 'Update your Cart'); ?></p>

Cập nhật giỏ hàng

Để cập nhật giỏ hàng thì ta cần truyền một mảng chứa id của sản phẩm và các giá trị muốn update tới phương thức $this->cart->update().

Lưu ý
Nếu số lượng được đặt là 0 thì sản phẩm sẽ bị xóa khỏi giỏ hàng.
$data = array(
        'rowid' => 'b99ccdf16028f015540f341130b6d8ec',
        'qty'   => 3
);

$this->cart->update($data);

//Hoặc một mảng đa chiều để update cùng lúc nhiều sản phẩm

$data = array(
        array(
                'rowid'   => 'b99ccdf16028f015540f341130b6d8ec',
                'qty'     => 3
        ),
        array(
                'rowid'   => 'xw82g9q3r495893iajdh473990rikw23',
                'qty'     => 4
        ),
        array(
                'rowid'   => 'fh4kdkkkaoe30njgoe92rkdkkobec333',
                'qty'     => 2
        )
);

$this->cart->update($data);

Bạn cũng có thể update một chỉ số bất kỳ mà bạn đã định nghĩa trước đó ki tiến hành chèn sản phẩm như options, price hay một chỉ số tùy chỉnh của bạn.

$data = array(
        'rowid'  => 'b99ccdf16028f015540f341130b6d8ec',
        'qty'    => 1,
        'price'  => 49.95,
        'coupon' => NULL
);

$this->cart->update($data);

Row ID là gì?

Row ID là giá trị nhận diện duy nhất được tạo ra từ giỏ hàng khi một sản phẩm nào đó được thêm vào giỏ hàng. Lý do của việc tạo ID là để phân biệt các sản phẩm trong giỏ hàng nhằm mục đích quản lý giỏ hàng dễ dàng hơn.

Ví dụ như khi ai đó mua hai chiếc áo T-Shirt (đều cùng ID) khác nhau về size thì ID của sản phẩm (và các thuộc tính khác) sẽ nhận diện chung cho cả hai chiếc áo này vì nó thực ra là cùng một áo, chỉ khác nhau về size. Khi đó giỏ hàng phải có khả năng nhận diện rằng đây là hai chiêc áo khác nhau (hai sản phẩm khác nhau) và được quản lý độc lập nhau, không liên quan đến nhau. Và giỏ hàng thực hiện việc này bằng cách tạo ra “row ID” duy nhất cho từng sản phẩm dựa trên ID sản phẩm và những tùy chọn khác liên quan.

Có thể nói trong tất cả các trường hợp thì việc cập nhật giỏ hàng sẽ được thực hiện khi người dùng xem giỏ hàng, vì thế mà đối với developer thì ta không cần quan tâm về “row ID”, thay vào đó ta cần đảm bảo rằng trang xem giỏ hàng cần chứa "row ID" và cần đảm bảo rằng nó phải được truyền tới phương thức update() khi người dùng thực hiện thao tác cập nhật giỏ hàng.

Tham khảo lớp CI_Cart

$product_id_rules = '.a-z0-9_-'

Đây là các quy tắc biểu thức chính quy ta dùng để kiểm tra sự hợp lệ của ID sản phẩm, chúng có thể các ký tự thường, ký số, dấu gạch giữa, dấu gạch dưới hoặc dấu chấm.

$product_name_rules = 'w -.:'

Đây là các quy tắc áp dụng cho ID và name của sản phẩm, gồm alpha-numeric, gạch giữa, gạch dưới, dấu hai chấm hoặc dấu chấm.

$product_name_safe = TRUE

Có hoặc không việc cho phép các tên sản phẩm ở dạng an toàn. Mặc định là TRUE.

insert([$items = array()])

Tham số:

$items (array) – Các sản phẩm thêm vào giỏ hàng

Trả về:

TRUE nếu thành công, FALSE nếu thất bại

Kiểu trả về:

 bool

Phương thức này dùng để chèn các sản phẩm và giỏ hàng và lưu vào bảng session.

update([$items = array()])

Tham số:

$items (array) – Các sản phẩm muốn cập nhật trong giỏ hàng

Trả về:

TRUE nếu thành công, FALSE nếu thất bại

Kiểu trả về:

 bool

Phương thức này cho phép thay đổi các thuộc tính của sản phẩm trong giỏ hàng, thông thường nó được gọi từ trang xem giỏ hàng nếu người dùng thay đổi số lượng trước khi tiến hành đặt hàng. Lưu ý rằng mảng dữ liệu phải chứa rowid của mỗi sản phẩm muốn cập nhật.

remove($rowid)

Tham số:

$rowid (int) – ID của sản phẩm muốn xóa khỏi giỏ hàng

Trả về:

TRUE nếu thành công, FALSE nếu thất bại

Kiểu trả về:

 bool

total()

Trả về tổng số sản phẩm trong giỏ hàng.

total_items()

Trả về tổng số sản phẩm khác khau trong giỏ hàng.

contents([$newest_first = FALSE])

Tham số:
  • $newest_first (bool) – Sắp xếp mảng với việc đặt sản phẩm mới nhất trước tiên
Trả về:

Mảng giỏ hàng

Kiểu trả về:

 array

Phương thức này sẽ sắp xếp các sản phẩm trong giỏ hàng theo trật tự sản phẩm mới nhất trước nếu đối số truyền vào là TRUE, ngược lại thì nó sắp xếp theo trật tự sản phẩm cũ nhất trước.

get_item($row_id)

Tham số:

$row_id (int) – Truy xuất tới rowID

Trả về:

Mảng dữ liệu về sản phẩm được truy xuất

Kiểu trả về:

 array

Trả về mảng chứa dữ liệu của sản phẩm tương ứng với row ID hoặc trả về FALSE nếu không tìm thấy.

has_options($row_id = '')

Parameters:

$row_id (int) – Row ID để kiểm tra

Trả về:

TRUE nếu thấy, FALSE nếu ngược lại

Kiểu trả về:

 bool

Phương thức trả về TRUE nếu giỏ hàng có chứa tùy chọn. Phương thức này được thiết kế để sử dụng lặp với phương thức contents(), do đó bạn phải truyền rowid tới phương thức này như thể hiện ở ví dụ bên trên.

product_options([$row_id = ''])

Tham số:

$row_id (int) – Row ID

Trả về:

Mảng các tùy chọn của sản phẩm

Kiểu trả về:

 array

Trả về một mảng các tùy chọn của sản phẩm tương ứng. Phương thức này cũng được thiết kế để sử dụng lặp với phương thức contents(), vì thế mà bạn phải truyền rowid tới phương thức này (bạn xem lại ví dụ bên trên để hiểu rõ hơn).

destroy()

Kiểu trả về:  void

Phương thức này dùng để hủy giỏ hàng, nó thường được gọi đến sau khi xử lý xong đơn hàng của khách hàng.

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

Đ cài đt CI, các bn thc hin nhng bước sau:

1. Tải bộ framework CI tại http://codeigniter.com/download

2. Giải nén gói CI bạn sẽ được 3 thư mục (application, system, user_guide) và 2 file cơ bản (index.php, license.txt). Trong đó, thư mục user_guide là thư mục chứa tài liệu hướng dẫn sử dụng CI, file license.txt là file license. Toàn bộ gói CI bạn chỉ quan tâm 2 thư mục application, system và file index.php (đây là toàn bộ gói CI).

3. Copy 2 thư mục application, system và file index.php vào thư mục webroot của server local (sau này gọi là localhost). Tôi sử dụng Wampserver làm server local nên tôi sẽ copy gói CI vào thư mục www.

4. Truy cập địa chỉ http://localhost. Nếu hiện ra trang welcome của CI thì bạn đã cài đặt thành công bước đầu.

5. Cấu hình website với 2 bước:

* Bước 1: Mở file application/config/config.php để cấu hình website. Trong file config.php hiện tại bạn chỉ quan tâm tới $config['base_url']. Bạn tìm đến phần này và cấu hình như sau:

$config['base_url'] = 'http://localhost';

Kinh nghim:

Bạn nên cấu hình như sau:

$config['base_url'] = 'http://'.$_SERVER['HTTP_HOST'];

* Bước 2: Mở file application/config/database.php để cấu hình thông số kết nối cơ sở dữ liệu. Hiện tại, bạn sẽ quan tâm tới 4 thông số sau:

- $db['default']['hostname']: Tên host của cơ sở dữ liệu.

- $db['default']['username']: Username để kết nối tới cơ sở dữ liệu.

- $db['default']['password']: Mật khẩu để kết nối tới cơ sở dữ liệu.

- $db['default']['database']: Tên cơ sở dữ liệu.

Với website này tôi sẽ khai báo như sau:

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'project_ci';

Với các bước trên, bạn đã cài đặt và cấu hình cơ bản cho website sử dụng CI. Các cấu hình khác bạn có thể tìm hiểu thêm hoặc reply lại tại topic đã qui định.

URL

Trong phần này chúng ta sẽ tìm hiểu về cách CI xử lý URL để gọi các controller, method.

Mặc định, URL của CI được thiết kế thân thiện với các máy tìm kiếm, tối ưu SEO bằng cách sử dụng các phân khúc (gọi là segment) thay vì sử dụng URL kiểu truyền thống (query string)

Bạn có thể xem một ví dụ về cách mà CI thiết kế URL:

example.com/news/article/my_article

Tuy nhiên, kiểu URL truyền thống (query string) các bạn cũng có thể sử dụng bằng cách cấu hình trong file application/config/config.php như sau:

$config['enable_query_strings'] = TRUE;

Bây gi ta s phân tích URL sau:

example.com/index.php/class/function/ID

Với URL trên, ta có ba segment là class, functionID. Trong đó:

- Segment class sẽ được CI gọi tới controller tên class (class cũng chính là một lớp).

- Segment function được CI gọi tới phương thc tên function của lớp class ở trên.

- Segment ID được CI hiểu như là 1 biến của phương thức function (Bạn cũng có thể truyền vào nhiều biến).

Để làm việc với các segment của URL, CI đã xây dựng sẳn các helper giúp bạn làm việc với các URI segment 1 cách dễ dàng, vì vậy bạn yên tâm về cách thiết kế URL này của CI.

Loại bỏ index.php

Với URL trên, chúng ta thấy sự xuất hiện của index.php, bạn cũng có thể bỏ index.php bằng cách sử dụng .htaccess (chỉ hoạt động trên server Linux). Code .htaccess để loại bỏ index.php như sau:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

Như vậy, sau khi sử dụng .htaccess ta sẽ có URL thân thiện sau:

example.com/class/function/ID

Thêm phần mở rộng cho URL

Bạn thường thấy một số website có đường URL như sau:

codeigniter.com/user_guide/general/urls.html (Phần đuôi .html).

CI cũng có thể làm được như vậy chỉ với 1 cấu hình đơn giản trong file application/config/config.php:

$config['url_suffix'] = '.html';

lúc đó URL của chúng ta sẽ là:

example.com/class/function/ID.html

Kích hoạt query string

Trong trường hợp bạn muốn sử dụng kiểu URL truyền thống (query string), bạn có thể tiến hành cấu hình kích hoạt trong file application/config/config.php:

$config['enable_query_strings'] = TRUE;
$config['controller_trigger'] = 'c'; //Biến lấy tên controller
$config['function_trigger'] = 'm'; //Biến lấy tên phương thức

Lúc đó, URL của chúng ta sẽ trở thành:

example.com/index.php?c=class&m=function&id=ID

Controller

Controller có thể được xem như trái tim của toàn bộ ứng dụng. Nó điều khiển các yêu cầu HTTP từ người dùng. Tất cả mọi xử lí do người dùng tuơng tác đều được xử lý tại controller. Controller sẽ làm nhiệm vụ giao tiếp giữa các yêu cầu người dùng (hay chính xác hơn đó là các yêu cầu HTTP) với ứng dụng cũng như với cơ sở dữ liệu.

Controller là 1 file class mà nó được đặt tên sao cho có mối liên hệ với URI. Ví dụ với URL sau:

example.com/blog

Với URL trên thì CI sẽ tìm và gọi controller blog.php và ta đặt tập tin controller này trong thư mục application/controllers/blog.php.

Chúng ta sẽ bt đu vi ng dng đu tiên "HELLO WORD!":

Chúng ta sẽ tạo một controller có tên là blog (blog.php) và lưu trong thư mục application/controllers/ với nội dung như sau:

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo 'Hello World!';
    }
}
?>

Với controller được tạo ở trên, bạn sẽ gọi controller này với URL như sau:

example.com/blog

Lúc đó, kết quả mà chúng ta thấy sẽ là câu "Hello World!".

Các bn chú ý v cách to 1 controller:

- File controller phải được đặt tên trùng với tên controller (tên class) và được đặt trong thư mục application/controllers/ (hoặc thư mục con trong application/controllers/).

- Tên controller (chính xác hơn đó là tên của class) phải được viết hoa chữ cái đầu tiên như ví dụ mà bạn thấy (Blog) và controller phải được extends class CI_Controller.

- Mỗi controller luôn luôn có phương thức khởi tạo __construct() với câu lệnh bên trong như bạn thấy ở ví dụ trên:

function __construct()
{
    parent::__construct();
}

Bạn thấy với controller blog trên, ta chỉ cần truy cập URL example.com/blogCI sẽ tự động tìm đến controller blog để thực thi. Vậy tại sao CI hiểu là sẽ gọi tới phương thức index()?. Trả lời: Bởi vì với URL trên thì CI đã hiểu ngầm rằng bạn đang truy cập tới controller blog và đang gọi phương thức index() (Có thể xem phương thức index() là phương thức mà CI sẽ tự động hiểu nếu ta không truyền tên phương thức vào URL).

Chúng ta sẽ xét tiếp 1 ví dụ khác như sau:

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo 'Hello World!';
    }

    function comments()
    {
        echo 'Look at this!';
    }
}
?>

Với ví dụ trên, nếu bạn muốn truy cập tới phương thức comments() để in ra câu "Look at this!" thì bạn sẽ truy cập URL sau:

example.com/blog/comments

Với URL trên, CI sẽ tự động tìm đến phương thức comments() của controller blog và thực thi khối lệnh bên trong phương thức đó, và kết quả là in ra câu "Look at this!".

Tiếp tục xét 1 ví dụ khác, ví dụ lần này ta sẽ truyền vào phương thức comments() biến $id, tức lúc này phương thức sẽ trở thành comments($id):

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo 'Hello World!';
    }

    function comments($id)
    {
        echo 'Look at this! ID comment is '.$id;
    }
}
?>

Với ví dụ trên, bạn truy cập URL sau:

example.com/blog/comments/12

Lúc này, kết quả bạn sẽ thấy là:

Look at this! ID comment is 12

Theo mặc định, CI sẽ xử lý URL và gọi các controller (cũng như phương thức tương ứng) như ta đã thấy ở trên. Ngoài ra, CI còn cung cấp cho chúng ta một "công cụ" giúp cho chúng ta hoàn toàn tùy biến việc thiết kế URL, đó là routes. Về routes tôi sẽ hướng dẫn trong 1 phần khác được đề cập sau.

Tên riêng

Để trợ giúp cho lập trình viên cũng như các developer thì CodeIgniter đã cung cấp sẵn nhiều hàm, phương thức, lớp và các biến, và đương nhiên ta không được dùng đến các tên giống với tên của các thành phần này (còn gọi là tên riêng). Dưới đây là danh sách các tên riêng mà ta không được dùng.

Tên của Controller

Do các lớp controller ta xây dựng sẽ thừa kế từ lớp controller được xây dựng sẵn nên bạn không được tạo lớp controller có tên trùng. Cụ thể, bạn không đặt tên controller của bạn trùng với những tên sau:

  • CI_Controller
  • Default
  • index

Các hàm không được đặt tên trùng

  • is_php()
  • is_really_writable()
  • load_class()
  • is_loaded()
  • get_config()
  • config_item()
  • show_error()
  • show_404()
  • log_message()
  • set_status_header()
  • get_mimes()
  • html_escape()
  • remove_invisible_characters()
  • is_https()
  • function_usable()
  • get_instance()
  • _error_handler()
  • _exception_handler()
  • _stringify_attributes()

Các biến không được đặt tên trùng

  • $config
  • $db
  • $lang

Các hằng không được đặt tên trùng

  • ENVIRONMENT
  • FCPATH
  • SELF
  • BASEPATH
  • APPPATH
  • VIEWPATH
  • CI_VERSION
  • MB_ENABLED
  • ICONV_ENABLED
  • UTF8_ENABLED
  • FILE_READ_MODE
  • FILE_WRITE_MODE
  • DIR_READ_MODE
  • DIR_WRITE_MODE
  • FOPEN_READ
  • FOPEN_READ_WRITE
  • FOPEN_WRITE_CREATE_DESTRUCTIVE
  • FOPEN_READ_WRITE_CREATE_DESTRUCTIVE
  • FOPEN_WRITE_CREATE
  • FOPEN_READ_WRITE_CREATE
  • FOPEN_WRITE_CREATE_STRICT
  • FOPEN_READ_WRITE_CREATE_STRICT
  • SHOW_DEBUG_BACKTRACE
  • EXIT_SUCCESS
  • EXIT_ERROR
  • EXIT_CONFIG
  • EXIT_UNKNOWN_FILE
  • EXIT_UNKNOWN_CLASS
  • EXIT_UNKNOWN_METHOD
  • EXIT_USER_INPUT
  • EXIT_DATABASE
  • EXIT__AUTO_MIN
  • EXIT__AUTO_MAX

View

View là một trang web hay một phần của trang web như header, footer, sidebar... Bạn hiểu đơn giản, view chỉ là những file HTML định hình trang web (phần lớn đều có chèn code PHP để lấy dữ liệu động). Thông thường, toàn bộ những gì bạn thấy trên trình duyệt thì đó được xem như là 1 view.

Về cơ bản, view không thể được gọi trực tiếp mà nó luôn được gọi thông qua một controller theo đúng mô hình MVC nổi tiếng.

Tạo view

Bạn tạo một tập tin (chẳng hạn tên là blogview.php) trong thư mục application/views như sau:

<html>
<head>
<title>My Blog</title>
</head>
<body>
    Welcome to my Blog!
</body>
</html>

Gọi view từ controller

Để gọi view, bạn sử dụng cú pháp sau:

$this->load->view('name');

Với view_name là tên file view bạn muốn load nhưng không kèm theo phần mở rộng (.php). Như vậy, với file blogview.php đã tạo ở trên chúng ta sẽ có cú pháp gọi file blogview.php như sau:

$this->load->view('blogview');

Bạn tạo một controller blog với nội dung lệnh như sau:

<?php
class Blog extends CI_Controller {
  public function index(){
    $this->load->view('blogview');
  }
}

Khi bạn truy cập URL sau:

example.com/index.php/blog

Kết quả sẽ là:

Welcome to my Blog!

Tải nhiều view

Bạn cũng có thể load nhiều view trong 1 controller như ví dụ sau:

<?php
class Page extends CI_Controller {
  public function index(){
    $data['page_title'] = 'Your title';
    $this->load->view('header');
    $this->load->view('menu');
    $this->load->view('content', $data);
    $this->load->view('footer');
  }
}
?>

Lưu trữ view trong thư mục con

Trường hợp bạn tạo view bên trong một thư mục con của thư mục application/views (ví dụ tôi đặt file blogview.php trong thư mục application/views/subfolder) bạn có thể sử dụng cú pháp lệnh sau để gọi view:

$this->load->view('subfolder/blogview');

Truyền dữ liệu từ controller ra view

Toàn bộ quá trình xử lý tương tác dữ liệu đều được thực hiện ở controller (trừ việc lấy dữ liệu từ database là thực hiện ở model sẽ nói sau) nên kết quả trả về sẽ nằm trong controller. Vậy làm cách nào để truyền dữ liệu này ra ngoài view để ta có thể trình bày theo ý muốn? Với CI thì công việc này rất đơn giản: Bạn chỉ việc gán toàn bộ các dữ liệu muốn truyền ra view vào 1 mảng và truyền vào tham số thứ 2 của phương thức load view như ví dụ dưới đây:

$data = array(
               'title' => 'HTML5',
               'heading' => 'Giới thiệu HTML5',
               'message' => 'Thông báo'
          );

$this->load->view('blogview', $data);

Với ví dụ trên, khi ra ngoài blogview bạn sẽ có ngay các biến là $title, $heading $message (tương ứng với tên chỉ số của phần tử mảng) để sử dụng.

Chúng ta xét ví dụ hoàn chỉnh sau:

Tạo controller blog (application/controllers/blog.php) với nội dung sau:

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $data = array(
               'title' => 'HTML5',
               'heading' => 'Giới thiệu HTML5',
               'message' => 'Thông báo'
        );
       
        //Load view
        $this->load->view('blogview', $data);
    }
}
?>

Tạo view blogview (application/views/blogview.php) với nội dung sau:

<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
    <h1><?php echo $heading; ?></h1>
    <?php echo $messagge; ?>
</body>
</html>

Bạn truy cập URL:

example.com/blog

Chúng ta sẽ có kết quả:

Giới thiệu HTML5

Thông báo

(Lưu ý: Chuỗi "HTML5" thì xut hin trên thanh tiêu đ ca trình duyt).

Khi dữ liệu được truyền từ controller ra view sẽ vẫn gi nguyên kiu d liu. Ví dụ kiểu dự trong controller là chuỗi (string) thì ngoài view cũng sẽ là chuỗi. Tương tự, kiểu mảng (array), kiểu đối tượng (object),... khi truyền ra view vn gi nguyên kiu d liu.

Tạo vòng lặp

Mảng dữ liệu truyền tới view không chỉ giới hạn ở các biến đơn. Ta có thể truyền nhiều mảng động để từ đó có thể tiến hành lặp để tạo nhiều hàng. Ví dụ, nếu bạn lấy dữ liệu từ database thì dữ liệu sẽ có dạng là một mảng đa chiều.

Dưới đây là một ví dụ minh họa.

Bạn đưa đoạn code sau vào controller:

<?php
class Blog extends CI_Controller {

  public function index(){
    $data['todo_list'] = array('Clean House', 'Call Mom', 'Run Errands');
    $data['title'] = "My Real Title";
    $data['heading'] = "My Real Heading";

    $this->load->view('blogview', $data);
  }

}

Bạn mở view để tạo một vòng lặp:

<html>
<head>
        <title><?php echo $title;?></title>
</head>
<body>
        <h1><?php echo $heading;?></h1>

        <h3>My Todo List</h3>

        <ul>
        <?php foreach ($todo_list as $item):?>

                <li><?php echo $item;?></li>

        <?php endforeach;?>
        </ul>

</body>
</html>
Lưu ý
Ví dụ trên sử dụng cú pháp thay thế của PHP. Nếu bạn chưa rõ về cú pháp thay thế này bạn có thể xem tại ĐÂY.

Trả về view dưới dạng dữ liệu

Trong lời gọi view từ controller có tham số tùy chọn thứ ba, tham số này giúp ta thay đổi hành vi của phương thức theo đó phương thức sẽ trả về dữ liệu dưới dạng chuỗi chứ không phải là gửi nó tới trình duyệt. Điều này có thể có ích nếu ta muốn xử lý dữ liệu theo một hướng nào đó. Nếu bạn đặt tham số thứ ba này là TRUE (boolean) thì việc gọi view sẽ tương ứng với việc trả về dữ liệu. Mặc định thì phương thức sẽ trả về FALSE và thông tin sẽ được gửi tới trình duyệt. Bạn cần gán giá trị trả về cho một biến nếu bạn muốn sử dụng dữ liệu trả về đó. Cú pháp cụ thể như sau:

$string = $this->load->view('myfile', '', TRUE);

Model

Model là 1 lớp PHP được thiết kế để tương tác với cơ sở dữ liệu của bạn. Chẳng hạn như bạn viết một trang blog sử dụng CI thì thường bạn sẽ có các thao tác với cơ sở dữ liệu như select, insert, delete, update. Và tất nhiên, vai trò của model là để thực hiện những công việc này.

Chúng ta xét 1 ví dụ dưới đây:

class Blogmodel extends CI_Model {

    var $title   = '';
    var $content = '';
    var $date    = '';

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
    }
    
    function get_last_ten_entries()
    {
        $query = $this->db->get('entries', 10);
        return $query->result();
    }

    function insert_entry()
    {
        $this->title   = $_POST['title']; // please read the below note
        $this->content = $_POST['content'];
        $this->date    = time();

        $this->db->insert('entries', $this);
    }

    function update_entry()
    {
        $this->title   = $_POST['title'];
        $this->content = $_POST['content'];
        $this->date    = time();

        $this->db->update('entries', $this, array('id' => $_POST['id']));
    }

}

Với vị dụ trên, model Blogmodel đã định nghĩa ra các phương thức như get_last_ten_entries(), insert_entry() hay update_entry(). Tất cả các phương thức này đều tương tác với cơ sở dữ liệu để lấy dữ liệu lên hay thêm mới, chỉnh sửa dữ liệu.

Một model (hay còn gọi class model) được tạo và đặt trong thư mục application/models. Và 1 điều lưu ý, tên file phải trùng với tên của class model nhưng viết thường (giống với controller). Với ví dụ trên thì ta sẽ có file application/models/blogmodel.php. Ngoài ra 1 class model luôn luôn extends CI_Model. Một class model có nội dung tương tự như sau:

class Model_name extends CI_Model {

    function __construct()
    {
        parent::__construct();
    }
}

Để sử dụng 1 model, trước tiên bạn phải load model đó. Ví dụ để sử dụng blogmodel ở trên, bạn sẽ phải load blogmodel trước khi sử dụng các phương thức như get_last_ten_entries(), insert_entry() hay update_entry() với cú pháp sau:

$this->load->model('blogmodel');

Chúng ta xét lại controller blog ở phần trước, các bạn muốn sử dụng blogmodel cho controller blog thì controller blog sẽ có nội dung như sau:

class Blog extends CI_Controller {

     function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $this->load->model('Blogmodel');

        $data['query'] = $this->Blogmodel->get_last_ten_entries();

        $this->load->view('blog', $data);
    }
}

Trong ví dụn trên, ngoài cú pháp load blogmodel thì bạn còn cần phải chú ý tới câu lệnh sau:

$data['query'] = $this->Blogmodel->get_last_ten_entries();

Đây là câu lệnh gọi tới phương thức get_last_ten_entries() và gán cho $data['query']. Như vậy để gọi tới các phương thức được định nghĩa trong một model, CI đã thiết kế 1 cách gọi như sau:

$this->model_name->method();

Bạn chú ý: model_name là tên của model và phải viết thườngmethod() là một phương thức trong class model. Đây cũng là cách sử dụng chung cho các thư viện của CI.

Để làm việc với model, các bạn còn phải tìm hiểu thêm về thư viện Database và tôi sẽ đề cập sau. Thư viện Database định nghĩa sẵn các phương thức tương tác an toàn với cơ sở dữ liệu và có lẽ đây là một thư viện chứa nhiều phương thức nhất của CI.

Helper

Những phần trước các bạn đã làm quen với CI, chỉ với những phần trên bạn đã có thể viết ứng dụng web của mình bằng CI rôi. Ở phần này, tôi sẽ giới thiệu về các hàm (function) trợ giúp (gọi là helper) giúp cho công việc viết code của bạn trở nên đơn giản hơn rất nhiều.

Helper đó là cách gọi dành cho các function đã được CI (hoặc kể cả người dùng) định nghĩa sẵn để sử dụng trong ứng dụng của mình một cách nhanh chóng. CI đã cung cấp sẵn rất nhiều helper giúp bạn làm việc với CI nhanh chóng hơn nhiều. Một số helper được CI định nghĩa và theo tôi nó được sử dụng thường xuyên nhất đó là: url, form, language, captcha, email, ...

Load một Helper

Việc sử dụng một helper rất đơn giản, trước tiên bạn load helper cần sử dụng bằng cú pháp sau:

$this->load->helper('tên_helper');

Ví dụ bạn muốn load helper url trong controller blog, bạn sẽ có đoạn code như sau:

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $this->load->helper('url'); //Load helper url
       
        echo base_url(); //Sử dụng một hàm trong helper url
    }
}
?>

Như ví dụ trên, helper url được load bởi câu lệnh $this->load->helper('url'); và hàm base_url() trong helper url được sử dụng với lời gọi hàm bình thường mà chúng ta vẫn biết trong PHP.

Load nhiều Helper một lúc

Chúng ta cũng có thể load một lúc nhiều helper bằng cú pháp lệnh như sau:

$this->load->helper(
        array('helper1', 'helper2', 'helper3')
);

Ví dụ, bạn muốn load các helper url, form, language bạn sẽ có cú pháp như sau:

$this->load->helper(
        array('url', 'form', 'language')
);

Việc sử dụng các hàm được định nghĩa sẳn trong helper như tôi đã nói ở trên là chúng ta sẽ gọi hàm bình thường như trong PHP.

Tự động load Helper

Nếu trong trường hợp bạn cần sử dụng một helper nào đó một cách thường xuyên trong ứng dụng thì bạn có thể yêu cầu CodeIgniter tự động load helper đó mỗi khi khởi tạo hệ thống. Việc này được thực hiện bằng cách mở tập tin application/config/autoload.php và tìm đến dòng lệnh $autoload['helper'] = array(); rồi thêm helper vào. Ví dụ như nếu bạn muốn tự động load helper url form bạn làm như sau:

$autoload['helper'] = array('url', 'form');

Sử dụng Helper

Một khi bạn đã load xong Helper có chứa hàm mà bạn muốn dùng thì bạn có quyền sử dụng (gọi) hàm đó theo cách gọi hàm thông thường trong PHP.

Ví dụ như để tạo một link ta có thể sử dụng phương thức anchor() như sau:

<?php echo anchor('blog/comments', 'Click Here');?>

Trong đó "Click Here" là tên link  và "blog/comments" là URI tương ứng với controller/method mà bạn muốn link tới.

Thừa kế Helper

Ngoài những helper do CI định nghĩa sẵn (và được lưu trong thư mục system/helpers) thì chúng ta cũng có thể tự tạo ra các helper riêng bằng cách thừa kế từ những helper có sẵn đó.

Để thừa kế một Helper nào đó, trước tiên ta tạo một tập tin trong thư mục application/helpers/ với tên giống hệt với tên của Helper bạn muốn thừa kế nhưng phần tiền tố bạn thêm MY_.

Lưu ý
Thuật ngữ Thừa kế (Extend) được dùng với ý nghĩa không như theo các chương trình truyền thống như Java hay C# vì các hàm của mỗi Helper là các thủ tục và rời rạc và vì vậy không thể được thừa kế theo nghĩa truyền thống. Nhưng điều này giúp ta có thể thêm hoặc thay thế các hàm có sẵn của mỗi Helper.

Ví dụ, để thừa kế helper Array thì ta tạo một tập tin có tên và vị trí là application/helpers/MY_array_helper.php, rồi thêm hoặc ghi đề các hàm sau:

// any_in_array() không có sẵn trong helper Array, nên nó được định nghĩa như là một hàm mới
function any_in_array($needle, $haystack)
{
        $needle = is_array($needle) ? $needle : array($needle);

        foreach ($needle as $item)
        {
                if (in_array($item, $haystack))
                {
                        return TRUE;
                }
        }

        return FALSE;
}

// random_element() đã có sẵn trong helper Array, nên nó được ghi đè như sau
function random_element($array)
{
        shuffle($array);
        return array_pop($array);
}

Thiết lập tiền tố

Để thiết lập tiền tố cho tên tập tin thừa kế helper thì ta mở tập tin application/config/config.php và tìm đến dòng lệnh sau:

$config['subclass_prefix'] = 'MY_';

Ở câu lệnh này bạn thấy tiền tố mặc định là 'MY_', bạn có quyền thay đổi lại tiền tố theo ý bạn, nhưng không được sử dụng tiền tố gốc thuộc các thư viện của CodeIgniter là CI_.

Thư viện của CI

Thư viện được CI tạo ra nhằm tạo ra các lớp chức năng giúp cho bạn làm việc nhanh chóng với ứng dụng. Có thể xem library có vai trò giống với helper.

Mỗi library là một class được định nghĩa sẵn các phương thức tiện ích. Tất cả các library do CI định nghịa được đặt trong thư mục system/libraies. Ngoài ra, chúng ta cũng có thể tự định nghĩa một library riêng của chính mình. Những library do chúng ta định nghĩa, có thể được lưu trong thư mục system/libraries nhưng tôi khuyên bạn nên đặt trong thư mục application/libraries.

Việc sử dụng một library tương tự như sử dụng helper với cú pháp như sau:

$this->load->library('class_name');

Ví dụ, CI đã định nghĩa sẳn library upload, bây giờ chúng ta muốn sử dụng library upload trong controller blog thì controller blog sẽ có nội dung sau:

<?php
class Blog extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $this->load->library('upload'); //Load thư viện upload
    }
}
?>

Chúng ta cũng có thể load cùng lúc nhiều library (giống như helper) với cú pháp như sau:

$this->load->library(
  array('class_name1','class_name')
);

Ví dụ, tôi muốn load 2 library upload cart thì tôi sẽ có cú pháp như sau:

$this->load->library(
  array('upload','cart')
);

Tạo thư viện riêng

Vui lòng đọc hướng dẫn tại phần Tạo thư viện riêng.

Tạo thư viện riêng

Từ "Libraries" tham chiếu đến các lớp đặt trong các tập tin thuộc thư mục application/libraries.

Tuy nhiên, CodeIgniter cũng cho phép bạn đưa vào các thư viện của riêng bạn, hoặc bạn cũng có thể tạo các lớp dẫn xuất từ các lớp của thư viện, hoặc bạn cũng có thể thay thế toàn bộ các thư viện sẵn có đó bằng thư viện mới của riêng bạn.

Tóm lại, CI có thể cho phép bạn:

  • Tạo thêm các thư viện mới.
  • Dẫn xuất từ các thư viện gốc.
  • Thay thế các thư viện gốc.

Lưu ý

Lớp Database không thể được thừa kế hay thay thế bằng lớp do bạn định nghĩa.

Lưu trữ

Các lớp thư viện của bạn cần được đặt trong thư mục application/libraries, đây là nơi CodeIgniter sẽ tìm đến khi chúng được khởi tạo. 

Quy ước đặt tên

  • Tên tập tin thư viện phải được viết hoa chữ đầu tiên. Ví dụ: Myclass.php

  • Phần định nghĩa một lớp cũng phải được được viết hoa chữ đầu tiên. Ví dụ: class Myclass

  • Tên lớp và tên tập tin phải trùng nhau.

Tập tin lớp

Các lớp được xây dựng cần có nguyên mẫu cơ bản như sau:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Someclass {

        public function some_method()
        {
        }
}

Lưu ý

Tên lớp là Someclass chỉ là ví dụ minh họa, bạn có thể dùng tên theo ý bạn.

Sử dụng lớp đã định nghĩa

Từ một phương thức bất kỳ của Controller ta đều có thể khởi tạo lớp thư viện đã định nghĩa theo dạng sau:

$this->load->library('someclass');

Trong đó, someclass chính là tên tập tin (không có phần mở rộng .php), bạn có thể viết hoặc không viết chữ cái đầu tiên.

Sau khi tải xong lớp thư viện ta có thể truy cập lớp như sau:

$this->someclass->some_method();  // Các đối tượng thể hiện sẽ luôn có dạng chữ in thường

Truyền tham số khi khởi tạo lớp

Bạn có thể truyền tham số khi tải lớp thư viện như sau:

$params = array('type' => 'large', 'color' => 'red');

$this->load->library('someclass', $params);

Nếu bạn sử dụng tính năng này thì bạn cần phải cài đặt hàm tạo như sau:

<?php defined('BASEPATH') OR exit('No direct script access allowed');

class Someclass {

        public function __construct($params)
        {
                // Code sử dụng $params
        }
}

Bạn cũng có thể truyền tham số được lưu trữ trong tập tin config bằng cách đơn giản là bạn tạo một tập tin config có tên tương ứng với tập tin lớp và lưu tập tin này trong thư mục application/config/. Lưu ý rằng nếu bạn muốn truyền các tham số động như mô tả ở trên thì tập tin config này sẽ không cho phép.

Sử dụng tài nguyên CodeIgniter trong thư viện đã tạo

Để truy cập được vào các tài nguyên gốc của CodeIgniter ở trong thư viện bạn đã tạo thì ta sử dụng phương thức get_instance(). Phương thức này sẽ trả về đối tượng super.

Thương thì từ bên trong các phương thức controller của bạn bạn sẽ gọi bất kỳ phương thức nào được phép của CodeIgniter bằng cách sử dụng $this dạng như sau:

$this->load->helper('url');
$this->load->library('session');
$this->config->item('base_url');
// etc.

Tuy vậy, $this chỉ làm việc trực tiếp trong các controller, model hay view. Nếu bạn cũng muốn sử dụng các lớp của CodeIgniter từ trong chính các lớp bạn xây dựng thì bạn có thể làm như sau:

Đầu tiên bạn gán đối tượng CodeIgniter cho một biến:

$CI =& get_instance();

Sau đó bạn sử dụng biến đó thay cho $this:

$CI =& get_instance();

$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');
// etc.

Lưu ý

Cần lưu ý rằng phương thức get_instance() ở trên được truyền theo dạng tham chiếu:

$CI =& get_instance();

Điều này rất quan trong vì việc gán tham chiếu sẽ cho phép bạn sử dụng đối tượng gốc của CodeIgniter thay vì phải tạo bản sao của nó.

Tuy nhiên, vì mỗi thư viện thực ra là một lớp cho nên tốt nhất là ta nên tận dụng các khả năng của lập trình hướng đối tượng (OOP). Vậy thì, để cho phép sử dụng đối tượng super CodeIgniter trong tất cả các phương thức của lớp ta nên gán nó cho một thuộc tính:

class Example_library {

        protected $CI;

        // Ta sẽ sử dụng một hàm tạo, vì bạn không thể trực tiếp gọi một hàm
        // từ việc định nghĩa thuộc tinh.
        public function __construct()
        {
                // Gán đối tượng siêu CodeIgniter
                $this->CI =& get_instance();
        }

        public function foo()
        {
                $this->CI->load->helper('url');
                redirect();
        }

        public function bar()
        {
                echo $this->CI->config->item('base_url');
        }

}

Thay thế các thư viện gốc

Để thực hiện điều này ta cần phải đặt tên file và khai báo lớp y hệt như tập tin gốc trong thư viện. Ví dụ như để thay thế thư viện gốc là Email bạn phải tạo một tập tin là application/libraries/Email.php, và khai báo lớp như sau:

class CI_Email {

}

Lưu ý rằng đa số các lớp đều có tên với tiền tố là CI_.

Để tải thư viện bạn định nghĩa thì ta làm như sau:

$this->load->library('email');

Dẫn xuất từ các thư viện gốc

Nếu bạn muốn thêm một vài chức năng nào đó vào thư viện gốc thôi thì bạn không nên thay thế bằng thư viện riêng của bạn, mà đơn giản là bạn chỉ cần tạo một lớp dẫn xuất từ lớp thư viện tương ứng đó. Để thực hiện điều này bạn cần lưu ý hai điều sau:

  • Khai báo lớp phải dẫn xuất từ lớp cha.

  • Lớp mới phải có tên với tiền tố là MY_.

Ví dụ, để thừa kế lớp Email gốc thì ta sẽ tạo một tập tin là application/libraries/MY_Email.php, và trong tập tin bạn khai báo một lớp là:

class MY_Email extends CI_Email {

}

Nếu bạn cần sử dụng một hàm tạo trong lớp thì bạn cần đảm bảo rằng nó phải chứa câu lệnh thừa kế từ hàm tạo của lớp cha:

class MY_Email extends CI_Email {

        public function __construct($config = array())
        {
                parent::__construct($config);
        }

}

Tải lớp thừa kế

Để tải lớp lớp ta cần bỏ qua tiền tố, chẳng hạn muốn tải lớp MY_Email ở trên thì ta làm như sau:

$this->load->library('email');

Sau khi tải xong thì ta có quyền truy cập vào các thành phần của lớp theo dạng sau:

$this->email->some_method();

Thiết lập tiền tố

Để thiết lập tiền tố cho lớp con thì ta mở tập tin application/config/config.php và tìm đến lệnh sau:

$config['subclass_prefix'] = 'MY_';

Xin lưu ý là tất cả các thư viện CodeIgniter đều có tiền tố là CI_ và vì vậy không được sử dụng nó để đặt cho tiền tố của bạn.

Cú pháp thay thế PHP

Nếu bạn không sử dụng template engine của CodeIgniter thì bạn sẽ sử dụng PHP thuần trong các tập tin View của bạn. Để tối ưu hóa code PHP trong các tập tin này, và để ta dễ nhận ra các khối lệnh thì khuyến nghị là ta nên dùng cú pháp thay thế của PHP cho các cấu trúc điều khiển và thẻ rút gọn cho câu lệnh echo. Mục đích chính của việc sử dụng cú pháp này là để loại bỏ đi các cặp ngoặc xoắn ({}) và loại bỏ đi câu lệnh "echo".

Hộ trợ thẻ ngắn tự động

Lưu ý

Nếu cú pháp miêu tả trong bài viết này không làm việc trên server của bạn thì có thể trong tập tin ini của PHP đã tắt chế độ “short tags”. CodeIgniter sẽ tùy chọn rewrite lại chế độ này để cho phép bạn sử dụng cú pháp cho dù server của bạn không hỗ trợ nó. Bạn có thể tìm thấy điều này trong tập  tin config/config.php.

Lưu ý rằng nếu bạn không sử dụng đặc điểm này thì nếu các lỗi PHP xuất hiện trong các tập tin view của bạn thì thông báo lỗi kèm số dòng sẽ không hiển thị đúng. Thay vào đó, tất cả các lỗi sẽ được thể hiện ở dạng các lỗi qua phương thức eval().

Thay thế "echo"

Thông thường thì để echo hay in ra giá trị của một biến ta sẽ làm như sau:

<?php echo $variable; ?>

Với cú pháp thay thế thì ta có thể làm như sau (sẽ giúp giảm được độ dài câu lệnh):

<?=$variable?>

Thay thế cấu trúc điều khiển

Các cấu trúc điều khiển như if, for, foreach và while có thể được viết theo dạng đơn giản hơn bằng cách sử dụng cú pháp thay thế. Dưới đây là một ví dụ áp dụng cho foreach:

<ul>

<?php foreach ($todo as $item): ?>

        <li><?=$item?></li>

<?php endforeach; ?>

</ul>

Ở ví dụ trên bạn thấy rằng các cặp ngoặc xoắn ({}) không xuất hiện, thay vào đó dấu mở ngoặc xoắn { được thay thế bằng dấu hai chấm (:), dấu đóng ngoặc xoắn } được thay thế bằng endforeach. Cú pháp của ví dụ trên cũng áp dụng cho các cấu trúc điều khiển khác như endif;endfor;endforeach;, và endwhile;.

Dưới đây là một ví dụ khác áp dụng cho if/elseif/else.

<?php if ($username === 'sally'): ?>

        <h3>Hi Sally</h3>

<?php elseif ($username === 'joe'): ?>

        <h3>Hi Joe</h3>

<?php else: ?>

        <h3>Hi unknown user</h3>

<?php endif; ?>

URI Routing

Thường thì có một mối quan hệ một-một giữa một chuỗi URL và controller class/method tương ứng. Các phân đoạn trong một URL thường có dạng như sau:

example.com/class/function/id/

Tuy nhiên trong một số tình huống ta có thể muốn ánh xạ lại mối quan hệ trên theo đó mỗi class/method riêng biệt có thể được gọi thay cho một URL tương ứng.

Ví dụ, ta có thể có URL dạng như sau:

example.com/product/1/
example.com/product/2/
example.com/product/3/
example.com/product/4/

Thương thì đoạn thứ hai của URL tương ứng với tên của phương thức, nhưng ở ví dụ trên thì nó lại được thay thế bằng ID của sản phẩm. Để tránh trường hợp này thì CodeIgniter cho phép ta có thể ánh xạ lại bộ xử lý URI.

Thiết lập các quy tắc định tuyến

Các quy tắc định tuyến được định nghĩa trong tập tin application/config/routes.php. Trong tập tin này ta sẽ thấy một mảng có tên $route và nó cho phép ta tạo các tiêu chí định tuyến riêng. Có hai cách định tuyến là sử dụng các ký hiệu đại diện (wildcards) hoặc biểu thức chính quy (Regular Expressions).

Wildcards

Việc định tuyến bằng ký hiệu đại diện thường có dạng như sau:

$route['product/:num'] = 'catalog/product_lookup';

Trong mỗi định tuyến thì chỉ số mảng chứa URI tương ứng, còn giá trị là đích mà nó sẽ được định tuyến lại. Trong ví dụ trên thì nếu "product" được tìm thấy trong đoạn URL và một số được tìm thấy ở đoạn ngay sau thì lớp controller "catalog" và phương thức "product_lookup" sẽ được thay thế tương ứng.

Ta có thể tương thích cách giá trị hằng hoặc cũng có thể sử dụng các loại ký hiệu:

(:num) tương ứng với đoạn (segment) chỉ chứa số.

(:any) sẽ tương ứng với một đoạn chứa bất kỳ ký tự nào ngoại trừ ký tự ‘/’.

Lưu ý

- Các ký hiệu thực ra chỉ là bí danh của các biểu thức chính quy, trong đó :any tương đương với [^/]+ và :num tương đương với [0-9]+.

- Các định tuyến sẽ chạy theo đúng thứ tự chúng được định nghĩa. Các định tuyến cao hơn sẽ có quyền ưu tiên hơn so với các định tuyến thấp hơn.

- Các quy tắc định tuyến không phải là các bộ lọc! Chẳng hạn việc thiết lập một quy tắc như ‘foo/bar/(:num)’ sẽ không ảnh hưởng tới việc gọi controller Foo và phương thức bar với một giá trị không phải là số nếu đó là một định tuyến hợp lệ.

Các ví dụ

Dưới đây là một số ví dụ về định tuyến:

$route['journals'] = 'blogs';

Một URL nào đó mà chứa từ “journals” ở đoạn đầu tiên thì sẽ được ánh xạ lại thành lớp “blogs”.

$route['blog/joe'] = 'blogs/users/34';

Một URL nào đó chứa blog/joe sẽ được ánh xạ lại thành lớp “blogs” và phương thức “users”. ID sẽ được đặt là “34”.

$route['product/(:any)'] = 'catalog/product_lookup';

Nếu một URL nào đó chứa “product” và đoạn ngay sau nó chưa bất kỳ ký tự nào thì nó sẽ được ánh xạ lại thành lớp “catalog” và phương thức là “product_lookup”.

$route['product/(:num)'] = 'catalog/product_lookup_by_id/$1';

Nếu một URL nào đó chứa “product” và đoạn ngay sau nó chứa một số thì nó sẽ được ánh xạ lại thành lớp “catalog” và phương thức “product_lookup_by_id” đồng thời đối số truyền đi của phương thức là số đó.

Quan trọng

Không sử dụng dấu xổ phải với dạng đầu/cuối.

Biểu thức chính quy (Regular Expression)

Nếu bạn nắm được kiến thức về biểu thức chính quy thì bạn có thể sử dụng nó để định nghĩa các quy tắc định tuyến của bạn. Bất kỳ biểu thức chính quy nào hợp lệ sẽ đều được tham chiếu ngược.

Lưu ý

Nếu bạn sử dụng các tham chiếu ngược thì bạn phải sử dụng ký tự $ thay cho dấu xổ phải.

Một biểu thức chính có thể có dạng như sau:

$route['products/([a-z]+)/(\d+)'] = '$1/id_$2';

Trong ví dụ trên nếu có một URI products/shirts/123 thì nó sẽ được thay bằng lớp controller “shirts” và phương thức “id_123”.

Với biểu thức chính quy ta có thể bắt nhiều đoạn mỗi lần. Ví dụ nếu người dùng truy cập một mật khẩu đã được bảo vệ trong ứng dụng web của bạn và muốn có thể điều hướng chúng trở về trang tương tự sau khi login thì ta có thể thực hiện như sau:

$route['login/(.+)'] = 'auth/login/$1';

Lưu ý

Trong ví dụ trên, nếu $1 chứa một dấu / thì nó sẽ vẫn được tách thành nhiều đoạn khi truyên tới Auth::login().

Bạn cũng có thể kết hợp wildcard với biểu thức chính quy.

Callback

Nếu bạn đang sử dụng PHP phiên bản từ 5.3 thì bạn có thể sử dụng callback tại vị trí của các biểu thức chính quy để xử lý tham chiếu ngược. Ví dụ:

$route['products/([a-zA-Z]+)/edit/(\d+)'] = function ($product_type, $id)
{
        return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id;
};

Dùng động từ HTTP để định tuyến

Ta có thể sử dụng HTTP (phương thức yêu cầu) để định nghĩa các quy tắc định tuyến của bạn. Đây là cách thường dùng khi xây dựng các ứng dụng tĩnh (RESTful). Bạn có thể sử dụng động từ HTTP (GET, PUT, POST, DELETE, PATCH) hoặc tùy biến nó như (PURGE). Các quy tắc động từ HTTP phân biệt chữ hoa/thường. Tất cả những gì bạn cần làm là thêm động từ như một chỉ số của phần tử mảng để định tuyến. Ví dụ:

$route['products']['put'] = 'product/insert';

Trong ví dụ trên, một yêu cầu PUT tới URI “products” sẽ gọi phương thức Product::insert().

$route['products/(:num)']['DELETE'] = 'product/delete/$1';

Trong ví dụ trên, một yêu cầu DELETE tới URL chứa “products” ở đoạn đầu tiên và sau đó là một số sẽ được ánh xạ thành phương thức Product::delete(), và đối số của phương thức này là số đó.

Việc sử dụng động từ HTTP đương nhiên là một tùy chọn, không phải là bắt buộc.

Định tuyến riêng

Có ba định tuyến riêng đã được tạo sẵn được trình bày dưới đây:

$route['default_controller'] = 'welcome';

Định tuyến này trỏ tới controller 'welcome' và sẽ được thực thi nếu URI rỗng hoặc không có, cụ thể là nó sẽ được load khi người dùng mở chuyển hướng đến URL gốc. Việc thiết lập sẽ chấp nhận giá trị controller/method và index() sẽ là phương thức mặc định nếu bạn không gọi phương thức nào cả. Trong ví dụ trên thì Welcome::index() sẽ được gọi.

Lưu ý

Ta không thể sử dụng thư mục như là một phần của cài đặt này!

Bạn nên chuẩn bị sẵn một định tuyến mặc định khi gặp lỗi 404, nếu không thì trang 404 sẽ mặc định được dùng đến.

$route['404_override'] = '';

Định tuyến trên chỉ định lớp controller sẽ được tải nếu controller yêu cầu không tồn tại. Nó sẽ ghi đè trang 404. Nó sẽ không ảnh hưởng tới hàm show_404(), tức là nó sẽ tiếp tục tải tập tin mặc định error_404.php tại application/views/errors/error_404.php.

$route['translate_uri_dashes'] = FALSE;

Tùy chọn trên cho phép ta tự động thay dấu gạch trừ '-' bằng dấu gạch dưới trong controller và phương thức tương ứng, khi thể hiện URL có dấu gạch trừ '-' thì nó sẽ đẹp và thân thiện hơn với công cụ tìm kiếm. Cách thức ở đây là bạn sẽ thay FALSE bằng TRUE để được phép sử dụng.

Quan trọng

Các định tuyến đã lưu phải nằm trước bất kỳ wildcard hay biểu thức chính quy nào.

Form Validation

Thư viện Form Validation của CodeIgniter giúp lập trình viên kiểm tra dữ liệu được gửi lên từ phía người dùng. Trong thư viện Form Validation đã xây dựng sẵn một số ràng buộc dữ liệu thường gặp, ta có thể áp dụng vào lập trình một cách dễ dàng. Để sử dụng thư viện này, ta khai báo như sau:

$this->load->library('form_validation');

Sau khi khai báo, ta có thể sử dụng c|c phương thức của thư viện này bằng cách sử dụng đối tượng $this->form_validation.

1. Thiết lập các điều kiện kiểm tra

Bằng cách kết hợp các điều kiện có sẵn và các hàm tự định nghĩa, thư viện Form Validation giúp lập trình viên có thể kiểm tra dữ liệu nhập vào từ phía người dùng. Để sử dụng các điều kiện này, ta khai b|o như sau:

$this->form_validation->set_rules(string $field, string $label, string $rules);

Trong đó:

- $field là tên của trường HTML được áp dụng điều kiện này, thông thường là giá trị thuộc tính name của tag INPUT, TEXTAREA, SELECT… Lưu ý là nếu sử dụng mảng làm tên trường (thường gặp đối với checkbox, list…), ví dụ chkColor[], ta phải truyền chính x|c tên trường, kể cả ký tự [].

- $label là tên của trường đó. Giá trị của biến này sẽ được sử dụng trong các thông báo lỗi.

- $rules là chuỗi chứa các điều kiện kiểm tra. Các điều kiện này có thể được xây dựng sẵn bởi CodeIgniter, hoặc là các hàm nhận một đối số của PHP hay các hàm callback do lập trình viên tự định nghĩa. C|c điều kiện cách nhau bởi ký tự gạch đứng |.

Xét ví dụ sau:

$this->form_validation->set_rules('txtUsername', 'Username', 'trim|required|min_length[5]|max_length[12]|xss_clean');

Điều kiện trên có nghĩa là, trường txtUsername là trường bắt buộc (required), giá trị của trường có chiều dài tối thiểu là 5 ký tự (min_length[5]), chiều dài tối đa l{ 12 ký tự (max_length[12]), dữ liệu này sẽ được loại bỏ khoảng trắng ở hai đầu (trim) và lọc XSS (xss_clean).

Các điều kiện có sẵn trong thư viện Form Validation:

Tên luật Mô tả Ví dụ
required  Trả về FALSE nếu trường rỗng   
matches  Trả về FALSE nếu giá trị của trường không trùng với giá trị của trường đượctruyền vào  matches[txtPassword]
min_length   Trả về FALSE nếu chiều dài giá trị của trường ít hơn số ký tự quy định  min_length[5]
max_length   Trả về FALSE nếu chiều dài giá trị của trường nhiều hơn số ký tự quy định  max_length[12]
exact_length   Trả về FALSE nếu chiều dài giá trị của trường không đúng bằng số ký tự quy định exact_length[8]
alpha    Chỉ cho phép giá trị của trường chứa các ký tự chữ  
alpha_numeric   Chỉ cho phép giá trị của trường chứa các ký tự chữ và số  
alpha_dash   Chỉ cho phép giá trị của trường chứa các ký tự chữ, số, dấu gạch ngang (-) và dấu gạch dưới (_)   
numeric  Chỉ cho phép giá trị của trường chứa các ký tự số  
integer   Chỉ cho phép trường chứa giá trị số nguyên  
is_natural   Chỉ cho phép trường chứa giá trị số tự nhiên  
is_natural_no_zero   Chỉ cho phép trường chứa giá trị số tự nhiên, bỏ số 0  
valid_email   Trả về FALSE nếu giá trị của trường không phải là một địa chỉ email hợp lệ   
valid_emails  Trả về FALSE nếu giá trị của trường không phải là một tập hợp các địa chỉ email hợp lệ, ngăn cách bởi dấu phẩy (,)   
valid_ip  Trả về FALSE nếu giá trị của trường không phải là một địa chỉ IP hợp lệ   
valid_base64  Trả về FALSE nếu giá trị của trường chứa các ký tự không phải là các ký tự của mã hóa Base 64  
xss_clean  Lọc XSS từ dữ liệu gửi lên  
prep_for_form   Chuyển đổi mã HTML thành các thực thể ký tự (character entites) để hiển thị chính x|c trên c|c tag như INPUT, TEXTAREA…   
prep_url  Thêm chuỗi http:// vào URL nếu không có strip_image_tags Lọc lấy địa chỉ URL của hình trong tag IMG   
encode_php_tags  Chuyển tag của PHP thành các thực thể ký tự  

Thư viện Form Validation còn cho phép thiết lập điều kiện kiểm tra bằng cách truyền vào hàm set_rules() một mảng hai chiều có dạng:

$config = array(

  array(

    'field' => 'txtUsername',

    'label' => 'Username',

    'rules' => 'required'

  ),

  array(

    'field' => 'txtPassword',

    'label' => 'Password',

    'rules' => 'required'

  ),

  array(

    'field' => 'txtPassConf',

    'label' => 'Password Confirmation',

    'rules' => 'required|matches[txtPassword]'

  ),

  array(

    'field' => 'txtEmail',

    'label' => 'Email',

    'rules' => 'required'

  )

);

$this->form_validation->set_rules($config);

Ta cũng có thể sử dụng các hàm một đối số của PHP như trim(), htmlspecialchars(), md5()…để thiết lập điều kiện. Ngoài ra, CodeIgniter còn cho phép lập trình viên sử dụng các hàm callback tự định nghĩa để thiết lập luật kiểm tra của riêng mình, chẳng hạn như kiểm tra tên đăng nhập đ~ có trong cơ sở dữ liệu chưa…C|c h{m callback được bắt đầu bằng tiền tố callback_ và phải trả về giá trị boolean.

$this->form_validation->set_rules('txtUsername', 'Username', 'callback_check_username');

function check_username($str) {

  if( $this->UserModel->usernamExists() == TRUE)

    return FALSE;

  else

    return TRUE;

}

Sau khi thiết lập các điều kiện, ta sử dụng phương thức run() để kiểm tra dữ liệu đầu vào. Nếu kết quả trả về là TRUE, tức là dữ liệu thỏa m~n c|c điều kiện đưa ra, ngược lại hàm trả về FALSE.

$this->form_validation->run();

Một chức năng hữu ích khác của thư viện CodeIgniter l{ cho phép ta lưu c|c điều kiện kiểm tra dữ liệu vào một tập tin thiết lập. C|c điều kiện này có thể được sắp xếp vào từng nhóm. Các nhóm này có thể được gọi một cách tự động hay thông qua lời gọi của lập trình viên.

Để sử dụng chức năng n{y, ta tạo một tập tin form_validation.php trong thư mục application/config. Bên trong tập tin này, ta khai báo mảng $config chứa c|c điều kiện kiểm tra như đã trình bày, với tên của khóa cũng l{ tên nhóm. Ví dụ, tạo hai nhóm điều kiện có tên là signup và email:

$config = array(

  'signup' => array(

    array(

      'field' => 'username',

      'label' => 'Username',

      'rules' => 'required'

    ),

    array(

      'field' => 'password',

      'label' => 'Password',

      'rules' => 'required'

    ),

  'email' => array(

    array(

      'field' => 'name',

      'label' => 'Name',

      'rules' => 'required|alpha'

    ),

    array(

      'field' => 'title',

      'label' => 'Title',

      'rules' => 'required'

    ),

    array(

      'field' => 'message',

      'label' => 'MessageBody',

      'rules' => 'required'

    )

  )

);

Khi đó, để kiểm tra dữ liệu cho một nhóm, ta gọi phương thức run() với tham số truyền vào là tên của nhóm điều kiện:

$this->form_validation->run('group_name');

Lớp Form Validation còn cho phép gắn nhóm điều kiện với từng phương thức trong controller. Khi dữ liệu được gửi v{o phương thức này, lớp Form Validation sẽ tự động kiểm tra c|c điều kiện đ~ được định sẵn. Ví dụ, để thiết lập điều kiện kiểm tra dữ liệu cho phương thức signup() của lớp controller Member, ta khai báo:

$config = array(

  'member/signup' => array(

    array(

      'field' => 'username',

      'label' => 'Username',

      'rules' => 'required'

    ),

    array(

      'field' => 'password',

      'label' => 'Password',

      'rules' => 'required'

    ),

    array(

      'field' => 'passconf',

      'label' => 'PasswordConfirmation',

      'rules' => 'required'

    ),

    array(

      'field' => 'email',

      'label' => 'Email',

      'rules' => 'required'

    )

  )

);

2. Xử lý lỗi

Thư viện Form Validation cung cấp hàm validation_errors() để hiển thị tất cả lỗi kiểm tra dữ liệu trong các tập tin view. Các thông báo sẽ hiển thị được quy định trong tập tin system/language/english/form_validation_lang.php. Ta cũng có thể thay đổi các thông báo này bằng cách sử dụng hàm set_message().

$this->form_validation->set_message('rule', 'Error Message');

Với rule là tên điều kiện dựng sẵn của thư viện Form Validation và Error Message là thông báo sẽ được hiển thị. Nếu trong Error Message có chứa %s, giá trị label sẽ được thay thế vào đó.

$this->form_validation->set_message(required', 'Field %s must not be empty!');

Để thiết lập thông báo cho các hàm callback, ta chỉ cần đưa tên h{m l{m đối số đầu tiên. Chẳng hạn:

$this->form_validation->set_message('check_username', 'This username is used. Please choose another one!');

Để hiển thị lỗi cho riêng từng trường, ta có thể sử dụng hàm form_error() như sau:

<?php echo form_error($fieldName); ?> // Với $fieldName là tên của trường

Theo mặc định, các thông báo lỗi sẽ được đặt trong tag P. Ta có thể thiết lập lại cách hiển thị này cho phù hợp với giao diện website. CodeIgniter cho phép thiết lập toàn cục, áp dụng với tất cả các lần gọi hàm validation_errors(), và cục bộ, áp dụng với từng lần gọi hàm riêng biệt. Để thiết lập toàn cục, ta sử dụng hàm sau:

$this->form_validation->set_error_delimiters(string $startTag, string $endTag);

Chẳng hạn, đoạn mã dưới đ}y sẽ thiết lập các thông báo lỗi được đặt trong thẻ DIV.

$this->form_validation->set_error_delimiters('<div class="error">', '</div>');

Để thiết lập riêng cho từng lần gọi hàm, ta sử dụng:

<?php echo form_error('field name',  '<div class="error">', '</div>'); ?>

Hoặc

<?php echo validation_errors('<div class="error">', '</div>'); ?>

3. Các hàm tiện ích

form_error(string $fieldName[, string $errorStartTag[, string $errorEndTag]])

Hàm form_error() sẽ hiển thị lỗi của trường được truyền vào.

set_value(string $fieldName[, mixed $defaultValue])

Hàm set_value() sẽ hiển thị lại những dữ liệu do người dùng nhập v{o, trong trường hợp trường hợp xảy ra lỗi. H{m này được áp dụng với các textfield (tag INPUT) hay textarea (tag TEXTAREA). Hàm nhận tên trường l{m đối số thứ nhất. Đối số thứ hai (tùy chọn) sẽ hiển thị giá trị mặc định của trường khi được tải lần đầu.

set_select(string $fieldName[, mixed $defaultValue[, boolean $isSelected]])

Hàm set_select() sẽ hiển thị lại giá trị đã chọn của người dùng trong combo box, trong trường hợp xảy ra lỗi. H{m được áp dụng cho các tag OPTION. Hàm nhận tên trường làm đối số thứ nhất. Đối số thứ hai (tùy chọn) sẽ hiển thị giá trị mặc định của tùy chọn này. Đối số thứ ba (tùy chọn) sẽ đ|nh dấu lựa chọn này làm lựa chọn mặc định.

set_checkbox(string $fieldName, mixed $defaultValue[, boolean $isSelected])

Hàm set_checbox() sẽ chọn những checkbox đã chọn của người dùng, trong trường hợp xảy ra lỗi. H{m được áp dụng cho các tag INPUT với type="checkbox". Hàm nhận tên trường l{m đối số thứ nhất. Đối số thứ hai là giá trị của checkbox. Đối số thứ ba (tùy chọn) sẽ đ|nh dấu checkbox n{y được chọn.

set_radio(string $fieldName, mixed $defaultValue[, boolean $isSelected])

Hàm set_radio() sẽ chọn những radio button đ~ được chọn của người dùng, trong trường hợp xảy ra lỗi. H{m n{y được áp dụng cho những tag INPUT có type="radio". Hàm nhận tên trường l{m đối số thứ nhất. Đối số thứ hai là giá trị của checkbox. Đối số thứ ba (tùy chọn) sẽ đ|nh dấu chọn cho radio button này.

Security

Bài viết này mô tả một số vấn đề thực tế và quan trọng nhất về bảo mật web và cũng trình bày chi tiết về các tính năng bảo mật web của CodeIgniter.

Bảo mật URI

CodeIgniter khá chặt chẽ về việc sử dụng các ký tự trong chuỗi URI nhằm giúp giảm thiểu khả năng dữ liệu độc hại có thể truyền được qua ứng dụng. URI chỉ có thể chứa những điều sau:

  • Các ký tự chữ và số (chỉ được là các ký tự latin)
  • Dấu ngã: ~
  • Ký hiệu phần trăm: %
  • Dấu chấm: .
  • Dấu hai chấm: :
  • Dấu gạch dưới: _
  • Dấu trừ: -
  • Dấu cách (Space)

register_globals

Khi khởi tạo tất cả các biến global thì các biến $_GET$_POST$_REQUEST và $_COOKIE sẽ bị hủy. Ta thực hiện điều này bằng cách sử dụng câu lệnh register_globals = off;

display_errors

Trong chế độ production ta thường mong muốn vô hiệu hóa thông báo lỗi của PHP vì lý do thông báo lỗi có thể chứa những thông tin nhạy cảm, và ta có thể thực hiện điều này bằng cách đặt cờ display_errors thành 0.

Thiết lập hằng ENVIRONMENT của CodeIgniter trong tập tin index.php thành giá trị là 'production' sẽ tắt được các lỗi này, còn ở chế độ development thì khuyến nghị giá trị là 'development'.

magic_quotes_runtime

magic_quotes_runtime được tắt khi khởi tạo hệ thống, vì thế mà ta không phải bỏ dấu xổ phải khi truy xuất dữ liệu từ cơ sở dữ liệu.

Best Practices

Trước khi chấp nhận bất kỳ dữ liệu nào trong ứng dụng của bạn như dữ liệu được POST khi submit form, dữ liệu COOKIE, URI, XML-RPC, hoặc kể cả là dữ liệu từ mảng SERVER, thì bạn nên thực hiện ba bước sau:

  1. Đảm bảo dữ liệu đúng loại, kiểu, độ dài, kích thước, ...

  2. Lọc dữ liệu có vấn đề.

  3. Hủy dữ liệu trước khi đưa nó vào cơ sở dữ liệu hay hiển thị ra trình duyệt.

CodeIgniter cung cấp các hàm và các hướng dẫn sau để hỗ trợ bạn xử lý các bước trên:

Lọc XSS

CodeIgniter có chứa bộ lọc Cross Site Scripting. Bộ lọc này có nhiệm vụ tìm ra những kỹ thuật được sử dụng phổ biến để nhúng mã độc JavaScript vào dữ liệu của ta, hoặc các kiểu mã lệnh khác nhằm chiếm quyền điều khiển cookie hoặc làm những điều nguy hiểm khác.

Lưu ý
XSS chỉ nên được thực hiện ở đầu ra, việc lọc dữ liệu đầu vào có thể làm thay đổi dữ liệu như bỏ đi các ký tự đặc biệt ở mật khẩu, dẫn đến giảm đi khả năng bảo mật.

Bảo vệ CSRF

CSRF là các ký tự viết tắt của Cross-Site Request Forgery, nó là một dạng tấn công nhằm đánh lừa nạn nhân để họ cố ý gửi một yêu cầu nào đó.

CodeIgniter cung cấp mức bảo vệ CSRF ngoài khối, nó sẽ tự động được kích hoạt cho mỗi yêu cầu không phải là GET HTTP, nhưng bạn cũng cần tạo form submit theo cách thông thường.

Xử lý Password

Một điều rất quan trọng cần thực hiện được đó là xử lý tốt các mật khẩu trong ứng dụng của bạn.

Tuy nhiên, nhiều nhà phát triển lại không biết cách thực hiện, và các trang web thì luôn đưa ra các cảnh báo và lỗi, nhưng ta không khắc phục được nó.

Dưới đây là các gợi ý nên làm và không nên làm để giúp bạn thực hiện:

  • Không lưu mật khẩu theo dạng văn bản thông thường.

    Cần luôn tạo mã băm cho mật khẩu.

  • Không sử dụng kiểu mã hóa Base64 hoặc tương tự để lưu mật khẩu, bởi vì kiểu mã hóa này tương tự như plain-text (văn bản thông thường).

    Encoding, and encryption too, are two-way processes. Passwords are secrets that must only be known to their owner, and thus must work only in one direction. Hashing does that - there’s no un-hashing or de-hashing, but there is decoding and decryption.

  • Không sử dụng các thuật toán băm yếu hoặc bị hỏng như MD5 hay SHA1.

    Những thuật toán này đã cux và đã được chứng mình là có thiếu sót, và không được thiết kế để băm mật khẩu ở vị trí đầu tiên.

    Ngoài ra, không được phát mình ra thuật toán của riêng bạn.

    Chỉ sử dụng các thuật toán băm mật khẩu như BCrypt, nó được sử dụng trong các hàm băm mật khẩu dành riêng cho PHP.

    Bạn nên sử dụng chúng, ngay cả khi bạn không sử dụng bản PHP 5.5+, vì CodeIgniter sẽ cung cấp chúng cho bạn điều này từ phiên bản PHP version 5.3.7. Nếu bạn sử dụng phiên bản nhỏ hơn bạn nên nâng cấp.

    Trường hợp bạn không không thể nâng cấp lên phiên bản PHP hiện thời thì bạn sử dụng hash_pbkdf() <http://php.net/hash_pbkdf2>.

  • Không hiển thị hay gửi mật khẩu dưới dạng văn bản thông thường plain-text!

    Ngay cả với chủ sở hữu mật khẩu thì nếu bạn cần sử dụng tính năng "Quên mật khẩu", bạn chỉ cần tạo ngẫu nhiên một mật khẩu mới và gửi nó đi chứ không gửi đi mật khẩu cũ.

  • Không được thiết lập những giới hạn không cần thiết đối với mật khẩu người dùng.

    Nếu bạn đang sử dụng thuật toán băm khác mà không phải BCrypt (giới hạn tới 72 ký tự), thì bạn nên thiết lập giới hạn ở mức cao đối với độ dài mật khẩu để giảm thiểu các cuộc tấn công DoS, ví dụ như để độ dài 1024 ký tự chẳng hạn.

Validate dữ liệu đầu vào

CodeIgniter đã có sẵn một thư viện Form Validation để hỗ trợ bạn validating, lọc và sửa dữ liệu.

Trong bất kỳ hoàn cảnh nào bạn cũng phải đảm bảo rằng dữ liệu đầu vào luôn luôn được validate và phải 'sạch sẽ'. Ví dụ, nếu bạn mong muống đầu vào là một chuỗi số thì bạn có thể sử dụng hàm is_numeric() hoặc ctype_digit(). Luôn luôn cố gắng giảm xuống mức thấp nhất có thể việc kiểm tra một mẫu nhất định.

Luôn nhớ rằng không chỉ có các biến $_POST và $_GET, bạn còn có các cookie, chuỗi tác nhân người dùng và về cơ bản là tất cả các dữ liệu mà không được tạo trực tiếp từ mã lệnh của chính bản.

Bỏ đi tất cả các dữ liệu trước khi chèn vào database

Không bao giờ được chèn thông tin vào database mà trước đó chưa xóa bỏ chúng. Vui lòng xem thêm tại database queries.

Ẩn tập tin của bạn

Một cách thức bảo mật thực tế tốt nữa là tại thư mục gốc của website (thường là thư mục có tên "htdocs/") bạn chỉ nên đặt tập tin index.php và các tập tin tài nguyên khác (.js, .css và các tập tin ảnh). Đây là những tập tin duy nhất mà bạn cần để truy cập từ trang web.

Điều này sẽ cho phép khách viếng thăm có thể xem được tất cả các tập tin này, thực hiện các kịch bản, ... Nếu bạn không cho phép làm điều đó thì bạn sử dụng tập tin .htaccess để ngăn chặn hoặc hạn chế truy cập.

CodeIgniter đã tạo săn file index.html trong tất cả các thư mục để nhằm mục đích ẩn đi những dữ liệu này, nhưng cần lưu ý là nó không đủ khả năng ngăn chặn những cuộc tấn công nguy hiểm.

Lớp Email

Gửi email là một thao tác thường gặp khi xây dựng một ứng dụng web. Bản thân PHP có hỗ trợ hàm mail() để thực hiện gửi email. Nhưng để thực hiện những chức năng cao cấp hơn, ta có thể sử dụng thư viện Email của CodeIgniter. Thư viện Email hỗ trợ những chức năng sau:

  • Gửi email bằng nhiều giao thức: Mail, Sendmail và SMTP
  • Mã hóa TLS và SSL cho SMTP
  • Có thể gửi cho nhiều người cùng lúc
  • CC (carbon copy) và BCC (blind carbon copy)
  • Gửi email dưới dạng HTML hoặc thuần văn bản
  • Đính kèm tập tin
  • Thiết lập độ ưu tiên
  • Hỗ trợ wordwrap
  • BCC Batch Mode, cho phép chia những danh sách email lớn thành những danh sách nhỏ hơn.
  • Hỗ trợ công cụ tìm lỗi

1. Load thư viện Email

Cũng giống sử dụng các thư viện khác của CodeIgniter, để sử dụng thư viện Email, ta sử dụng phương thức load() như sau:

$this->load->library('email');

2. Thiết lập các tùy chọn

Để sử dụng thư viện Email, ta cần thiết lập các tùy chọn gửi email, chẳng hạn như giao thức, thông số của máy chủ SMTP. Các thiết lập này được lưu vào một mảng, và truyền vào phương thức initialize() để tiến hành khởi tạo. Chẳng hạn:

$config['protocol'] = 'sendmail';

$config['mailpath'] = '/usr/sbin/sendmail';

$config['charset'] = 'utf-8';

$config['wordwrap'] = TRUE;

$this->email->initialize($config);

Ngoài ra, ta cũng có thể lưu các thiết lập vào mảng $config trong tập tin application/config/email.php. Khi đó các thiết lập này sẽ được gọi một cách tự động khi thư viện Email được khai báo sử dụng, ta không cần thiết phải gọi hàm initialize().

Danh sách các tùy chọn:

The following is a list of all the preferences that can be set when sending email.

Thiết lập Giá trị mặc định Tùy chọn Mô tả
useragent CodeIgniter Không có Đại lý người dùng.
protocol mail mail, sendmail hoặc smtp Giao thức dùng để gửi email.
mailpath /usr/sbin/sendmail Không có Đường dẫn đến thư mục Sendmail trên máy chủ (server).
smtp_host Không mặc định Không có Địa chỉ của máy chủ SMTP.
smtp_user Không mặc định Không có Tên tài khoản sử dụng máy chủ SMTP.
smtp_pass Không mặc định Không có Mật khẩu tài khoản SMTP.
smtp_port 25 Không có Cổng truy cập máy chủ SMTP.
smtp_timeout 5 Không có Thời gian trễ tạm ngưng khi truy cập máy chủ SMTP (tính bằng giây).
smtp_keepalive FALSE TRUE hoặc FALSE (boolean) Cho phép kết nối SMTP lâu dài hay không.
smtp_crypto Không mặc định tls hoặc ssl Mã hóa SMTP
wordwrap TRUE TRUE hoặc FALSE (boolean) Cho phép sử dụng wordwrap hay không.
wrapchars 76   Số ký tự trên một dòng khi sử dụng wordwrap.
mailtype text text hoặc html Kiểu của email. Nếu bạn gửi email HTML bạn phải gửi nó dưới dạng một trang web hoàn chỉnh. Cần đảm bảo rằng bạn không có bất kỳ liên kết hoặc đường dẫn ảnh tương đối nào vì chúng sẽ không làm việc.
charset $config['charset']   Tập ký tự (utf-8, iso-8859-1, ...).
validate FALSE TRUE hoặc FALSE (boolean) Có kiểm tra tính hợp lệ của địa chỉ email không.
priority 3 1, 2, 3, 4, 5 Độ ưu tiên của email với 1 là cao nhất, 3 là bình thường và 5 là thấp nhất.
crlf \n "\r\n" hoặc "\n" hoặc "\r" Ký tự xuống dòng (sử dụng \r\n theo RFC 822).
newline \n "\r\n" hoặc "\n" hoặc "\r" Ký tự xuống dòng (sử dụng \r\n theo RFC 822).
bcc_batch_mode FALSE TRUE hoặc FALSE (boolean) Có sử dụng BCC Batch Mode hay không.
bcc_batch_size 200 None Số địa chỉ email mỗi nhóm khi sử dụng BCC Batch Mode.
dsn FALSE TRUE hoặc FALSE (boolean) Có cho phép thông báo nhắc nhở từ server hay không

3. Thao tác gửi email

Sau khi khai báo sử dụng thư viện Email và thiết lập các tùy chọn cần thiết, ta có thể thực hiện gửi email như trong đoạn mã sau:

$this->load->library('email');

$this->email->from('your@example.com', 'Your Name');

$this->email->to('someone@example.com');

$this->email->cc('another@another-example.com');

$this->email->bcc('them@their-example.com');

$this->email->subject('Email Test');

$this->email->message('Testing the email class.');

$this->email->send();

echo $this->email->print_debugger();

4. Wordwrap

Chế độ wordwrap cho phép hiển thị văn bản trong một "khung" nhất định, giúp cho văn bản không tràn ra khỏi khung màn hình và thuận tiện cho người đọc. Theo RFC 822, chế độ wordwrap nên được kích hoạt. Thư viện Email cho phép thực hiện wordwrap trong nội dung email. Sau n ký tự (mặc định là 76, có thể được thiết lập bằng giá trị wrapchars), văn bản sẽ được đưa sang một hàng mới. Tuy nhiên, đối với những liên kết quá dài, khi thực hiện wordwrap sẽ làm cho chúng bị ngắt quãng, không thể click được. Để tránh điều này, thư viện Email sử dụng hai tag {unwrap} {/unwrap} để thông báo cho chương trình biết đoạn văn bản nào sẽ không được thực hiện wordwrap. Ví dụ:

Phần văn bản của email của bạn
sẽ được đẩy xuống dòng.

{unwrap}http://example.com/một_link_dài_nhưng_bạn_không_muốn_bị_xuống_dòng.html{/unwrap}

Các đoạn văn bản email khác
cũng có hiệu ứng tương tự.

Lưu ý: Bạn hãy đặt phần mà bạn không muốn bị hiệu ứng wordwrap giữa {unwrap} và {/unwrap}.

5. Tham chiếu lớp

class CI_Email

from()

Cú pháp:

$this->email->from(string $email, string $name)

Phương thức from() cho phép thiết lập địa chỉ email và tên của người gửi. Ví dụ:

$this->email->from('support@v1study.com', 'V1Study')

reply_to()

Cú pháp:

$this->email->reply_to(string $email, string $name)

Phương thức reply_to() cho phép thiết lập địa chỉ email sẽ nhận trả lời. Nếu phương thức này không được sử dụng, hệ thống sẽ tự nhận địa chỉ email trong phương thức from() làm địa chỉ nhận trả lời.

to()

Cú pháp:

$this->email->to(string/array $emailAddresses)

Phương thức to() cho phép thiết lập những địa chỉ email sẽ được gửi. Các địa chỉ này được cách nhau bởi dấu phẩy (,) hoặc được lưu trong một mảng. Ví dụ:

$this->email->to('one@example.com, two@example.com, three@example.com');

$list = array('one@example.com', 'two@example.com', 'three@example.com');

$this->email->to($list);

cc()

Cú pháp:

$this->email->cc(string/array $emailAddresses)

Phương thức cc() cho phép thiết lập những địa chỉ email sẽ được nhận bản sao khi gửi email (carbon copy). Người nhận sẽ thấy những địa chỉ được thiết lập bằng phương thức cc(). Cũng giống như phương thức to(), ta có thể truyền vào danh sách các địa chỉ email hoặc một mảng.

bcc()

Cú pháp:

$this->email->bcc(string/array $emailAddresses)

Phương thức bcc() cho phép thiết lập những địa chỉ email sẽ được nhận bản sao khi gửi email, tuy nhiên người nhận sẽ không thấy những email được thiết lập trong phương thức to(), cc() và bcc() (blind carbon copy). Cũng giống như phương thức to(), ta có thể truyền vào danh sách các địa chỉ email hoặc một mảng.

subject()

Cú pháp:

$this->email->subject(string $subject)

Phương thức subject() cho phép thiết lập tiêu đề của email.

message()

Cú pháp:

$this->email->message(string $message)

Phương thức message() cho phép thiết lập nội dung của email.

set_alt_message()

Cú pháp:

$this->email->set_alt_message(string $message)

Phương thức set_alt_message() cho phép thiết lập nội dung thay thế của email. Nếu email được gửi có dạng HTML nhưng người nhận không muốn hiển thị HTML vì lý do bảo mật, nội dung thay thế này sẽ được hiển thị. Nếu phương thức này không được sử dụng, CodeIgniter sẽ tự động tách bỏ các tag HTML trong phần nội dung email làm nội dung thay thế.

set_header($header, $value)

Cú pháp:

$this->email->set_header($header, $value);

Hàm này có tác dụng thiết lập các tiêu đề (header) cho e-mail. Ví dụ:

$this->email->set_header('Tiêu_đề1', 'Giá_trị1');
$this->email->set_header('Tiêu_đề2', 'Giá_trị2');

clear()

Cú pháp:

$this->email->clear([boolean $clearAttachment])

Phương thức clear() sẽ xóa tất cả giá trị đ~ được thiết lập bởi các phương thức from(), reply_to(), to(), cc(), bcc(), subject(), message(). Phương thức này thường được sử dụng bên trong vòng lặp, giúp khởi động lại các giá trị sau mỗi lần lặp. Ví dụ:

foreach ($list as $name => $address) {

    $this->email->clear();

    $this->email->to($address);

    $this->email->from('your@example.com');

    $this->email->subject('Here is your info '.$name);

    $this->email->message('Hi '.$name.' Here is the info you requested.');

    $this->email->send();

}

Nếu biến tùy chọn $clearAttachment có giá trị TRUE, tất cả tập tin đính kèm cũng bị xóa.

send()

Cú pháp:

$this->email->send()

Phương thức send() sẽ thực hiện việc gửi email. Phương thức này trả về TRUE nếu gửi email thành công, ngược lại trả về FALSE.

attach()

Cú pháp:

$this->email->attach(string $filePath)

Phương thức attach() sẽ đính kèm tập tin vào email. Phương thức này nhận đường dẫn tương đối đến tập tin trên máy chủ làm đối số thứ nhất. Nếu muốn đính kèm nhiều tập tin, ta gọi phương thức này nhiều lần.

attachment_cid()

Cú pháp:

$this->email->attachment_cid($filename);

Thiết lập và trả về một Content-ID của tệp tin đính kèm, điều này cho phép bạn có thể nhúng một tệp tin (một ảnh chẳng hạn) vào phần HTML. Lưu ý là tham số của hàm phải là một tệp tin đã được đính kèm. Ví dụ:

$filename = '/img/photo1.jpg';
$this->email->attach($filename);
foreach ($list as $address)
{
    $this->email->to($address);
    $cid = $this->email->attachment_cid($filename);
    $this->email->message('<img src='cid:". $cid ."' alt="photo1" />');
    $this->email->send();
}

Lưu ý là Content-ID (CID) cho mỗi email phải được tạo lại để nó trở thành duy nhất.

print_debugger()

Cú pháp:

$this->email->print_debugger()

Phương thức print_debugger() sẽ hiển thị những thông tin trả về từ phía server, email header cũng như nội dung email. Thường được sử dụng cho việc gỡ lỗi. Ví dụ:

if ( $this->email->send() == FALSE ) {

    $this->email->print_debugger();

}

Thư viện Encryption

Trong một ứng dụng web, việc bảo mật thông tin của người sử dụng là điều bắt buộc. Đối với các ứng dụng thương mại điện tử, việc mã hóa thông tin khách hàng, chẳng hạn như số thẻ tín dụng, điện thoại, địa chỉ, email, ... quyết định sự sống còn của website.

Thư viện Encryption của CodeIgniter được xây dựng nhằm hỗ trợ lập trình viên thực hiện mã hóa/giải mã một cách đơn giản và hiệu quả.

Thư viện Encryption sử dụng cơ chế mã hóa đối xứng. Thông điệp cần mã hóa sẽ được tiền xử lý bằng cách thực hiện phép XOR với một đoạn hash ngẫu nhiên. Sau đó, kết quả thu được sẽ được mã hóa một lần nữa bởi thư viện Mcrypt. Nếu phiên bản PHP được cài đặt không kích hoạt thư viện Mcrypt, kết quả mã hóa vẫn cung cấp một mức độ bảo mật chấp nhận được cho các ứng dụng nhỏ. Trong trường hợp sử dụng thư viện Mcrypt, mức độ bảo mật được nâng cao rất nhiều.

Quan trọng

KHÔNG sử dụng thư viện này hoặc bất kỳ thư viện mã hóa nào để lưu trữ mật khẩu người dùng, thay vào đó mật khẩu phải được băm, và ta nên băm thông qua phần mở rộng mật khẩu băm của PHP.

Thư viện Encryption cung cấp phương pháp mã hóa dữ liệu hai chiều. Để thực hiện điều này được an toàn thì thư viện này sử dụng tiện ích mở rộng PHP nhưng lưu ý là không phải tất cả các hệ thống đều có. Bạn phải đáp ứng một trong các phụ thuộc sau đây để sử dụng thư viện này:

  • OpenSSL (và PHP 5.3.3)
  • Mcrypt (và MCRYPT_DEV_URANDOM sẵn có)

Nếu không thì CI sẽ không thể cung cấp cho bạn đủ các tiêu chuẩn cần thiết cho việc mã hóa thích hợp.

Khởi tạo lớp

Giống như hầu hết các lớp khác trong CodeIgniter, thư viện mã hóa được khởi tạo trong điều khiển của bạn bằng cách sử dụng $this->load->library():

$this->load->library('encryption');

Sau khi load xong thì ta sẽ sử dụng như sau:

$this->encryption

Hành vi mặc định

Theo mặc định, thư viện Encryption sẽ sử dụng các thuật toán mã hóa AES-128 ở chế độ CBC, sử dụng encryption_key và xác thực HMAC SHA512 đã được bạn cấu hình.

Lưu ý

AES-128 được quyền chọn cả hai, vì nó được chứng minh là đủ mạnh và vì nó có khả năng mở rộng bằng phần mềm mã hóa hoặc bằng các API của các ngôn ngữ lập trình khác nhau.

Tuy nhiên, encryption_key lại không được sử dụng như vậy.

Nếu bạn đang làm quen với mật mã, bạn nên biết rằng một HMAC cũng đòi hỏi một khóa bảo mật và sử dụng khóa tương tự cho cả mã hóa và xác thực, và đây lại là điều không nên làm.

Do đó ta cần có hai khóa riêng biệt có nguồn gốc từ encryption_key đã được cấu hình là: một cho mã hóa và một cho xác thực. Điều này được thực hiện thông qua một kỹ thuật gọi là HMAC-based Key Derivation Function (HKDF).

Thiết lập encryption_key

Một khóa mã hóa là một phần của thông tin điều khiển quá trình mã hóa và cho phép một chuỗi văn bản thông thường được mã hóa, và sau đó là giải mã. Đây chính là bí quyết trong toàn bộ quá trình để cho phép bạn là người duy nhất có thể giải mã dữ liệu đã mã hóa. Sau khi một khóa được sử dụng để mã hóa dữ liệu, thì khóa tương tự sẽ chỉ cung cấp cách thức giải mã, vì vậy, không những bạn phải lựa chọn một cách cẩn thận khóa, mà bạn còn phải không được để mất nó nếu không bạn sẽ mất quyền truy cập vào dữ liệu.

Cần lưu ý rằng để đảm bảo an toàn tối đa thì không những khóa cần phải mạnh mà nó còn phải thay đổi thường xuyên. Tuy nhiên hành vi như vậy là hiếm trong thực tế, và đó là lý do tại sao CodeIgniter cung cấp cho bạn khả năng cấu hình một khóa duy nhất và nó được sử dụng (gần như) mọi lúc.

Khóa mã hóa của bạn phải đủ dài theo từng thuật toán. Đối với mã hóa AES-128 thì kích thước là 128 bit (16 byte). Bảng phía dưới có đưa ra độ dài quy định ứng với từng thuật toán.

Khóa nên nên được tạo ra một cách ngẫu nhiên, và nó không nên là một chuỗi văn bản thông thường, cũng không phải là sản phẩm của một hàm băm. Để tạo khóa ta sử dụng phương thức create_key() như sau:

// $key sẽ được gán một giá trị ngẫu nhiên kích thước 16-byte (128-bit)
$key = $this->encryption->create_key(16);

Key có thể đươc lưu tại application/config/config.php hoặc bạn có thể thiết kế cơ chế lưu trữ riêng và truyền khóa tự động khi mã hóa / giải mã.

Để lưu mã khóa của riêng bạn thì bạn mở application/config/config.php và thiết lập:

$config['encryption_key'] = 'KEY của bạn';

Phương thức create_key() trả về dữ liệu dạng nhị phân, vì vậy ta cần sử dụng bin2hex(), hex2bin() hoặc Base64-encoding để làm việc với khóa được tạo từ phương thức này. Ví dụ:

// Lấy khóa chuẩn từ hàm bin2hex():
$key = bin2hex($this->encryption->create_key(16));

// Lưu vào tập tin config bằng cách
// chuyển ngược thành dạng nhị phân:
$config['encryption_key'] = hex2bin($key>);

Hỗ trợ mật mã mã hóa và các chế độ

Lưu ý
Các thuật ngữ "mật mã" và "thuật toán mã hóa" có thể tương đồng nhau.

Mật mã dành cho di động

Do Mcrypt và OpenSSL (trong bài viết này ta gọi là driver) hỗ trợ các thuật toán mã hóa khác nhau và thường xuyên thực hiện chúng theo những cách khác nhau, nên thư viện Encryption của CI được thiết kế để có thể sử dụng chúng trong các thiết bị di động.

Chúng cũng có thể được thực hiện một cách có mục đích để phù hợp với việc triển khai chuẩn trong các ngôn ngữ lập trình khác và các thư viện.

Dưới đây là danh sách các mật mã dành cho các thiết bị di động, trong đó "tên CodeIgniter" là giá trị dạng chuỗi mà bạn phải truyền tới thư viện Encryption để sử dụng thuật toán mã hóa:

Tên Mật mã Tên CodeIgniter Chiều dài key (bit / byte) Chế độ hỗ trợ
AES-128 / Rijndael-128 aes-128 128/16 CBC, CTR, CFB, CFB8, OFB, ECB
AES-192 aes-192 192/24 CBC, CTR, CFB, CFB8, OFB, ECB
AES-256 aes-256 256/32 CBC, CTR, CFB, CFB8, OFB, ECB
DES des 56/7 CBC, CFB, CFB8, OFB, ECB
TripleDES TripleDES 56/7, 112/14, 168/21 CBC, CFB, CFB8, OFB
Blowfish blowfish 128-448 / 16-56 CBC, CFB, OFB, ECB
CAST5 / CAST-128 cast5 88-128 / 11-16 CBC, CFB, OFB, ECB
RC4 / ARCFour rc4 40-2048 / 5-256 Suối
Quan trọng
Bởi vì cách Mcrypt hoạt động, nếu bạn không cung cấp một khóa với độ dài thích hợp, bạn có thể kết thúc bằng cách sử dụng một thuật toán khác nhau hơn so với một cấu hình, vì vậy hãy thực sự cẩn thận với điều đó!

Lưu ý

- Trong trường hợp nó không phải là rõ ràng từ bảng trên, Blowfish, CAST5 và hỗ trợ RC4 phím dài biến. Đó là, bất kỳ số lượng trong phạm vi được thể hiện là hợp lệ, mặc dù về mặt chút mà chỉ xảy ra trong gia số 8-bit.

- Mặc dù CAST5 hỗ trợ chiều dài khóa thấp hơn so với 128 bit (16 byte), trong thực tế, họ sẽ chỉ là zero-đệm với chiều dài tối đa, như quy định trong RFC 2144.

- Blowfish hỗ trợ chiều dài khóa nhỏ như 32 bit (4 byte), nhưng các xét nghiệm của chúng tôi đã chỉ ra rằng chỉ có độ dài 128 bit (16 byte) hoặc cao hơn được hỗ trợ đúng bởi cả hai Mcrypt và OpenSSL. Nó cũng là một thực tế xấu để sử dụng phím dài thấp như vậy anyway.

Các mật mã điều khiển cụ thể

Tên Mật mã Driver Chiều dài key (bit / byte) Chế độ hỗ trợ
AES-128 OpenSSL 128/16 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
AES-192 OpenSSL 192/24 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
AES-256 OpenSSL 256/32 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
Rijndael-128 Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Rijndael-192 Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Rijndael-256 Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
GOST Mcrypt 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
twofish Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
CAST-128 Mcrypt 40-128 / 5-16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
CAST-256 Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Loki97 Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
SaferPlus Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Serpent Mcrypt 128/16, 192/24, 256/32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
XTEA Mcrypt 128/16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
RC2 Mcrypt 8-1024 / 1-128 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
RC2 OpenSSL 8-1024 / 1-128 CBC, CFB, OFB, ECB
Camellia-128 OpenSSL 128/16 CBC, CFB, CFB8, OFB, ECB
Camellia-192 OpenSSL 192/24 CBC, CFB, CFB8, OFB, ECB
Camellia-256 OpenSSL 256/32 CBC, CFB, CFB8, OFB, ECB
hạt OpenSSL 128/16 CBC, CFB, OFB, ECB

Lưu ý

- Nếu bạn muốn sử dụng một trong những thuật toán mã hóa, bạn phải vượt qua tên của nó trong trường hợp thấp hơn đến các thư viện mã hóa.

- Bạn đã có thể nhận thấy rằng tất cả cipers AES (Rijndael và-128) cũng được liệt kê trong danh sách mật mã di động. Điều này là do trình điều khiển hỗ trợ các chế độ khác nhau cho các thuật toán mã hóa. Ngoài ra, điều quan trọng là cần lưu ý rằng AES-128 và Rijndael-128 thực sự là những mật mã giống nhau, nhưng chỉ khi được sử dụng với một phím 128-bit.

- CAST-128 / CAST-5 cũng được liệt kê trong cả di động và trình điều khiển cụ thể danh sách các mật mã. Điều này là do thực hiện OpenSSL không xuất hiện để được làm việc đúng với kích thước khóa 80 bit và thấp hơn.

- RC2 được liệt kê như là hỗ trợ bởi cả hai Mcrypt và OpenSSL. Tuy nhiên, cả hai trình điều khiển thực hiện chúng một cách khác nhau và họ là không cầm tay. Nó có lẽ là đáng chú ý là chúng tôi chỉ tìm thấy một nguồn vô danh xác nhận rằng nó là Mcrypt đó là không đúng thực hiện nó.

Các chế độ mã hóa

Các chế độ mã hóa khác nhau có những đặc điểm khác nhau và phục vụ cho các mục đích khác nhau. Một số chế độ mã hóa thì mạnh, một số lại nhanh hơn và cung cấp một số tính năng bổ sung. Bảng dưới đây cung cấp tài liệu tham khảo thông tin ngắn gọn về các chế độ mã hóa.

Tên chế độ Tên CodeIgniter Driver hỗ trợ Thông tin bổ sung
CBC cbc Mcrypt, OpenSSL Một sự lựa chọn mặc định an toàn
CTR ctr Mcrypt, OpenSSL Về lý thuyết thì tốt hơn so với CBC, nhưng không được phổ biến rộng rãi.
CFB CFB Mcrypt, OpenSSL N / A
CFB8 cfb8 Mcrypt, OpenSSL Tương tự như CFB, nhưng hoạt động ở chế độ 8-bit (không khuyến khích).
OFB ofb Mcrypt, OpenSSL N / A
OFB8 ofb8 Mcrypt Tương tự như OFB, nhưng hoạt động ở chế độ 8-bit (không khuyến khích).
ECB ECB Mcrypt, OpenSSL Bỏ qua IV (không khuyến khích).
XTS XTS OpenSSL Thường được sử dụng để mã hóa dữ liệu truy cập ngẫu nhiên như RAM hay lưu trữ đĩa cứng.
Stream stream Mcrypt, OpenSSL Đây thực ra không phải là một chế độ, nó chỉ là mật mã stream đang được sử dụng. Điều này là cần thiết vì các quá trình khởi tạo chế độ + mật mã chung.

Độ dài thông điệp (Message Length)

Có một điều quan trọng bạn cần biết là độ dài chuỗi đã được mã hóa thường dài hơn chuỗi gốc (là chuỗi văn bản thông thường), dài hơn bao nhiêu phụ thuộc vào mật mã. Cụ thể, IV thêm vào phía trước văn bản mật mã và thông điệp xác thực HMAC cũng được thêm vào phía trước. Hơn nữa, thông điệp được mã hóa cũng có thể là Base64-encoding cho nên nó đủ an toàn để lưu trữ và truyền dẫn.

Bạn cần ghi nhớ điều trên khi lựa chọn cơ chế lưu trữ dữ liệu. Ví dụ như Cookie chỉ có thể lưu giữ 4KB của thông tin.

Cấu hình thư viện

Thư viện Encryption được thiết kế để có thể sử dụng driver, mật mã mã hóa, chế độ và key nhiều lần.

Như đã đề cập trong phần "Hành vi mặc định" ở trên, điều này có nghĩa là sử dụng một driver tự động phát hiện (OpenSSL có một ưu tiên cao hơn), các ciper AES-128 trong chế độ CBC, và giá trị $config['encryption_key'] của bạn.

Tuy nhiên, nếu muốn ta có thể thay đổi điều này bằng cách sử dụng phương thức initialize(). Phương thức này chấp nhận một mảng kết hợp các thông số, tất cả đều là tùy chọn:

Tùy chọn Giá trị có thể
driver 'mcrypt', 'openssl'
cipher Tên mật mã
mode Chế độ mã hóa
key Khóa mã hóa

Ví dụ, nếu bạn đã thay đổi thuật toán mã hóa và chế độ mã hóa AES-256 ở chế độ CTR, thì bạn nên làm như sau:

$this->encryption->initialize(
        array(
                'cipher' => 'aes-256',
                'mode' => 'ctr',
                'key' => '<một chuỗi ngẫu nhiên 32 ký tự>'
        )
);

Cần lưu ý rằng ở đây ta chỉ đề cập đến việc thay đổi ciper và mode, nhưng ở ví dụ trên ta đề cập đến cả key. Như đã nói ở trên, điều quan trọng là ta cần chọn một key có kích thước thích hợp với các thuật toán được dùng đến.

Ngoài ra ta còn có khả năng thay đổi driver, nếu vì một lý do nào đó ta có đẩy đủ nhưng chỉ muốn sử dụng Mcrypt thay vì OpenSSL thì ta làm như sau:

//Chuyển sang driver Mcrypt 
$this->encryption->initialize(array('driver' => 'mcrypt'));

//chuyển về driver OpenSSL
$this->encryption->initialize(array('driver' => 'openssl'));

Mã hoá và giải mã dữ liệu

Mã hoá và giải mã dữ liệu với các thiết lập thư viện đã được cấu hình là công việc khá đơn giản với CI, đơn giản là ta chỉ cần truyền một chuỗi tới phương thức the encrypt() và / hoặc decrypt():

$plain_text = 'Đây là một tin nhắn văn bản đơn giản!';
$ciphertext = $this->encryption->encrypt($plain_text);

// Đầu ra: Đây là một tin nhắn văn bản đơn giản!
echo $this->encryption->decrypt($ciphertext);

Thư viện Encryption sẽ làm tất cả mọi thứ cần thiết cho toàn bộ quá trình được mã hóa an toàn ngoài khối và bạn không cần phải lo lắng về nó nữa.

Quan trọng

Cả hai phương thức trên đều sẽ trả về FALSE trong trường hợp có lỗi, trong khi đối với phương thức encrypt() lỗi này có nghĩa là cấu hình không chính xác, thì bạn cần luôn luôn kiểm tra giá trị trả về của decrypt() khi gặp lỗi.

Cách thức hoạt động

Dưới đây là cách thức hoạt động của hai phương thức này:

  • $this->encryption->encrypt($plain_text)

    1. Lấy ra một khoá mật mã và khóa HMAC từ cấu hình encryption_key qua HKDF, sử dụng SHA-512 để thực hiện thuật toán.

    2. Tạo một vector khởi tạo ngẫu nhiên (IV).

    3. Mã hóa dữ liệu thông qua mã hóa AES-128 trong chế độ CBC (hoặc một thuật toán mã hóa và chế độ cấu hình từ trước), sử dụng khóa mã hóa có nguồn gốc nói trên và IV.

    4. Thêm vào trước IV kết quả thuật toán mã hóa văn bản.

    5. Mã hóa Base64 cho kết quả dạng chuỗi, do đó nó có thể được lưu trữ an toàn hoặc chuyển đổi mà không cần lo lắng về tập ký tự.

    6. Tạo tin nhắn xác thực SHA-512 HMAC sử dụng phím HMAC nguồn gốc để đảm bảo tính toàn vẹn dữ liệu và thêm vào trước nó vào chuỗi Base64.

  • $this->encryption->decrypt($ciphertext)

    1. Lấy ra một khoá mật mã và khóa HMAC từ cấu hình encryption_key qua HKDF, sử dụng SHA-512 để thực hiện thuật toán. Do cấu hình encryption_key là như nhau, nên sẽ tạo ra những kết quả tương tự như trong phương thức encrypt() ở trên - nếu không bạn sẽ không thể giải mã nó.

    2. Kiểm tra nếu chuỗi là đủ dài thì tách HMAC ra khỏi nó và xác nhận nó đúng hay không (điều này được thực hiện nhằm ngăn chặn các cuộc tấn công trở lại). Trả về FALSE nếu một trong các kiểm tra lỗi.

    3. Giải mã chuỗi Base64.

    4. Tách IV ra khỏi thuật toán mã hóa văn bản và giải mã nó sử dụng IV và khóa mã hóa đã lấy ra.

Sử dụng các tham số tùy chỉnh

Bạn có thể tương tác với các hệ thống khác nằm ngoài tầm kiểm soát của bạn và sử dụng một phương thức khác để mã hóa dữ liệu, phương thức này không tuân theo trình tự nêu trên.

Thư viện Encryption cho phép ta thay đổi cách mã hóa và giải mã quá trình làm việc của nó, do đó bạn có thể dễ dàng điều chỉnh một giải pháp tùy chỉnh cho các tình huống như vậy.

Lưu ý

Có thể sử dụng các thư viện trong cách này, mà không cần thiết lập một encryption_key trong tập tin cấu hình của bạn.

Việc bạn cần phải làm là truyền một mảng kết hợp với một vài tham số cho một trong hai phương thức encrypt() hoặc decrypt. Ví dụ:

// Giả sử rằng chúng ta có $ciphertext, $key và $hmac_key từ nguồn bên ngoài

$message = $this->encryption->decrypt(
        $ciphertext,
        array(
                'cipher' => 'blowfish',
                'mode' => 'cbc',
                'key' => $key,
                'hmac_digest' => 'sha256',
                'hmac_key' => $hmac_key
        )
);

Trong ví dụ trên, ta giải mã một thông điệp đã được mã hóa bằng cách sử dụng thuật toán mã hóa Blowfish trong chế độ CBC và xác thực thông qua một HMAC SHA-256.

Quan trọng

Lưu ý rằng cả 'key' và 'hmac_key' đều được sử dụng trong ví dụ này. Khi sử dụng các tham số tùy chỉnh, mã hóa và khóa HMAC không bắt nguồn như hành vi mặc định của thư viện.

Dưới đây là một danh sách các tham số tùy chọn có sẵn. Tuy nhiên, trừ khi bạn thực sự cần và bạn biết những gì bạn đang làm, lời khuyên đưa ra là bạn không thay đổi quá trình mã hóa như đã trình bày ở trên vì có thể ảnh hưởng đến an toàn, vì vậy hãy làm điều này một cách thận trọng.

Tùy chọn Giá trị mặc định Bắt buộc / tùy chọn Sự miêu tả
cipher N/A Thuật toán mã hóa.
mode N/A Chế độ mã hóa.
key N/A Khóa mã hóa.
HMAC TRUE Không Nếu thiết lập là FALSE thì hmac_digest và hmac_key sẽ bị bỏ qua.
hmac_digest SHA512 Không Thông điệp HMAC yêu cầu thực hiện thuật toán.
hmac_key N/A Có, trừ khi HMAC là FALSE Khóa HMAC.
raw_data FALSE Không Nếu thiết lập là TRUE thì mã hóa và giải mã Base64 sẽ không được thực hiện và HMAC sẽ không thể là một chuỗi thập lục phân.

Quan trọng

encrypt() và decrypt() sẽ trả về FALSE nếu một tham số bắt buộc không được cung cấp hoặc nếu giá trị được cung cấp không chính xác, tham số bắt buộc ở đây là hmac_key, trừ khi HMAC được đặt là FALSE.

Các thuật toán xác thực HMAC được hỗ trợ

Để xác thực thông điệp HMAC, thư viện Encryption hỗ trợ việc sử dụng thuật toán SHA-2:

Thuật toán Chiều dài (byte) Chiều dài mã hóa hệ 16 (byte)
SHA512 64 128
sha384 48 96
sha256 32 64
sha224 28 56

Lý do của việc không sử dụng các thuật toán phổ biến khác như MD5 hoặc SHA1 là do chúng không còn được coi là đủ an toàn và như vậy, ta không nên sử dụng chúng. Nếu bạn buộc cần phải sử dụng chúng bạn có thể sử dụng hàm hash_hmac() của PHP.

Tham chiếu lớp CI_Encryption

initialize($params)

Tham số:
  • $ params (array) - các tham số cấu hình
Giá trị trả về:

Thể hiện của CI_Encryption

Kiểu trả về:

CI_Encryption

Phương thức này dùng để khởi tạo (cấu hình) thư viện để sử dụng trình điều khiển, thuật toán mã hóa, chế độ hoặc key khác nhau.

Ví dụ:

$this->encryption->initialize(
        array('mode' => 'ctr')
);

encrypt($data[$params = NULL])

Tham số:
  • $datachuỗi ) - Dữ liệu mã hóa
  • $ params(array) - Các tham số tùy chọn
Giá trị trả về:

 Dữ liệu được mã hóa hoặc FALSE nếu thất bại

Kiểu trả về:

string

Phương thức này có tác dụng mã hóa dữ liệu đầu vào và trả về giá trị mã hóa dạng văn bản.

Vi dụ:

$ciphertext = $this->encryption->encrypt('My secret message');

decrypt($data[$params = NULL])

Tham số:
  • $data(string) - Số liệu để giải mã
  • $ params (array) - Các tham số tùy chọn
Giá trị trả về:

Dữ liệu được giải mã hoặc FALSE nếu thất bại

Kiểu trả về:

string

Phương thức có nhiệm vụ giải mã các dữ liệu đầu vào và trả về nó dưới dạng văn bản thông thường.

Ví dụ:

echo $this->encryption->decrypt($ciphertext);

create_key($length)

Tham số:
  • $length(int) - Chiều dài đầu ra
Trả về:

Khóa mật mã giả ngẫu nhiên với chiều dài xác định, hoặc FALSE nếu thất bại

Kiểu trả về:

string

Nhiệm vụ của phương thức là tạo một khóa mật mã bằng cách lấy dữ liệu ngẫu nhiên từ các nguồn của hệ điều hành (ví dụ /dev/urandom).

hkdf($key[$digest = 'sha512'[$salt = NULL[$length = NULL[$info = '']]]])

Tham số:
  • $key(string) - Dữ liệu khóa đầu vào
  • $digest(string) - Một thuật toán SHA-2
  • $salt(string) - Tùy chọn
  • $length(int) - Chiều dài đầu ra tùy chọn
  • $info(string) - Tùy chọn bối cảnh / thông tin ứng dụng cụ thể
Trả về:

Một key giả ngẫu hoặc FALSE nếu thất bại

Kiểu trả về:

string

Phương thức này được sử dụng nội bộ để lấy mật mã và khóa HMAC từ cấu hình encryption_key.

Ví dụ:

$hmac_key = $this->encryption->hkdf(
        $key,
        'sha512',
        NULL,
        NULL,
        'authentication'
);

//$hmac_key là một key giả ngẫu nhiên với chiều dài 64 byte

Thư viện Session - Khởi tạo và hoạt động

Thư viện Session của CodeIgniter giúp quản lý trạng thái của người dùng khi họ truy cập website. Các thông tin này được lưu trữ (và mã hóa) trong một tập tin cookie. Hoặc ta cũng có thể thiết lập lưu trữ session trong cơ sở dữ liệu để nâng cao tính bảo mật. Lưu ý là khái niệm session ở đây không liên quan đến session của PHP. CodeIgniter tạo ra dữ liệu session của riêng nó, nhằm cung cấp một cách thức quản lý linh động hơn.

Khởi tạo một session

Để sử dụng thư viện Session, ta khai báo như sau:

$this->load->library('session');

Sau khi khai báo, ta có thể sử dụng các phương thức của thư viện Session bằng cách gọi:

$this->session->some_function();

 

Quan trọng

Do lớp Loader được khởi tạo bởi bộ điểu khiển cơ sở của CodeIgniter, vậy nên hãy đảm bảo rằng bạn đã gọi parent::__construct() trước khi cố gắng load một thư viện từ bên trong một hàm tạo controller.

Cách thức hoạt động

Khi một trang được tải về, lớp Session sẽ kiểm tra xem có dữ liệu session hợp lệ trong cookie của người dùng hay không. Nếu session không tồn tại hoặc đã hết hạn, một session mới sẽ được tạo ra và lưu vào cookie của người dùng.

Nếu session tồn tại, thông tin bên trong session sẽ được cập nhật và một session_id sẽ được tạo ra.

Điều quan trọng bạn cần phải hiểu đó là một khi đã được khởi tạo thì lớp Session sẽ chạy tự động và bạn không cần phải làm gì. Bạn cũng có thể xem phần bên dưới về dữ liệu session, nhưng những hoạt động như đọc, ghi và update một session là tự động.

Lưu ý:

Theo CLI, lớp Session sẽ tự động dừng chính nó, vì đây là ý tưởng hoàn toàn dựa trên giao thức HTTP.

Lưu ý về truy cập đồng thời (concurrency)

Trừ khi bạn đang phát triển một website thiên về sử dụng nhiều tính năng AJAX, bạn có thể bỏ qua phần lưu ý này. Tuy nhiên, nếu bạn đang gặp khó khăn về hiệu năng của website thì đây là lưu ý bạn nên xem xét.

Các Session trong các phiên bản trước đây của CodeIgniter đã không thực thi việc khóa (locking), có nghĩa là hai yêu cầu (request) HTTP sử dụng cùng một session lại có thể cùng chạy được trong cùng một thời điểm. Để thực hiện kỹ thuật này một cách phù hợp hơn thì các yêu cầu phải ở trạng thái không khóa (non-blocking).

Tuy nhiên, các yêu cầu mà ở trạng thái non-blocking thì lại không an toàn trong trường hợp là các session, nguyên do là vì những thay đổi đối với dữ liệu session (hoặc tạo session ID) trong một yêu cầu có thể gây cản trở đối với việc thực thi của yêu khác đang mong muốn truy cập đồng thời. Chi tiết này là nguồn gốc của nhiều vấn đề và là lý do chính để CodeIgniter 3.0 viết lại thư viện Session một cách hoàn chỉnh.

Vì sao ta lại nói về điều này? Bởi vì có thể sau khi cố gắng tìm được nguyên nhân về hiệu năng của website của bạn thì bạn có thể kết luận rằng khóa (locking) là một nguyên nhân và bạn sẽ có thể tìm cách để loại bỏ các khóa đi.

BẠN ĐỪNG LÀM ĐIỀU ĐÓ! Việc loại bỏ các khóa lại là hành động sai và nó sẽ gây ra nhiều vấn đề hơn!

Thực ra khóa không phải là vấn đề, nó là một giải pháp. Vấn đề ở đây là bạn vẫn mở session trong khi bạn đã xử lý xong nó, thế thì nó không còn cần đến nữa. Do đó, điều mà bạn cần làm là đóng session đối với yêu cầu hiện thời lại sau khi nó không còn cần đến nữa.

Đóng session bằng cách nào? bạn gọi đến hàm session_write_close() mỗi khi bạn không còn cần một biến session nào nữa.

Thư viện Session - Dữ liệu Session

Dữ liệu Session (Session Data) là gì?

Dữ liệu session đơn giản là một mảng kết hợp với một session ID cụ thể (cookie).

Nếu bạn đã quen với việc sử dụng các session trong PHP rồi thì bạn nên làm quen với $_SESSION superglobal của PHP.

CodeIgniter cho phép truy cập dữ liệu session của nó và sử dụng các thao tác (như đọc, thiết lập và hủy) trên mảng $_SESSION.

Mặt khác, CodeIgniter cũng cung cấp hai loại dữ liệu session đặc biệt sẽ được trình bày chi tiết bên dưới: flashdata và tempdata.

Lưu ý:

Trong những phiên bản CI trước đây thì dữ liệu session phổ biến được sử dụng là 'userdata'. Trong phiên bản này và về sau chủ yếu nó được viết để giải thích cách tùy chỉnh 'userdata' để các phương thức hoạt động.

Truy xuất dữ liệu Session

Bất kỳ thông tin nào của mảng session đều có sẵn trong $_SESSION superglobal:

$_SESSION['item']

Hoặc thông qua các getter magic:

$this->session->item

Và để tương thích ngược thì ta sử dụng phương thức userdata():

$this->session->userdata('item');

Trong đó item là chỉ số (key) của mảng mà bạn muốn lấy. Ví dụ như để gán key 'name' cho biến $name thì ta làm như sau:

$name = $_SESSION['name'];
// hoặc:
$name = $this->session->name
// hoặc:
$name = $this->session->userdata('name');

 

Lưu ý:

Phương thức userdata() trả về NULL nếu key bạn muốn truy cập không có sẵn.

Nếu bạn muốn truy xuất tất cả các userdata thì đơn giản là bạn chỉ cần làm như sau:

$_SESSION

// hoặc:

$this->session->userdata();

Thêm dữ liệu Session

Giả sử có một người dùng đăng nhập vào site của bạn. Sau khi xác thực, bạn có thể thêm tên đăng nhập và địa chỉ email vào session, và sau đó bạn có quyền sử dụng những dữ liệu đó trong session mà không cần phải thao tác gì với database cả.

Công việc của bạn lúc này là chỉ việc gán dữ liệu vào mảng $_SESSION giống như các biến thông thường, hoặc bạn có thể thực hiện: $this->session.

Ngoài ra, bạn có thể dùng cách thức cũ để gán dữ liệu ở dạng "userdata" bằng cách truyền một mảng chứa dữ liệu tương ứng tới phương thức set_userdata():

$this->session->set_userdata($array);

Trong đó, $array là một mảng kết hợp có chứa dữ liệu của bạn. Ví dụ:

$newdata = array(
  'username'  => 'johndoe',
  'email'     => 'johndoe@some-site.com',
  'logged_in' => TRUE
);

$this->session->set_userdata($newdata);

Nếu bạn muốn thêm vào userdata từng giá trị một thì bạn có thể làm như sau:

$this->session->set_userdata('some_name', 'some_value');

Nếu bạn muốn kiểm tra xem một biến session nào đó có tồn tại hay không thì bạn đơn giản là dùng phương thức isset():

// trả về FALSE nếu biến 'some_name' không có hoặc chứa NULL,
// trả về TRUE nếu ngược lại:
isset($_SESSION['some_name'])

Hoặc bạn cũng có thể gọi phương thức has_userdata():

$this->session->has_userdata('some_name');

Xóa dữ liệu Session

Để xóa một dữ liệu session nào đó trong $_SESSION thì bạn có thể sử dụng phương thức unset():

unset($_SESSION['some_name']);
// hoặc xóa nhiều:
unset(
        $_SESSION['some_name'],
        $_SESSION['another_name']
);

Ngoài ra, ta có thể sử dụng phương thức unset_userdata() để xóa dữ liệu session. Ví dụ như nếu bạn muốn xóa 'some_name' khỏi dữ liệu session bạn làm như sau:

$this->session->unset_userdata('some_name');

Hoặc nếu bạn muốn xóa cùng lúc nhiều dữ liệu session thì bạn làm như sau:

$array_items = array('username', 'email');

$this->session->unset_userdata($array_items);

 

Lưu ý:

Trong những phiên bản trước thì phương thức unset_userdata() dùng được cho mảng nhưng theo dạng cặp key => 'dummy value'. Ở phiên hiện này thì điều đó không còn được hỗ trợ nữa.

Thư viện Session - Flashdata và Tempdata

Flashdata

CodeIgniter hỗ trợ "flashdata", là những session chỉ được sử dụng một lần và sẽ được xóa tự động.

Điều này có thể rất hữu dụng, đặc biệt là cho một lần cung cấp thông tin, lỗi hoặc các thông báo trạng thái.

Cần lưu ý rằng các biến flashdata là các biến session thông thường, chỉ khác ở một điểm là có thêm key '__ci_vars'.

Nếu bạn muốn đánh dấu một biến session nào đó là "flashdata" thì bạn có thể làm như sau:

$this->session->mark_as_flash('name');

Nếu bạn muốn đánh dấu cùng lúc nhiều biến thành flashdata thì bạn làm như sau:

$this->session->mark_as_flash(array('name1', 'name2'));

Để thêm một flashdata ta làm như sau:

$_SESSION['name'] = 'value';
$this->session->mark_as_flash('name');

Ngoài ra, ta cũng có thể sử dụng phương thức set_flashdata():

$this->session->set_flashdata('item', 'value');

Bạn cũng có thể truyền một mảng tới set_flashdata() giống như với hàm set_userdata().

Để đọc dữ liệu trong một biến flashdata thì ta cũng làm tương tự như dữ liệu session với $_SESSION:

echo $_SESSION['item']

 

Quan trọng:

Phương thức userdata() sẽ không trả về các biến flashdata.

Nếu bạn chỉ muốn làm việc với biến "flashdata" thì bạn có thể sử dụng phương thức flashdata():

$this->session->flashdata('item');

Hoặc nếu bạn muốn lấy tất cả các biến flashdata thì bạn làm như sau:

$this->session->flashdata();

 

Lưu ý:

Phương thức flashdata() trả về NULL nếu item không phải là flashdata.

Nếu bạn thấy rằng bạn cần phải bảo quản một biến flashdata thông qua một yêu cầu bổ sung thì bạn có thể sử dụng phương thức keep_flashdata(). Bạn có thể truyền một biến hoặc một mảng flashdata tới phương thức để bảo quản.

$this->session->keep_flashdata('item');
$this->session->keep_flashdata(array('item1', 'item2', 'item3'));

Tempdata

CodeIgniter cũng hỗ trợ “tempdata”, đây là loại dữ liệu session có thời gian hết hạn xác định. Sau khi hết hạn giá trị hoặc hết hạn session hoặc hết bị xóa, thì giá trị của tempdata tự động bị xóa.

Tương tự như flashdata, các biến tempdata là những biến session chính quy được đánh dấu bằng key ‘__ci_vars’.

Để đánh dấu một biến là “tempdata” thì đơn giản là bạn truyền key của nó và thời gian hết hạn (bằng giây-second) tới phương thức mark_as_temp():

// 'item' sẽ bị xóa sau 300 seconds
$this->session->mark_as_temp('item', 300);

Bạn cũng có thể đánh dấu cùng lúc nhiều biến là tempdata bằng hai cách sau, phụ thuộc vào việc bạn muốn tất cả chúng có cùng thời gian hết hạn hay không:

// Cả 'item' và 'item2' sẽ hết hạn sau 300 seconds
$this->session->mark_as_temp(array('item', 'item2'), 300);

// 'item' sẽ bị xóa sau 300 seconds, còn 'item2'
// bị xóa sau 240 seconds
$this->session->mark_as_temp(array(
        'item'  => 300,
        'item2' => 240
));

Để thêm một biến tempdata:

$_SESSION['item'] = 'value';
$this->session->mark_as_temp('item', 300);

Hoặc có thể thêm bằng cách dùng phương thức set_tempdata():

$this->session->set_tempdata('item', 'value', 300);

Bạn cũng có thể thêm cùng lúc nhiều tempdata bằng cách truyền một mảng tới set_tempdata():

$tempdata = array('newuser' => TRUE, 'message' => 'Thanks for joining!');
$this->session->set_tempdata($tempdata, NULL, $expire);

 

Lưu ý:

Nếu giá trị hết hạn không được đặt hoặc được đặt là 0 thì giá trị mặc định là 300 giây (5 phút) sẽ được sử dụng.

Để đọc một biến tempdata ta lại sử dụng mảng $_SESSION superglobal:

$_SESSION['item']

 

Quan trọng:

Phương thức userdata() sẽ không trả về biến tempdata.

Hoặc nếu bạn muốn đảm bảo rằng bạn đang đọc biến tempdata mà không phải là loại nào khác thì bạn dùng phương thức tempdata():

$this->session->tempdata('item');

Và đương nhiên, nếu bạn muốn truy xuất đến tất cả các tempdata đã có thì bạn sử dụng:

$this->session->tempdata();

 

Lưu ý:

Phương thức tempdata() trả về NULL nếu không tìm thấy biến tempdata.

Nếu bạn cần xóa một giá trị tempdata trước khi nó hết hạn thì bạn có thể trực tiếp unset nó từ mảng $_SESSION:

unset($_SESSION['item']);

Tuy nhiên, điều này sẽ không xóa được marker đã đánh dấu biến là tempdata (nó sẽ không có giá trị ở lần yêu cầu HTTP tiếp theo), cho nên nếu bạn muốn sử dụng khóa tương tự trong cùng một yêu cầu thì bạn dùng phương thức unset_tempdata():

$this->session->unset_tempdata('item');

Thư viện Session - Hủy và truy cập dữ liệu Session

Hủy Session

Để xóa session hiện thời (ví dụ xóa trước khi đăng xuất) thì bạn đơn giản là sử dụng phương thức session_destroy() của PHP hoặc phương thức sess_destroy(). Cả hai phương thức đều làm việc theo cách thức giống nhau:

session_destroy();

// hoặc:

$this->session->sess_destroy();

 

Lưu ý:

Hoạt động hủy cần phải được thực hiện cuối cùng, bởi vì tất cả các dữ liệu session (bao gồm cả flashdata và tempdata) sẽ bị hủy vĩnh viễn và các hàm sẽ không thể sử dụng được khi có yêu cầu sau khi hủy session.

Truy cập siêu dữ liệu session

Trong những phiên bản CodeIgniter trước đây thì mảng dữ liệu session bao gồm bốn thành là 'session_id', 'ip_address', 'user_agent' và 'last_activity'.

Chúng được sử dụng để xác định cách thức hoạt động của session, nhưng từ phiên bản CI này thì điều đó không cần thiết nữa. Tuy nhiên, có thể ứng dụng của bạn lại dựa trên những giá trị này, cho nên ta có thể sử dụng những phương thức sau đây để thay thế chúng.

  • session_id: session_id()

  • ip_address: $_SERVER['REMOTE_ADDR']

  • user_agent: $this->input->user_agent()

  • last_activity: Phụ thuộc vào vấn đề lưu trữ, không có cách thế nào.

Form Helper - Phần 1

Tập tin Form Helper có chứa những hàm hỗ trợ cho người dùng làm việc với các form.

Để tải helper này ta dùng câu lệnh sau:

$this->load->helper('form');

Hàm html_escape()

Có thể bạn cần sử dụng HTML và các ký tự như các dấu nháy chẳng hạn trong các phần tử của form. Để thực hiện điều này an toàn thì ta cần sử dụng hàm html_escape().

Xét ví dụ sau:

$string = 'Here is a string containing "quoted" text.';

<input type="text" name="myfield" value="<?php echo $string; ?>" />

Vì chuỗi ở trên chứa hai cặp nháy là nháy đơn và nháy kép, cho nên nó sẽ dẫn đến lỗi form khi thể hiện dữ liệu cho thẻ <input> tương ứng. Hàm html_escape() sẽ làm nhiệm vụ chuyển đổi các ký tự sang dạng đặc biệt và điều này sẽ khắc phục được lỗi:

<input type="text" name="myfield" value="<?php echo html_escape($string); ?>" />

Lưu ý

Nếu ta sử dụng bất kỳ một hàm nào của form helper để tạo phần tử cho trang web thì các giá trị của form sẽ tự động được làm phù hợp, vì thế ta không cần sử dụng hàm html_escape() trong trường hợp này. html_escape() chỉ cần được dùng đến khi ta tự tạo các phần tử của form một cách thông thường.

Các hàm của Form Helper

form_open($action,$attributes,$hidden)

Tham số:
  • $action (string) – Chuỗi action/target URI của form
  • $attributes (array) – Các thuộc tính HTML
  • $hidden (array) – Mảng định nghĩa các trường ẩn
Trả về:

Thẻ mở form HTML

Kiểu trả về:

 string

Hàm này dùng để tạo một thẻ mở form với URL cơ sở được xây dựng từ các tham chiếu cấu hình của bạn. Nó cho phép ta có thể thêm các thuộc tính form và ẩn các trường input, nó cũng luôn luôn thêm thuộc tính accept-charset dựa trên giá trị charset trong tập tin cấu hình của bạn.

Ưu điểm chính của việc sử dụng thẻ này là giảm được lượng code HTML, nó cho làm cho site của bạn uyển chuyển hơn trong trường hợp thay đổi các URL.

Ví dụ:

echo form_open('email/send');

Ví dụ trên tạo một form trỏ tới URL cơ sở của bạn ghép với đoạn URI "email/send", chẳng hạn nó có thể tương đương như sau:

<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send">

Thêm thuộc tính

Thuộc tính có thể được thêm vào hàm này bằng cách sử dụng tham số thứ hai dạng như sau:

$attributes = array('class' => 'email', 'id' => 'myform');
echo form_open('email/send', $attributes);

Bạn cũng có thể đặc tả tham số thứ hai dưới dạng chuỗi như sau:

echo form_open('email/send', 'class="email" id="myform"');

Ví dụ trên sẽ tạo một form dạng như sau:

<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" class="email" id="myform">

Thêm trường ẩn

Để thêm trường ẩn thì ta sử dụng tham số thứ ba của hàm dạng như sau:

$hidden = array('username' => 'Joe', 'member_id' => '234');
echo form_open('email/send', '', $hidden);

Ví dụ trên tương đương với việc tạo một form như sau:

<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send">
        <input type="hidden" name="username" value="Joe" />
        <input type="hidden" name="member_id" value="234" />

form_open_multipart($action,$attributes,$hidden)

Tham số:
  • $action (string) – Chuỗi URI cho thuộc tính action/target
  • $attributes (array) – Các thuộc tính HTML
  • $hidden (array) – Mảng định nghĩa các trường ẩn
Trả về:

Thẻ mở multipart form HTML

Kiểu trả về: 

string

Hàm này giống hệt như hàm form_open() ở trên, chỉ khác một điều là nó có thêm thuộc tính multipart, thuộc tính này được dùng để upload tập tin.

form_hidden($name,$value)

Tham số:
  • $name (string) – Tên trường
  • $value (string) – Giá trị của trường
Trả về:

Thẻ <input type="hidden">

Kiểu trả về: 

string

Hàm này dùng để tạo thẻ <input type="hidden">. Hàm cho phép thiết lập tên (thuộc tính name) của thẻ và giá trị (thuộc tính value) của thẻ đó:

form_hidden('username', 'johndoe');
// Sẽ tạo ra: <input type="hidden" name="username" value="johndoe" />

Bạn cũng có thể tạo cùng lúc nhiều thẻ hidden bằng cách sử dụng mảng như sau:

$data = array(
        'name'  => 'John Doe',
        'email' => 'john@example.com',
        'url'   => 'http://example.com'
);

echo form_hidden($data);

/*
 Sẽ tạo ra:
 <input type="hidden" name="name" value="John Doe" />
 <input type="hidden" name="email" value="john@example.com" />
 <input type="hidden" name="url" value="http://example.com" />
*/

Bạn cũng có thể tạo một mảng thẻ hidden bằng cách sau:

$data = array(
        'name'  => 'John Doe',
        'email' => 'john@example.com',
        'url'   => 'http://example.com'
);

echo form_hidden('my_array', $data);

/*
 Sẽ tạo ra:

 <input type="hidden" name="my_array[name]" value="John Doe" />
 <input type="hidden" name="my_array[email]" value="john@example.com" />
 <input type="hidden" name="my_array[url]" value="http://example.com" />
*/

Nếu bạn muốn tạo thẻ input hidden bao gồm nhiều thuộc tính hơn bạn làm như sau:

$data = array(
        'type'  => 'hidden',
        'name'  => 'email',
        'id'    => 'hiddenemail',
        'value' => 'john@example.com',
        'class' => 'hiddenemail'
);

echo form_input($data);

/*
 Sẽ tạo ra:

 <input type="hidden" name="email" value="john@example.com" id="hiddenemail" class="hiddenemail" />
*/

form_input($data,$value,$extra)

Tham số:
  • $data (array) – Các thuộc tính của thẻ
  • $value (string) – Giá trị của thẻ
  • $extra (mixed) – Các thuộc tính mở rộng của thẻ
Trả về:

Thẻ <input type="text">

Kiểu trả về: 

string

Hàm này dùng để tạo thẻ <input type="text">. Bạn có thể truyền vào hai đối số là tên và giá trị vào hai tham số đầu của hàm như sau:

echo form_input('username', 'johndoe');

Hoặc bạn cũng có thể truyền một mảng chứa các dữ thuộc tính của thẻ như sau:

$data = array(
        'name'          => 'username',
        'id'            => 'username',
        'value'         => 'johndoe',
        'maxlength'     => '100',
        'size'          => '50',
        'style'         => 'width:50%'
);

echo form_input($data);

/*
 Sẽ tạo ra:

 <input type="text" name="username" value="johndoe" id="username" maxlength="100" size="50" style="width:50%"  />
*/

Nếu bạn muốn thẻ chứa những dữ liệu mở rộng như JavaScript chẳng hạn, thì bạn có thể làm như sau:

$js = 'onClick="some_function()"';
echo form_input('username', 'johndoe', $js);

Hoặc truyền ở dạng mảng:

$js = array('onClick' => 'some_function();');
echo form_input('username', 'johndoe', $js);

form_password($data,$value,$extra)

Tham số:
  • $data (array) – Các thuộc tính của thẻ
  • $value (string) – Giá trị của thẻ
  • $extra (mixed) – Các thuộc tính mở rộng của thẻ
Trả về:

Thẻ <input type="password">

Kiểu trả về: 

string

Form Helper - Phần 2

form_upload($data,$value,$extra)

Tham số:
  • $data (array) – Các thuộc tính của thẻ
  • $value (string) – Giá trị của thẻ
  • $extra (mixed) – Các thuộc tính mở rộng của thẻ
Trả về:

Thẻ <input type="file">

Kiểu trả về: 

string

form_textarea($data,$value,$extra)

Tham số:
  • $data (array) – Các thuộc tính của thẻ
  • $value (string) – Giá trị của thẻ
  • $extra (mixed) – Các thuộc tính mở rộng của thẻ
Trả về:

Thẻ <textarea>

Kiểu trả về: 

string

Lưu ý
Cần thay thế các thuộc tính maxlength và size bằng các thuộc tính rows và cols.

form_dropdown($name,$options,$selected,$extra)

Tham số:
  • $name (string) – Tên của thẻ <select>
  • $options (array) – Mảng chứa các thẻ <option>
  • $selected (array) – Các <option> được đánh dấu với thuộc tính selected
  • $extra (mixed) – Các thuộc tính mở rộng
Trả về:

Thẻ <select> và các thẻ con <option>

Kiểu trả về: 

string

Hàm này dùng để tạo một thẻ <select> với các thẻ con <option>. Bạn cũng có thể truyền một mảng để tạo nhiều thẻ <select>.

Ví dụ:

$options = array(
        'small'         => 'Small Shirt',
        'med'           => 'Medium Shirt',
        'large'         => 'Large Shirt',
        'xlarge'        => 'Extra Large Shirt',
);

$shirts_on_sale = array('small', 'large');
echo form_dropdown('shirts', $options, 'large');

/*
 Sẽ tạo ra:

 <select name="shirts">
  <option value="small">Small Shirt</option>
  <option value="med">Medium  Shirt</option>
  <option value="large" selected="selected">Large Shirt</option>
  <option value="xlarge">Extra Large Shirt</option>
 </select>
*/

echo form_dropdown('shirts', $options, $shirts_on_sale);

/*
 Sẽ tạo ra:

 <select name="shirts" multiple="multiple">
  <option value="small" selected="selected">Small Shirt</option>
  <option value="med">Medium  Shirt</option>
  <option value="large" selected="selected">Large Shirt</option>
  <option value="xlarge">Extra Large Shirt</option>
 </select>
*/

Bạn cũng có thể truyền JavaScript bằng cách như sau:

$js = 'id="shirts" onChange="some_function();"';
echo form_dropdown('shirts', $options, 'large', $js);

Hoặc truyền ở dạng mảng:

$js = array(
        'id'       => 'shirts',
        'onChange' => 'some_function();'
);
echo form_dropdown('shirts', $options, 'large', $js);

Nếu mảng truyền $options là mảng đa chiều thì form_dropdown() sẽ tạo một <optgroup> với key của mảng là các nhãn.

form_multiselect($name,$options,$selected,$extra)

Tham số:
  • $name (string) – Tên của thẻ <select>
  • $options (array) – Mảng chứa các thẻ <option>
  • $selected (array) – Các <option> được đánh dấu với thuộc tính selected
  • $extra (mixed) – Các thuộc tính mở rộng
Trả về:

Thẻ <select> và các thẻ con <option> với thuộc tính multiple kèm theo (tạo một dropdown multiselect)

Kiểu trả về: 

string

Hàm này tương tự hàm form_dropdown() nhưng có thêm thuộc tính multiple để tạo danh sách cho phép chọn nhiều tùy chọn

form_fieldset($legend_text,$attributes)

Tham số:
  • $legend_text (string) – Chuỗi đặt trong thẻ <legend>
  • $attributes (array) – Các thuộc tính của thẻ <fieldset>
Trả về:

Thẻ <fieldset> và thẻ con <legend>

Kiểu trả về:

string

Ví dụ:

echo form_fieldset('Address Information');
echo "<p>fieldset content here</p>\n";
echo form_fieldset_close();

/*
 Sẽ tạo ra:

 <fieldset>
  <legend>Address Information</legend>
   <p>form content here</p>
 </fieldset>
*/

Tương tự như các hàm khác, bạn có thể submit một mảng ở tham số thứ hai nếu bạn muốn thêm các thuộc tính, ví dụ:

$attributes = array(
        'id'    => 'address_info',
        'class' => 'address_info'
);

echo form_fieldset('Address Information', $attributes);
echo "<p>fieldset content here</p>\n";
echo form_fieldset_close();

/*
 Sẽ tạo ra:

 <fieldset id="address_info" class="address_info">
  <legend>Address Information</legend>
   <p>form content here</p>
 </fieldset>
*/

form_fieldset_close($extra)

Tham số:

$extra (string) – Thêm vào sau thẻ đóng </fieldset>

Trả về:

Thẻ đóng </fieldset>

Kiểu trả về: 

string

Ví dụ:

$string = '</div></div>';
echo form_fieldset_close($string);
// Sẽ tạo ra: </fieldset></div></div>

form_checkbox($data,$value,$checked,$extra)

Tham số:
  • $data (array) – Các thuộc tính của thẻ <checkbox>
  • $value (string) – Giá trị của thẻ
  • $checked (bool) – Tích mặc định cho thẻ hay không
  • $extra (mixed) – Các thuộc tính mở rộng của thẻ
Returns:

An HTML checkbox input tag

Return type:

string

Hàm này dùng để tạo thẻ <input type="checkbox">. Ví dụ:

echo form_checkbox('newsletter', 'accept', TRUE);
// Sẽ tạo ra:
<input type="checkbox" name="newsletter" value="accept" checked="checked" />

Tham số thứ ba của hàm dùng để xác định có mặc định tích trước cho checkbox hay không (thông qua thuộc tính checked).

Tương tự như những hàm khác thì ta cũng có thể thiết lập các thuộc tính cho checkbox bằng cách truyền mảng thuộc tính tới hàm. Ví dụ:

$data = array(
        'name'          => 'newsletter',
        'id'            => 'newsletter',
        'value'         => 'accept',
        'checked'       => TRUE,
        'style'         => 'margin:10px'
);

echo form_checkbox($data);
// Sẽ tạo ra:
<input type="checkbox" name="newsletter" id="newsletter" value="accept" checked="checked" style="margin:10px" />

Nếu bạn cũng muốn thêm code như JavaScript chẳng hạn cho checkbox thì bạn có thể làm như sau đối với thuộc tính thứ tư của hàm:

$js = 'onClick="some_function()"';
echo form_checkbox('newsletter', 'accept', TRUE, $js);

Hoặc bạn có thể truyền nó như một mảng:

$js = array('onClick' => 'some_function();');
echo form_checkbox('newsletter', 'accept', TRUE, $js);

form_radio($data,$value,$checked,$extra)

Tham số:
  • $data (array) – Các thuộc tính của <radio>
  • $value (string) – Giá trị của radio
  • $checked (bool) – Tích hay không tích cho radio
  • $extra (mixed) – Các thuộc tính mở rộng
Trả về:

Thẻ <input type="radio">

Kiểu trả về:

string

Hàm này có tác dụng tương tự như hàm form_checkbox(), chỉ khác là nó tạo ra thẻ <input type="radio">.

form_label($label_text,$id,$attributes)

Tham số:
  • $label_text (string) – Nhãn cho thẻ <label>
  • $id (string) – ID của phần tử form
  • $attributes (string) – Các thuộc tính của <label>
Trả về: Thẻ <label>
Kiểu trả về:

string

Hàm này dùng để tạo thẻ <label>. Ví dụ:

echo form_label('What is your Name', 'username');
// Sẽ tạo ra:
<label for="username">What is your Name</label>

Ví dụ sau sẽ tạo thẻ label với các thuộc tính thêm vào:

$attributes = array(
        'class' => 'mycustomclass',
        'style' => 'color: #000;'
);

echo form_label('What is your Name', 'username', $attributes);
// Sẽ tạo ra:
<label for="username" class="mycustomclass" style="color: #000;">What is your Name</label>

form_submit($data,$value,$extra)

Tham số:
  • $data (string) – Tên của nút submit
  • $value (string) – Giá trị của nút submit
  • $extra (mixed) – Các thuộc tính mở rộng cho submit
Trả về: Thẻ <input type="submit">
Kiểu trả về:

string

Hàm này dùng để tạo nút lệnh submit. Ví dụ:

echo form_submit('mysubmit', 'Submit Post!');
// Sẽ tạo ra:
<input type="submit" name="mysubmit" value="Submit Post!" />

Tương tự như các hàm khác, ta có thể thiết lập các thuộc tính cho submit thông qua mảng các thuộc tính ở tham số thứ ba của hàm.

form_reset($data,$value,$extra)

Tham số:
  • $data (string) – Tên của nút reset
  • $value (string) – Giá trị của reset
  • $extra (mixed) – Các thuộc tính mở rộng
Trả về:

Thẻ <input type="reset">

Kiểu trả về: 

string

Hàm này dùng để tạo nút lệnh reset (<input type="reset">). Hàm này thường dùng với hàm form_submit().

Form Helper - Phần 3

form_button($data,$content,$extra)

Tham số:
  • $data (string) – Tên nút lệnh
  • $content (string) – Nhãn của nút lệnh
  • $extra (mixed) – Các thuộc tính mở rộng của nút lệnh
Trả về: Thẻ <button></button>
Kiểu trả về:

string

Hàm này dùng để tạo thẻ <button>. Ví dụ:

echo form_button('name','content');
// Sẽ tạo ra:
<button name="name" type="button">Content</button>

Bạn cũng có thể truyền một mảng thuộc tính cho hàm để tạo các thuộc tính cho nút lệnh như sau:

$data = array(
        'name'          => 'button',
        'id'            => 'button',
        'value'         => 'true',
        'type'          => 'reset',
        'content'       => 'Reset'
);

echo form_button($data);
// Sẽ tạo ra:
<button name="button" id="button" value="true" type="reset">Reset</button>

Nếu bạn muốn chứa code JavaScript chẳng hạn, trong thuộc tính sự kiện thì ta có thể làm như sau:

$js = 'onClick="some_function()"';
echo form_button('mybutton', 'Click Me', $js);

form_close($extra)

Tham số:

$extra (string) – Đưa thêm nội dung vào sau thẻ đóng </form>

Trả về:

Thẻ </form>

Kiểu trả về: 

string

Hàm này tạo thẻ đóng </form>. Nếu đối số của hàm tồn tại thì nội dung trong đối số sẽ được đặt sau thẻ đóng này. Ví dụ:

$string = '</div></div>';
echo form_close($string);
// Sẽ tạo ra: </form></div></div>

set_value($field,$default,$html_escape)

Tham số:
  • $field (string) – Tên của thẻ
  • $default (string) – Giá trị mặc định
  • $html_escape (bool) – Bật/tắt trong việc lấy dấu nháy
Trả về:

Giá trị của thẻ (trong thuộc tính value)

Kiểu trả về: 

string

Hàm này dùng để thiết lập giá trị cho thẻ <input> hoặc <textarea>. Tham số thứ nhất sẽ chứa tên của trường, tham số thứ hai (tùy chọn) sẽ dùng để thiết lập giá trị mặc định cho thẻ, còn tham số thứ ba (tùy chọn) dùng để tắt/bật trong việc lấy dấu nháy. Trong trường hợp cần thiết thì bạn nên sử dụng kết hợp với hàm form_input() để tránh việc trùng lặp dấu nháy. Ví dụ:

<input type="text" name="quantity" value="<?php echo set_value('quantity', '0'); ?>" size="50" />

Thẻ <input> ở trên sẽ hiển thị trong nó giá trị mặc định là 0.

Lưu ý
Nếu bạn đã tải thư viện Form Validation và thiết lập các quy tắc xác định tính hợp lệ cho thẻ khi sử dụng helper này thì nó sẽ chuyển tới lời gọi phương thức set_value(), nếu không thì hàm sẽ tìm giá trị trong $_POST.

set_select($field,$value,$default)

Tham số:
  • $field (string) – tên của thẻ <select>
  • $value (string) – Giá trị cho thẻ con <option>
  • $default (string) – có sử dụng thuộc tính selected cho <option> hay không
Trả về:

Trả về thuộc tính 'selected' hoặc một chuỗi rỗng

Kiểu trả về: 

string

Hàm này sẽ tạo giá trị (tham số thứ hai) cho thẻ <option> của <select> đồng thời chỉ định có hay không (tham số thứ 3) việc sử dụng thuộc tính selected cho <option> đó. Ví dụ:

<select name="myselect">
        <option value="one" <?php echo  set_select('myselect', 'one', TRUE); ?> >One</option>
        <option value="two" <?php echo  set_select('myselect', 'two'); ?> >Two</option>
        <option value="three" <?php echo  set_select('myselect', 'three'); ?> >Three</option>
</select>

set_checkbox($field,$value,$default)

Tham số:
  • $field (string) – Tên của checkbox
  • $value (string) – Giá trị của checkbox
  • $default (string) – Có dùng checked hay không
Trả về:

Thuộc tính 'checked' hoặc chuỗi rỗng

Kiểu trả về: 

string

Hàm này dùng để thiết lập giá trị cho checkbox và có thiết lập hay không thuộc tính checked cho nó. Ví dụ:

<input type="checkbox" name="mycheck" value="1" <?php echo set_checkbox('mycheck', '1'); ?> />
<input type="checkbox" name="mycheck" value="2" <?php echo set_checkbox('mycheck', '2', TRUE); ?> />

set_radio($field,$value,$default)

Tham số:
  • $field (string) – Tên thẻ radio
  • $value (string) – Giá trị cho radio
  • $default (string) – Dùng checked hay không
Trả về:

Thuộc tính 'checked' hoặc chuỗi rỗng

Kiểu trả về: 

string

Hàm này dùng để thiết lập giá trị cho radio và thiết lập checked hay không cho nó. Ví dụ:

<input type="radio" name="myradio" value="1" <?php echo  set_radio('myradio', '1', TRUE); ?> />
<input type="radio" name="myradio" value="2" <?php echo  set_radio('myradio', '2'); ?> />
Lưu ý
Nếu bạn sử dụng lớp Form Validation thì bạn phải xác định quy tắc cho trường của bạn cho dù nó trống để cho các hàm dạng set_*() hoạt động. Lý do là bởi vì nếu một đối tượng của lớp Form Validation được định nghĩa thì quyền điều khiển sẽ được trao cho các hàm dạng set_*() thông qua một phương thức của lớp đó thay vì tạo một hàm helper.

form_error($field,$prefix,$suffix)

Tham số:
  • $field (string) – Tên trường
  • $prefix (string) – Thẻ mở lỗi
  • $suffix (string) – Thẻ đóng lỗi
Trả về:

Thông báo lỗi đặt trong thẻ HTML tương ứng

Kiểu trả về: 

string

Trả về thông báo lỗi từ thư viện Form Validation được đặt trong tên của trường tương ứng. Ta có thể tùy chọn xác định thẻ mở và thẻ đóng để bao ngoài thông báo lỗi.

Ví dụ:

// Giả sử rằng giá trị của trường 'username' là không đúng thì:
echo form_error('myfield', '<div class="error">', '</div>');

// sẽ tạo ra: <div class="error">Thông báo lỗi cho trường 'username'.</div>

validation_errors($prefix,$suffix)

Tham số:
  • $prefix (string) – Thẻ mở error
  • $suffix (string) – Thẻ đóng error
Trả về:

Thẻ thông báo lỗi hợp lệ của form đã được định dạng HTML

Kiểu trả về: 

string

Tương tự như hàm form_error(), hàm này trả về tất cả các thông báo lỗi được tạo ra từ thư viện Form Validation, trong đó mỗi thông báo lỗi đều được đặt trong thẻ mở và đóng.

Ví dụ:

echo validation_errors('<span class="error">', '</span>');

/*
Khi phát sinh lỗi thì thông báo lỗi sẽ có dạng như sau:

 <span class="error">Thông báo lỗi!</span

 */

form_prep($str)

Tham số:

$str (string) – Giá trị escape

Trả về:

Giá trị escape

Kiểu trả về: 

string

Hàm này cho phép sử dụng HTML và các ký tự một cách an toàn (chẳng hạn như các dấu nháy) trong các phần tử của form mà không lo bị lỗi form.

Lưu ý
- Nếu sử dụng bất kỳ một hàm nào của form helper thì các giá trị của các phần tử form sẽ tự động được sử dụng một cách an toàn và tự động, do vậy bạn không cần phải gọi hàm form_prep() nữa.
- Hàm này đã lỗi thời, bạn nên dùng hàm html_escape() để thay thế.

HTML Helper

Helper này có chứa các hàm hỗ trợ cho ta khi làm việc với HTML.

Tải HTML Helper

$this->load->helper('html');

Các hàm hiện có của HTML Helper

heading($data, $h, $attributes)

Tham số:
  • $data (string) – Nội dung
  • $h (string) – Mức tiêu đề
  • $attributes (mixed) – Các thuộc tính HTML
Trả về:

Thẻ Heading

Kiểu trả về:

string

Hàm này dùng để tạo các thẻ tiêu đề HTML, trong đó tham số đầu tiên là nội dung mà thẻ chứa, tham số thứ hai là mức tiêu đề của thẻ. Ví dụ:

echo heading('Welcome!', 3);

// Sẽ tạo ra: <h3>Welcome!</h3>

Ngoài ra, để thêm các thuộc tính cho thẻ heading như là class, id hay style thì ta sử dụng tham số thứ 3 của hàm và thể hiện nó ở dạng mảng hoặc chuỗi. Ví dụ:

echo heading('Welcome!', 3, 'class="pink"');
echo heading('How are you?', 4, array('id' => 'question', 'class' => 'green'));

//Sẽ tạo ra:

<h3 class="pink">Welcome!<h3>
<h4 id="question" class="green">How are you?</h4>

img($src, $index_page, $attributes)

Tham số:
  • $src (string) – Nguồn ảnh
  • $index_page (bool) – Có thiết lập $src như là một URI định tuyến hay không
  • $attributes (array) – Các thuộc tính HTML
Trả về:

Thẻ <img>

Kiểu trả về:

 string

Hàm này dùng để tạo thẻ <img />. Tham số đầu tiên chứa nguồn của ảnh. Ví dụ:

echo img('public/images/article/picture.jpg'); // gives <img src="http://site.com/public/images/article/picture.jpg" />

Tham số tùy chọn thứ hai chứa giá trị TRUE hoặc FALSE dùng để xác định xem nguồn ảnh có được dùng trong $config['index_page'] hay không. Ví dụ:

echo img('public/images/article/picture.jpg', TRUE);

// Sẽ tương đương: <img src="http://site-của-bạn.com/index.php/public/images/article/picture.jpg" alt="" />

Ngoài ra, ta co thể dùng tham số thứ 3 để cung cấp các thuộc tính cho thẻ <img>. Nếu bạn không cung cấp giá trị cho thuộc tính alt thì nó sẽ được gán một chuỗi rỗng. Ví dụ:

$image_properties = array(
        'src'   => 'public/images/article/picture.jpg',
        'alt'   => 'Me, demonstrating how to eat 4 slices of pizza at one time',
        'class' => 'post_public/images/article',
        'width' => '200',
        'height'=> '200',
        'title' => 'That was quite a night',
        'rel'   => 'lightbox'
);

img($image_properties);
//Sẽ tạo ra: <img src="http://site.com/index.php/public/images/article/picture.jpg" alt="Me, demonstrating how to eat 4 slices of pizza at one time" class="post_public/images/article" width="200" height="200" title="That was quite a night" rel="lightbox" />

link_tag($href, $rel, $type, $title, $media, $index_page)

Tham số:
  • $href (string) – URL liên kết tới tập tin CSS
  • $rel (string) – Kiểu quan hệ
  • $type (string) – Kiểu tài liệu quan hệ
  • $title (string) – Tiêu đề link
  • $media (string) – Kiểu media
  • $index_page (bool) – Có áp dụng $src cho chuỗi URI định tuyến hay không
Trả về:

Thẻ <link />

Kiểu trả về:

 string

Hàm này dùng để tạo thẻ <link />. Ví dụ:

echo link_tag('css/mystyles.css');
//Sẽ tạo ra: <link href="http://site.com/css/mystyles.css" rel="stylesheet" type="text/css" />

echo link_tag('favicon.ico', 'shortcut icon', 'image/ico');
//Sẽ tạo ra: <link href="http://site.com/favicon.ico" rel="shortcut icon" type="image/ico" />

echo link_tag('feed', 'alternate', 'application/rss+xml', 'My RSS Feed');
//Sẽ tạo ra: <link href="http://site.com/feed" rel="alternate" type="application/rss+xml" title="My RSS Feed" />

Ngoài ra, ta có thể sử dụng mảng để tạo các thuộc tính và truyền vào cho hàm link() như ví dụ sau:

$link = array(
        'href'  => 'css/printer.css',
        'rel'   => 'stylesheet',
        'type'  => 'text/css',
        'media' => 'print'
);

echo link_tag($link);

//Sẽ tạo ra: <link href="http://site.com/css/printer.css" rel="stylesheet" type="text/css" media="print" />

ul($list, $attributes)

Tham số:
  • $list (array) – Danh sách các <li> với các text tương ứng
  • $attributes (array) – Các thuộc tính HTML
Trả về:

Thẻ <ul> và các thẻ con <li>

Kiểu trả về:

 string

Hàm này cho phép bạn tạo thẻ <ul> và các thẻ con <li>. Ví dụ:

$list = array(
        'red',
        'blue',
        'green',
        'yellow'
);

$attributes = array(
        'class' => 'boldlist',
        'id'    => 'mylist'
);

echo ul($list, $attributes);

//Sẽ tạo ra:

<ul class="boldlist" id="mylist">
  <li>red</li>
  <li>blue</li>
  <li>green</li>
  <li>yellow</li>
</ul>

Còn dưới đây là ví dụ phức tạp hơn dùng mảng đa chiều:

$attributes = array(
        'class' => 'boldlist',
        'id'    => 'mylist'
);

$list = array(
        'colors'  => array(
                'red',
                'blue',
                'green'
        ),
        'shapes'  => array(
                'round',
                'square',
                'circles' => array(
                        'ellipse',
                        'oval',
                        'sphere'
                )
        ),
        'moods'  => array(
                'happy',
                'upset' => array(
                        'defeated' => array(
                                'dejected',
                                'disheartened',
                                'depressed'
                        ),
                        'annoyed',
                        'cross',
                        'angry'
                )
        )
);

echo ul($list, $attributes);

//Đoạn mã trên sẽ tạo ra:

<ul class="boldlist" id="mylist">
        <li>colors
                <ul>
                        <li>red</li>
                        <li>blue</li>
                        <li>green</li>
                </ul>
        </li>
        <li>shapes
                <ul>
                        <li>round</li>
                        <li>suare</li>
                        <li>circles
                                <ul>
                                        <li>elipse</li>
                                        <li>oval</li>
                                        <li>sphere</li>
                                </ul>
                        </li>
                </ul>
        </li>
        <li>moods
                <ul>
                        <li>happy</li>
                        <li>upset
                                <ul>
                                        <li>defeated
                                                <ul>
                                                        <li>dejected</li>
                                                        <li>disheartened</li>
                                                        <li>depressed</li>
                                                </ul>
                                        </li>
                                        <li>annoyed</li>
                                        <li>cross</li>
                                        <li>angry</li>
                                </ul>
                        </li>
                </ul>
        </li>
</ul>

ol($list, $attributes)

Tham số:
  • $list (array) – Danh sách các thẻ <li> với các text tương ứng
  • $attributes (array) – Các thuộc tính của <ol>
Trả về:

Thẻ <ol> với các thẻ con <li>

Kiểu trả về:

 string

Hàm này tương tự như hàm ul(), chỉ khác ở chỗ nó tạo ra thẻ <ol> thay vì thẻ <ul>.

meta($name, $content, $type, $newline)

Tham số:
  • $name (string) – Tên thẻ <meta>
  • $content (string) – Nội dung thẻ <meta>
  • $type (string) – Kiểu thẻ <meta>
  • $newline (string) – Ký tự xuống dòng
Trả về:

Thẻ <meta>

Kiểu trả về:

 string

Hàm này giúp ta tạo thẻ <meta>. Ta có thể truyền các chuỗi tới hàm, hoặc một mảng đơn hoặc mảng đa chiều. Ví dụ:

echo meta('description', 'My Great site');
// Sẽ tạo ra:  <meta name="description" content="My Great Site" />

echo meta('Content-type', 'text/html; charset=utf-8', 'equiv');
// Lưu ý: tham số thứ 3 có thể là "equiv" hoặc "name"
// Sẽ tạo ra:  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

echo meta(array('name' => 'robots', 'content' => 'no-cache'));
// Sẽ tạo ra:  <meta name="robots" content="no-cache" />

$meta = array(
        array(
                'name' => 'robots',
                'content' => 'no-cache'
        ),
        array(
                'name' => 'description',
                'content' => 'My Great Site'
        ),
        array(
                'name' => 'keywords',
                'content' => 'love, passion, intrigue, deception'
        ),
        array(
                'name' => 'robots',
                'content' => 'no-cache'
        ),
        array(
                'name' => 'Content-type',
                'content' => 'text/html; charset=utf-8', 'type' => 'equiv'
        )
);

echo meta($meta);

// Sẽ tạo ra:

// <meta name="robots" content="no-cache" />
// <meta name="description" content="My Great Site" />
// <meta name="keywords" content="love, passion, intrigue, deception" />
// <meta name="robots" content="no-cache" />
// <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

doctype($type)

Tham số:

$type (string) – Tên của <!doctype>

Trả về:

Khai báo <!doctype>

Kiểu trả về:

 string

Thẻ này dùng để tạo khai báo <!doctype> hoặc các DTD, mặc định là XHTML 1.0 Strict. Ví dụ:

echo doctype();
//Sẽ tạo ra: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

echo doctype('html4-trans');
//Sẽ tạo ra: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

Dưới đây là một danh sách các lựa chọn doctype, ta có thể cấu hình và lấy nó từ application/config/doctypes.php:

Document type Tùy chọn Sẽ cho ra
XHTML 1.1 xhtml11 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd“>
XHTML 1.0 Strict xhtml1-strict <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd“>
XHTML 1.0 Transitional xhtml1-trans <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
XHTML 1.0 Frameset xhtml1-frame <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Frameset//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd“>
XHTML Basic 1.1 xhtml-basic11 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML Basic 1.1//EN” “http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd“>
HTML 5 html5 <!DOCTYPE html>
HTML 4 Strict html4-strict <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd“>
HTML 4 Transitional html4-trans <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd“>
HTML 4 Frameset html4-frame <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Frameset//EN” “http://www.w3.org/TR/html4/frameset.dtd“>
MathML 1.01 mathml1 <!DOCTYPE math SYSTEM “http://www.w3.org/Math/DTD/mathml1/mathml.dtd“>
MathML 2.0 mathml2 <!DOCTYPE math PUBLIC “-//W3C//DTD MathML 2.0//EN” “http://www.w3.org/Math/DTD/mathml2/mathml2.dtd“>
SVG 1.0 svg10 <!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.0//EN” “http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd“>
SVG 1.1 Full svg11 <!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd“>
SVG 1.1 Basic svg11-basic <!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1 Basic//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd“>
SVG 1.1 Tiny svg11-tiny <!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1 Tiny//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd“>
XHTML+MathML+SVG (XHTML host) xhtml-math-svg-xh <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN” “http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd“>
XHTML+MathML+SVG (SVG host) xhtml-math-svg-sh <!DOCTYPE svg:svg PUBLIC “-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN” “http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd”>
XHTML+RDFa 1.0 xhtml-rdfa-1 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML+RDFa 1.0//EN” “http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd“>
XHTML+RDFa 1.1 xhtml-rdfa-2 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML+RDFa 1.1//EN” “http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd“>

br($count)

Tham số:

$count (int) – Số lượng thẻ <br /> muốn tạo

Trả về:

Thẻ <br/>

Kiểu trả về:

 string

Hàm này dùng để tạo thẻ <br />). Ví dụ:

echo br(3);

//Sẽ tạo ra:

<br /><br /><br />

Lưu ý là hàm này không còn được khuyến khích dùng nữa, ta nên dùng hàm str_repeat() kết hợp với thẻ <br /> để thay thế.

nbs($num)

Tham số:

$num (int) – Số lượng dấu cách (space) muốn tạo

Trả về:

Các dấu cách (non-breaking space)

Kiểu trả về:

 string

Hàm này dùng để tạo các dấu cách (&nbsp). Ví dụ:

echo nbs(3);

//Sẽ tạo ra:

&nbsp;&nbsp;&nbsp;

Lưu ý là hàm này không còn được khuyến khích dùng nữa, thay vào đó ta nên dùng hàm str_repeat() kết hợp với &nbsp; để thay thế.

Text Helper

Tải Text Helper

Để tải helper này ta sử dụng câu lệnh như sau:

$this->load->helper('text');

Các hàm thao tác

word_limiter($str, $limit, $end_char)

Parameters:
  • $str (string) – Chuỗi đầu vào
  • $limit (int) – Số từ muốn cắt
  • $end_char (string) – Ký tự kết thúc (thường là dấu ba chấm )
Trả về:

Một chuỗi con với số lượng từ tương ứng bắt đầu tính từ bên trái

Kiểu trả về:

string

Hàm này dùng để cắt chuỗi lấy một số lượng từ nhất định. Ví dụ:

$string = "Here is a nice text string consisting of eleven words.";
$string = word_limiter($string, 4);
// Trả về:  Here is a nice

Tham số thứ ba là một hậu tố tùy chọn thêm vào sau chuỗi lấy được, mặc định là dấu ba chấm (...).

character_limiter($str, $n = 500, $end_char)

Tham số:
  • $str (string) – Chuỗi đầu vào
  • $n (int) – Số lượng ký tự muốn cắt
  • $end_char (string) – Ký tự kết thúc thêm vào
Trả về:

Một chuỗi với số lượng ký tự mong muốn

Kiểu trả về:

string

Hàm này dùng để cắt một số lượng ký tự mong muốn từ chuỗi đầu vào bắt đầu từ bên trái chuỗi đó. Nó vẫn đảm bảo tính toán vẹn của từ mặc dù có thể vượt quá hoặc ít hơn số ký tự muốn cắt. Ví dụ:

$string = "Here is a nice text string consisting of eleven words.";
$string = character_limiter($string, 20);
// Trả về:  Here is a nice text string

Tham số thứ 3 dùng để thêm hậu tố vào sau chuỗi cắt được, thường là dấu 3 chấm.

Lưu ý
Nếu bạn cần cắt một số lượng ký tự chính xác bạn có thể sử dụng hàm ellipsize() như trình bày bên dưới.

ascii_to_entities($str)

Tham số:

$str (string) – Chuỗi đầu vào

Trả về:

Một chuỗi các giá trị ASCII đã được chuyển thành ký tự

Kiểu trả về:

string

Hàm này dùng để chuyển các giá trị ASCII thành các ký tự tương ứng, bao gồm cả các ký tự ASCII mức cào và các ký tự trong MS Word mà khi sử dụng trên trang web có thể gặp vấn đề, điều này giúp ta thể hiện được các ký tự mà không bị phụ thuộc vào cài đặt trình duyệt hay cách thức lưu trữ chúng trong cơ sở dữ liệu. Có một số sự phục thuộc vào sự hỗ trợ của máy chủ đối với các ký tự, vì thế mà một số ký tự có thể không hiển thị đúng theo cách thông thường (chẳng hạn như các ký tự có dấu).

Ví dụ:

$string = ascii_to_entities($string);

convert_accented_characters($str)

Tham số:

$str (string) – Chuỗi đầu vào

Trả về:

Một chuỗi với các ký tự có dấu chuyển đổi

Kiểu trả về:

string

Hàm này dùng để chuyển đổi một chuỗi chứa các ký tự ASCII từ chữ hoa sang chữ thường. Điều này hữu dụng khi các ký tự không phải là tiếng Anh cần được sử dụng ở những nơi chỉ bao gồm các ký tự ASCII một cách an toàn, ví dụ như các URL.

Ví dụ:

$string = convert_accented_characters($string);
Lưu ý
Hàm này sử dụng một tập tin cấu hình đi kèm là application/config/foreign_chars.php để định nghĩa đến và từ mảng dùng cho việc chuyển ngữ.

word_censor($str, $censored, $replacement)

Tham số:
  • $str (string) – Chuỗi đầu vào
  • $censored (array) – Các từ cần kiểm duyệt
  • $replacement (string) – Thay thế những từ cần kiểm duyệt
Trả về:

Chuỗi đã được kiểm duyệt

Kiểu trả về:

string

Hàm này cho phép ta kiểm duyệt các từ trong một chuỗi. Tham số đầu tiên sẽ chứa chuỗi gốc, tham số thứ hai chứa một mảng các từ ta cần kiểm duyệt, còn tham số thứ 3 (tùy chọn) chứa giá trị thay thế cho các từ kiểm duyệt, nếu tham số thứ 3 không được sử dụng thì chúng mặc định được thay bằng: ####.

Ví dụ:

$disallowed = array('darn', 'shucks', 'golly', 'phooey');
$string = word_censor($string, $disallowed, 'Beep!');

highlight_code($str)

Tham số:

$str (string) – Chuỗi đầu vào

Trả về:

Chuỗi mã đã được highlight bằng HTML

Kiểu trả về:

string

Hàm này dùng để đánh dấu (highlight) một chuỗi mã (PHP, HTML, ...). Ví dụ:

$string = highlight_code($string);

Hàm này sử dụng hàm của PHP là highlight_string(), vậy nên các màu được sử dụng được quy định tại tập tin php.ini.

highlight_phrase($str, $phrase, $tag_open, $tag_close)

Tham số:
  • $str (string) – Chuỗi đầu vào
  • $phrase (string) – Phrase to highlight
  • $tag_open (string) – Opening tag used for the highlight
  • $tag_close (string) – Closing tag for the highlight
Returns:

String with a phrase highlighted via HTML

Return type:

string

Hàm này dùng để làm nổi bật một cụm từ trong chuỗi văn bản đầu vào. Tham số đầu tiên chứa chuỗi gốc, tham số thứ hai chứa cụm mà bạn muốn đánh dấu, tham số thứ ba và thứ tư chứa thẻ nở và đóng bao cụm muốn đánh dấu.

Ví dụ:

$string = "Here is a nice text string about nothing in particular.";
echo highlight_phrase($string, "nice text", '<span style="color:#990000;">', '</span>');

Đoạn mã trên sẽ tương đương:

Here is a <span style="color:#990000;">nice text</span> string about nothing in particular.
Lưu ý
Hàm này được dùng để sử dụng thẻ <strong> mặc định. Những trình duyệt cũ không hỗ trợ HTML5 thì ta nên chèn đoạn mã CSS sau:
mark {
        background: #ff0;
        color: #000;
};

word_wrap($str, $charlim)

Tham số:
  • $str (string) – Chuỗi đầu vào
  • $charlim (int) – Số lượng giới hạn ký tự
Trả về:

Chuỗi đã được ngắt từ

Kiểu trả về:

string

Hàm này có nhiệm vụ ngắt một chuỗi thành các hàng.

Ví dụ:

$string = "Here is a simple string of text that will help us demonstrate this function.";
echo word_wrap($string, 25);

// Sẽ tạo ra:

// Here is a simple string
// of text that will help us
// demonstrate this
// function.

ellipsize($str, $max_length, $position, $ellipsis)

Tham số:
  • $str (string) – Chuỗi đầu vào
  • $max_length (int) – Giới hạn độ dài chuỗi
  • $position (mixed) – Vị trí phân tách (int hoặc float)
  • $ellipsis (string) – Loại dấu chấm lửng
Returns:

Chuỗi đã được chèn dấu chấm lửng

Return type:

string

Hàm này dùng để loại bỏ thẻ trong chuỗi, cắt bớt số lượng ký tự mong muốn và chèn thay vào đó dấu chấm lửng.

Tham số đầu tiên là chuỗi muốn thiết lập dấu chấm lửng, tham số thứ hai là số lượng ký tự muốn bỏ đi, tham số thứ 3 là một số từ 0-1 thể hiện vị trí đặt dấu chấm lửng, trong đó nếu là 1 thì dấu 3 chấm được đặt ở bên phải, 0 thì được đặt bên trái, 0.5 được đặt chính giữa chuỗi.

Tham số tùy chọn thứ 4 là loại dấu chấm lửng, mặc định là &hellip;.

Ví dụ:

$str = 'this_string_is_entirely_too_long_and_might_break_my_design.jpg';
echo ellipsize($str, 32, .5);

Sẽ tạo ra:

this_string_is_e&hellip;ak_my_design.jpg

Lớp Query Builder

CodeIgniter cho phép ta truy cập lớp Query Builder. Lớp này cho phép các thông tin được truy xuất, chèn và cập nhật trong cơ sở dữ liệu bằng cách viết các câu lệnh (script) ngắn gọn và tối giản. Trong một số trường hợp chỉ có một hoặc hai dòng lệnh cần thiết để thực hiện thao tác trên một cơ sở dữ liệu. CodeIgniter không yêu cầu mỗi bảng trong cơ sở dữ liệu phải có tập tin lớp của chính nó, thay vào đó nó sẽ cung cấp một giao diện (interface) đơn giản.

Ngoài tính đơn giản, một lợi ích lớn nữa của việc sử dụng các tính năng của Query Builder là nó cho phép tạo Cơ sở dữ liệu độc lập với các ứng dụng do cú pháp truy vấn được tạo bởi từng bộ chuyển đổi cơ sở dữ liệu. Sử dụng Query Builder cũng đảm bảo các truy vấn được an toàn hơn vì các giá trị được hệ thống tự động thiết lập tính an toàn.

Lưu ý
Nếu bạn muốn viết các truy vấn riêng mà không cần dùng đến Query Builder thì bạn có thể vô hiệu hóa lớp này trong tập tin cấu hình cơ sở dữ liệu, điều này sẽ cho phép thư viện cơ sở dữ liệu lõi và bộ chuyển đổi sử dụng ít tài nguyên hơn.

Các khả năng sau của Query Builder được mô tả bằng các nhóm hàm dưới đây.

Các hàm SELECT dữ liệu

Dưới đây sẽ trình bày những hàm dùng để xây dựng các câu lệnh SELECT.

$this->db->get()

Hàm này sẽ thực hiện câu lệnh select và trả về kết quả là các bản ghi có được, nó tương đương với câu lệnh Select * From Tên_bảng.

$query = $this->db->get('mytable'); // Tương đương: SELECT * FROM mytable

Tham số thứ 2 và 3 của hàm cho phép ta thiết lập vị trí bắt đầu lấy bản ghi và số lượng bản ghi muốn lấy:

$query = $this->db->get('mytable', 10, 20);

// Tương đương: SELECT * FROM mytable LIMIT 20, 10

Cần lưu ý rằng để lấy kết quả truy vấn thì cần phải gán hàm cho một biến, hàm trên được gán cho một biến có tên $query:

$query = $this->db->get('mytable');

foreach ($query->result() as $row)
{
    echo $row->title;
}

$this->db->get_compiled_select()

Hàm này trả về câu lệnh truy vấn dưới dạng một chuỗi.

Ví dụ:

$sql = $this->db->get_compiled_select('mytable');
echo $sql;

// Sẽ in ra chuỗi: SELECT * FROM mytable

Tham số thứ 2 cho phép ta thiết lập việc có hay không query builder được thiết đặt lại (mặc định là có, giống như khi sử dụng $this->db->get()):

echo $this->db->limit(10,20)->get_compiled_select('mytable', FALSE);

// Sẽ in ra chuỗi: SELECT * FROM mytable LIMIT 20, 10

echo $this->db->select('title, content, date')->get_compiled_select();

// Sẽ in ra chuỗi: SELECT title, content, date FROM mytable LIMIT 20, 10

Một điểm quan trọng cần lưu ý trong ví dụ trên là câu truy vấn thứ hai không sử dụng $this->db->from() và không truyền tên bảng vào tham số thứ nhất. Lý do là vì câu truy vấn không được thực thi bằng cách sử dụng $this->db->get() để đặt lại giá trị hoặc đặt lại thư mục bằng cách sử dụng $this->db->reset_query().

$this->db->get_where()

Tương tự như hàm trên, chỉ khác là nó có thêm mệnh đề where ở tham số thứ hai mà không cần sử dụng hàm db->where():

$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);

Vui lòng đọc thêm về mệnh để where phía dưới để biết thêm thông tin.

Lưu ý
get_where() trước đây có định dạng là getwhere() và bây giờ định dạng này đã bị bỏ.

$this->db->select()

Hàm này cho phép ta thực hiện câu lệnh SELECT với các cột mong muốn:

$this->db->select('title, content, date');
$query = $this->db->get('mytable');

// Tương đương: SELECT title, content, date FROM mytable

 

Lưu ý
Nếu muốn chọn tất cả các cột của một bảng thì ta không cần sử dụng hàm này, chỉ cần dùng hàm $this->db->get().

$this->db->select() có tham số tùy chọn thứ hai, nếu ta đặt là FALSE thì CodeIgniter sẽ không bảo về các trường hay các bảng nữa. Điều này rất hữu ích nếu như ta cần một câu lệnh select gộp trong đó có thể bỏ qua những trường ảnh hưởng đến câu lệnh gộp này.

$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE);
$query = $this->db->get('mytable');

$this->db->select_max()

Hàm này dùng để lấy giá trị lớn nhất của cột cụ thể, tham số thứ hai của hàm dùng để đặt bí danh.

$this->db->select_max('age');
$query = $this->db->get('members');
// Tương đương: SELECT MAX(age) as age FROM members

$this->db->select_max('age', 'member_age');
$query = $this->db->get('members');
// Tương đương: SELECT MAX(age) as member_age FROM members

$this->db->select_min()

Hàm này tương tự hàm trên nhưng dùng để lấy giá trị nhỏ nhất của cột.

$this->db->select_min('age');
$query = $this->db->get('members');
// Produces: SELECT MIN(age) as age FROM members

$this->db->select_avg()

Hàm này tương tự hàm trên, nhưng dùng để tính giá trị trung bình của cột.

$this->db->select_avg('age');
$query = $this->db->get('members');
// Produces: SELECT AVG(age) as age FROM members

$this->db->select_sum()

Hàm này tương tự hàm trên, nhưng dùng để tính tổng các giá trị của cột.

$this->db->select_sum('age');
$query = $this->db->get('members');
// Produces: SELECT SUM(age) as age FROM members

$this->db->from()

Hàm này dùng để tạo mệnh đề FROM trong truy vấn:

$this->db->select('title, content, date');
$this->db->from('mytable');
$query = $this->db->get();
// Produces: SELECT title, content, date FROM mytable

 

Lưu ý
Ta nên dùng $this->db->get() vì hàm này tạo mệnh đề FROM.

$this->db->join()

Hàm dùng để liên kết bảng:

$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');
$query = $this->db->get();

// Sẽ tạo ra:
// SELECT * FROM blogs JOIN comments ON comments.id = blogs.id

Bạn có quyền gọi hàm này nhiều lần để liên kết nhiều bảng.

Nếu bạn cần xác định kiểu của JOIN thì bạn có thể thực hiện bằng tham số thứ 3 của hàm. Các tùy chọn gồm: left, right, outer, inner, left outer, và right outer.

$this->db->join('comments', 'comments.id = blogs.id', 'left');
// Tương đương: LEFT JOIN comments ON comments.id = blogs.id

Các hàm truy vấn với WHERE

$this->db->where()

Hàm này cho phép bạn thiết lập mệnh đề WHERE sử dụng một trong bốn cách thức sau:

Lưu ý
Tất cả các giá trị được truyền tới hàm này đều bị ngắt tự động để tạo các truy vấn an toàn hơn.

1. Dùng key/value thông thường:

$this->db->where('name', $name); // Sẽ tạo ra: WHERE name = 'Joe'

Lưu ý rằng dấu gán tự động được thêm.

Nếu bạn sử dụng nhiều lời gọi hàm thì có thể chúng sẽ được gộp với nhau thông qua toán tử AND:

$this->db->where('name', $name);
$this->db->where('title', $title);
$this->db->where('status', $status);
// WHERE name = 'Joe' AND title = 'boss' AND status = 'active'

2. Dùng key/value tùy chỉnh:

Ta có thể đưa vào một toán tử trong tham số thứ nhất để điều khiển phép toán so sánh:

$this->db->where('name !=', $name);
$this->db->where('id <', $id); // Sẽ tạo ra: WHERE name != 'Joe' AND id < 45

3. Dùng mảng kết hợp:

$array = array('name' => $name, 'title' => $title, 'status' => $status);
$this->db->where($array);
// Sẽ tạo ra: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'

Ta có thể gộp các toán tử mong muốn bằng cách sử dụng cách thức như sau:

$array = array('name !=' => $name, 'id <' => $id, 'date >' => $date);
$this->db->where($array);

4. Dùng chuỗi tùy chỉnh:

Ta cũng có thể viết một chuỗi truy vấn thông thường như sau:

$where = "name='Joe' AND status='boss' OR status='active'";
$this->db->where($where);

$this->db->where() sẽ chấp nhận một tùy chọn ở tham số thứ ba. Nếu bạn thiết lập là FALSE thì CodeIgniter sẽ không bảo vệ các trường hay bảng của bạn.

$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);

$this->db->or_where()

Hàm này dùng để thiết lập đa điều kiện theo OR:

$this->db->where('name !=', $name);
$this->db->or_where('id >', $id);  // Sẽ tạo ra: WHERE name != 'Joe' OR id > 50

$this->db->where_in()

Hàm này dùng thể thiết lập điều kiện sử dụng mệnh đề IN().

$names = array('Frank', 'Todd', 'James');
$this->db->where_in('username', $names);
// Sẽ tạo ra: WHERE username IN ('Frank', 'Todd', 'James')

$this->db->or_where_in()

Hàm này dùng để kết hợp đa điều kiện OR với mệnh đề IN():

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_in('username', $names);
// Sẽ tạo ra: OR username IN ('Frank', 'Todd', 'James')

$this->db->where_not_in()

Hàm này sẽ tạo ra điều kiện kết hợp với mệnh đề NOT IN():

$names = array('Frank', 'Todd', 'James');
$this->db->where_not_in('username', $names);
// Sẽ tạo ra: WHERE username NOT IN ('Frank', 'Todd', 'James')

$this->db->or_where_not_in()

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_not_in('username', $names);
// Sẽ tạo ra: OR username NOT IN ('Frank', 'Todd', 'James')

Các hàm tìm kiếm dữ liệu tương tự

$this->db->like()

Phương thức này cho phép sử dụng mệnh đề LIKE trong điều kiện, nó rất hữu dụng để tìm kiếm.

1. key/value đơn giản:

$this->db->like('title', 'match');
// Tạo ra: WHERE `title` LIKE '%match%' ESCAPE '!'

Ta có quyền sử dụng cùng lúc nhiều lần phương thức này, khi đó đa kiều kiện sẽ là AND:

$this->db->like('title', 'match');
$this->db->like('body', 'match');
// Sẽ tạo ra: WHERE `title` LIKE '%match%' ESCAPE '!' AND  `body` LIKE '%match% ESCAPE '!'

Ta có thể điều khiển vị trí của ký hiệu (%) bằng cách sử dụng đối số thứ ba với các lựa chọn là 'before', 'after' và 'both', trong đó mặc định là 'both'.

$this->db->like('title', 'match', 'before'); // Sẽ tạo ra: WHERE `title` LIKE '%match' ESCAPE '!'
$this->db->like('title', 'match', 'after');  // Sẽ tạo ra: WHERE `title` LIKE 'match%' ESCAPE '!'
$this->db->like('title', 'match', 'both');   // Sẽ tạo ra: WHERE `title` LIKE '%match%' ESCAPE '!'

2. Sử dụng mảng kết hợp:

$array = array('title' => $match, 'page1' => $match, 'page2' => $match);
$this->db->like($array);
// Tương ứng: WHERE `title` LIKE '%match%' ESCAPE '!' AND  `page1` LIKE '%match%' ESCAPE '!' AND  `page2` LIKE '%match%' ESCAPE '!'

$this->db->or_like()

Phương thức này kết hợp đa kiều kiện mệnh đề LIKE với OR:

$this->db->like('title', 'match'); $this->db->or_like('body', $match);
// Tương tự: WHERE `title` LIKE '%match%' ESCAPE '!' OR  `body` LIKE '%match%' ESCAPE '!

$this->db->not_like()

$this->db->not_like('title', 'match');
// Tương tự: WHERE `title` NOT LIKE '%match% ESCAPE '!'

$this->db->or_not_like()

$this->db->like('title', 'match');
$this->db->or_not_like('body', 'match');
// Sẽ tạo ra: WHERE `title` LIKE '%match% OR  `body` NOT LIKE '%match%' ESCAPE '!'

$this->db->group_by()

Phương thức này tương ứng với việc sử dụng mệnh đề GROUP BY:

$this->db->group_by("title"); // Sẽ tạo ra: GROUP BY title

Ta cũng có thể truyền đối số dạng mảng như sau:

$this->db->group_by(array("title", "date"));
// Sẽ tạo ra: GROUP BY title, dat

$this->db->distinct()

Phương thức này thêm từ khóa "DISTINCT" vào truy vấn:

$this->db->distinct();
$this->db->get('table');
// Sẽ tạo ra: SELECT DISTINCT * FROM table

$this->db->having()

Phương thức này tương ứng với việc sử dụng mệnh đề HAVING trong truy vấn. Ta có thể viết theo hai cách như sau:

$this->db->having('user_id = 45');  // Tương ứng: HAVING user_id = 45
$this->db->having('user_id'45);  // Tương ứng: HAVING user_id = 45

Ta cũng có thể sử dụng mảng trong đối số như sau:

$this->db->having(array('title =' => 'My Title', 'id <' => $id));
// Sẽ tạo ra: HAVING title = 'My Title', id < 45

Bạn có thể thiết lập câu truy vấn chuẩn bằng cách sử dụng đối số thứ 3 và thiết lập là FALSE.

$this->db->having('user_id',  45);  // Sẽ tạo ra: HAVING `user_id` = 45 ; MySQL thường là thế này
$this->db->having('user_id',  45, FALSE);  // Sẽ tạo ra: HAVING user_id = 45

$this->db->or_having()

Tương tự như hàm having(), chỉ khác là các điều kiện phân cách nhau bằng đa điều kiện OR.

Các hàm sắp xếp kết quả

$this->db->order_by()

Hàm này dùng để thay thế mệnh đề ORDER BY.

Tham số thứ nhất chưa tên của cột bạn muốn sắp xếp, tham số thứ hai dùng để thiết lập hướng sắp xếp, có 3 hướng là ASC, DESC và RANDOM.

$this->db->order_by('title', 'DESC');
// Sẽ tạo ra: ORDER BY `title` DESC

Ta cũng có thể truyền đối số dưới dạng chuỗi cho tham số thứ nhất.

$this->db->order_by('title DESC, name ASC');
// Sẽ tạo ra: ORDER BY `title` DESC, `name` ASC

Ta cũng được quyền sử dụng hàm này nhiều lần như sau:

$this->db->order_by('title', 'DESC');
$this->db->order_by('name', 'ASC');
// Sẽ tạo ra: ORDER BY `title` DESC, `name` ASC

Nếu ta chọn sắp xếp RANDOM thì tham số thứ nhất sẽ bị bỏ qua, trừ trường hợp nó là một số.

$this->db->order_by('title', 'RANDOM');
// Tương đương: ORDER BY RAND()

$this->db->order_by(42, 'RANDOM');
// Tương đương: ORDER BY RAND(42)

 

Chú ý
Sắp xếp Random hiện tại không được Oracle hỗ trợ, nó sẽ thay thế bằng mặc định ASC.

Các hàm giới hạn số lượng trong kết quả

$this->db->limit()

Hàm này sẽ tương ứng với hàm limit() của MySQL:

$this->db->limit(10);  // Tương ứng: LIMIT 10

Tham số thứ hai chính là vị trí bắt đầu lấy số bản ghi.

$this->db->limit(10, 20); // Sẽ tạo ra: LIMIT 20, 10

$this->db->count_all_results()

Hàm này dùng để đếm số bản ghi có được từ câu lệnh truy vấn, trong đó nó chấp nhận những hàm như where(), or_where(), like()or_like(), ... Ví dụ:

echo $this->db->count_all_results('my_table');  // In ra số lượng bản ghi từ câu lệnh truy vấn với bảng my_table
$this->db->like('title', 'match');
$this->db->from('my_table');
echo $this->db->count_all_results(); // In ra số lượng bản ghi sau khi áp dụng hàm like() để tìm bản ghi

Lưu ý là phương thức này cũng có thể được dùng để thiết lập lại giá trị nào bạn đã truyền cho hàm select(). Vậy nên, nếu bạn không muốn thay đổi giá trị thì bạn truyền FALSE ở đối số thứ hai của hàm:

echo $this->db->count_all_results('my_table', FALSE);

$this->db->count_all()

Hàm này sẽ đếm số bản ghi trong một bảng cụ thể. Ví dụ:

echo $this->db->count_all('my_table');  // Trả về tất cả các bản ghi của bảng my_table

Các hàm tạo nhóm điều kiện truy vấn

Nhóm truy vấn cho phép ta tạo các nhóm điều kiện trong mệnh đề WHERE. Điều này sẽ cho phép ta tạo các câu lệnh truy vấn với những điều kiện phức tạp. Ví dụ:

$this->db->select('*')->from('my_table')
        ->group_start()
                ->where('a', 'a')
                ->or_group_start()
                        ->where('b', 'b')
                        ->where('c', 'c')
                ->group_end()
        ->group_end()
        ->where('d', 'd')
->get();

// Sẽ tạo ra:
// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'

 

Lưu ý
Mỗi nhóm cần phải một cặp group_start() và group_end().

$this->db->group_start()

Bắt đầu một nhóm mới, hàm này tương ứng với dấu mở ngoặc tròn ở mệnh đề WHERE của câu truy vấn (xem ví dụ trên).

$this->db->or_group_start()

Bắt đầu một nhóm mới, tương ứng với dấu mở ngoặc tròn và ở phía trước nó là 'OR' (xem ví dụ trên).

$this->db->not_group_start()

Bắt đầu một nhóm mới, tương ứng với dấu mở ngoặc tròn và ở phía trước nó là 'NOT'.

$this->db->or_not_group_start()

Bắt đầu một nhóm mới, tương ứng với dấu mở ngoặc tròn và ở phía trước nó là 'OR NOT'.

$this->db->group_end()

Kết thúc nhóm hiện thời, tương ứng với dấu đóng ngoặc tròn ở mệnh đề WHERE của câu truy vấn.

Các hàm chèn dữ liệu

$this->db->insert()

Hàm này tương ứng với câu lệnh INSERT dựa trên dữ liệu mà ta cung cấp để thực hiện câu truy vấn. Ta cũng có thể truyền một mảng hoặc một đối tượng tới hàm. Dưới đây là một ví dụ sử dụng mảng:

$data = array(
        'title' => 'My title',
        'name' => 'My Name',
        'date' => 'My date'
);

$this->db->insert('mytable', $data);
// Sẽ tạo ra:
INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

Tham số đầu tiên của hàm sẽ chứa tên bảng, tham số thứ hai là một mảng kết hợp các giá trị muốn insert.

Còn đây là một ví dụ sử dụng đối tượng:

/*
class Myclass {
        public $title = 'My Title';
        public $content = 'My Content';
        public $date = 'My Date';
}
*/

$object = new Myclass;
$this->db->insert('mytable', $object);
// Sẽ tạo ra:
INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')

Tham số đầu tiên chứa tên bảng, tham số thứ hai là một đối tượng.

Lưu ý
Tất cả các giá trị đều được tự động thêm những yếu tố để tạo lên câu lệnh truy vấn an toàn.

$this->db->get_compiled_insert()

Biên dịch câu truy vấn insert thành dạng $this->db->insert() nhưng không thực thi, mà trả về một chuỗi chứa câu lệnh truy vấn.

Ví dụ:

$data = array(
        'title' => 'My title',
        'name'  => 'My Name',
        'date'  => 'My date'
);

$sql = $this->db->set($data)->get_compiled_insert('mytable');
echo $sql;

// Sẽ tao ra chuỗi:
"INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date')"

Tham số thứ hai của hàm cho phép ta thiết lập việc có hay không reset lại câu truy vấn, mặc định là có (TRUE):

echo $this->db->set('title', 'My Title')->get_compiled_insert('mytable', FALSE);

// Sẽ tạo ra chuỗi:
"INSERT INTO mytable (`title`) VALUES ('My Title')"

echo $this->db->set('content', 'My Content')->get_compiled_insert();

// Sẽ tạo ra chuỗi:
"INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content')"

Một chú ý quan trọng đối với ví dụ trên là câu truy vấn thứ hai không được dùng hàm $this->db->from() và cũng không được truyền bảng ở tham số thứ nhất. Lý do là bởi hàm này trả về chuỗi truy vấn chứ không thực thi câu truy vấn giống như hàm $this->db->insert() (hàm này có thể thiết lập lại các giá trị hoặc thiết lập lại trực tiếp bằng hàm $this->db->reset_query()).

Lưu ý
Phương thức này không sử dụng với việc insert nhiều lần hoặc một lô (batch) insert.

$this->db->insert_batch()

Hàm này sẽ tạo ra một chuỗi lệnh truy vấn dựa trên dữ liệu của bạn, và sau đó thực hiện truy vấn đấy. Ta có thể truyền một mảng hoặc một đối tượng tới hàm. Dưới đây là ví dụ sử dụng mảng:

$data = array(
        array(
                'title' => 'My title',
                'name' => 'My Name',
                'date' => 'My date'
        ),
        array(
                'title' => 'Another title',
                'name' => 'Another Name',
                'date' => 'Another date'
        )
);

$this->db->insert_batch('mytable', $data);
// Sẽ tạo ra:
INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'),  ('Another title', 'Another name', 'Another date')

Tham số đầu tiên là tên bảng, tham số thứ hai là mảng kết hợp các giá trị.

Lưu ý
Tất cả các giá trị insert đều được bảo đảm để tạo câu lệnh truy vấn an toàn.

Các hàm cập nhật dữ liệu

$this->db->replace()

Phương thức này sẽ thực hiện câu lệnh REPLACE, câu lệnh này dựa trên chuẩn SQL đối với cặp câu lệnh (tùy chọn) DELETE + INSERT, trong đó sử dụng các ràng buộc PRIMARY và UNIQUE để xác định thành phần. Mục đích của hàm là để giúp ta tiết kiệm trong việc thực hiện các logic phức tạp với những sự kết hợp khác nhau của các lời gọi tới các hàm select()update()delete() và insert().

Ví dụ:

$data = array(
        'title' => 'My title',
        'name'  => 'My Name',
        'date'  => 'My date'
);

$this->db->replace('table', $data);

// Sẽ thực hiện:
REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

Ở ví dụ trên, nếu ta giả sử rằng trường title là khóa chính (PK) thì nếu một hàng nào đó chứa tiêu đề là 'My title' thì hàng đó sẽ bị xóa và thay thế bằng một hàng mới.

Bạn cũng được quyền sử dụng phương thức set() cho phương thức này, khi đó tất cả các trường sẽ được tự động đảm bảo an toàn giống như phương thức insert().

$this->db->set()

Hàm này có nhiệm vụ thiết lập các giá trị để thực hiện các thao tác insert và update.

Hàm này cũng có thể được sử dụng để thay thế cho việc truyền mảng dữ liệu trực tiếp tới các hàm insert hoặc update:

$this->db->set('name', $name);
$this->db->insert('mytable');
// Produces:
INSERT INTO mytable (`name`) VALUES ('{$name}')

Nếu bạn sử dụng nhiều lời gọi hàm thì chúng sẽ được ghép theo đúng cách dựa trên trên thao tác bạn muốn làm là insert hay update:

$this->db->set('name', $name);
$this->db->set('title', $title);
$this->db->set('status', $status);
$this->db->insert('mytable');

set() cũng có một tham số nữa (tham số tùy chọn) là tham số thứ 3 ($escape), tham số này sẽ ngăn cản dữ liệu không cho đảm bảo an toàn nếu đặt giá trị là FALSE. Để minh họa điều này, ví dụ dưới đây hàm set() với việc sử dụng và không sử dụng tham số thứ 3.

$this->db->set('field', 'field+1', FALSE);
$this->db->where('id', 2);
$this->db->update('mytable');
// cho ra:
UPDATE mytable SET field = field+1 WHERE id = 2

$this->db->set('field', 'field+1');
$this->db->where('id', 2);
$this->db->update('mytable');
// cho ra:
UPDATE `mytable` SET `field` = 'field+1' WHERE `id` = 2

Bạn cũng có thể truyền một mảng kết hợp tới hàm này như sau:

$array = array(
        'name' => $name,
        'title' => $title,
        'status' => $status
);

$this->db->set($array);
$this->db->insert('mytable');

Hoặc truyền một đối tượng như sau:

/*
class Myclass {
        public $title = 'My Title';
        public $content = 'My Content';
        public $date = 'My Date';
}
*/

$object = new Myclass;
$this->db->set($object);
$this->db->insert('mytable');

$this->db->update()

Hàm này tạo một chuỗi update và thực hiện truy vấn dựa trên dữ liệu đầu vào. Ta có thể truyền một mảng hoặc một đối tượng tới ham này. Dưới đây là ví dụ truyền mảng:

$data = array(
        'title' => $title,
        'name' => $name,
        'date' => $date
);

$this->db->where('id', $id);
$this->db->update('mytable', $data);
// Sẽ tạo ra:
UPDATE mytable SET title = '{$title}', name = '{$name}', date = '{$date}' WHERE id = $id

Còn đây là ví dụ truyền đối tượng:

/*
class Myclass {
        public $title = 'My Title';
        public $content = 'My Content';
        public $date = 'My Date';
}
*/

$object = new Myclass;
$this->db->where('id', $id);
$this->db->update('mytable', $object);
// Sẽ tạo ra:
UPDATE `mytable` SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' WHERE id = `$id

Từ ví dụ trên bạn thấy rằng ta có thể sử dụng hàm $this->db->where() đi kèm với hàm update() để có thể thiết lập điều kiện update. Ta cũng có thể tùy chọn truyền thông tin trực tiếp tới hàm update dưới dạng chuỗi như sau:

$this->db->update('mytable', $data, "id = 4");

Hoặc dưới dạng mảng như sau:

$this->db->update('mytable', $data, array('id' => $id));

Ngoài ra, ta cũng có thể sử dụng hàm $this->db->set() để thực hiện update.

$this->db->update_batch()

Hàm này sẽ tạo một chuỗi update dựa trên dữ liệu đầu vào thực hiện truy vấn tương ứng. Ta cũng có thể truyền dữ liệu dạng mảng hoặc dạng đối tượng tới hàm. Ví dụ dưới đây là truyền dạng mảng:

$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name 2' ,
      'date' => 'My date 2'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name 2' ,
      'date' => 'Another date 2'
   )
);

$this->db->update_batch('mytable', $data, 'title');

// Sẽ tạo ra:
// UPDATE `mytable` SET `name` = CASE
// WHEN `title` = 'My title' THEN 'My Name 2'
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// ELSE `name` END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date` END
// WHERE `title` IN ('My title','Another title')

Tham số đầu tiên của hàm sẽ chứa tên bảng, tham số thứ hai là mảng các giá trị, còn tham số thứ ba liên quan đến mệnh đề where.

Lưu ý
Hàm affected_rows() sẽ không cho ta kết quả phù hợp với phương thức này do bản chất của cách thức hoạt động của nó, thay vào đó ta nên dùng hàm update_batch().

$this->db->get_compiled_update()

Hàm này làm việc chuẩn xác tương tự như hàm $this->db->get_compiled_insert() ngoại trừ việc nó tạo ra một chuỗi truy vấn UPDATE thay vì chuỗi truy vấn INSERT.

Các bạn xem lại về hàm $this->db->get_compiled_insert() để hiểu rõ hơn về hàm này.

Lưu ý
Hàm này không làm việc với lô lệnh update.

Các hàm xóa dữ liệu

$this->db->delete()

Hàm này tạo một câu lệnh DELETE và thực thi nó.

$this->db->delete('mytable', array('id' => $id));
// sẽ tạo ra:
DELETE FROM mytable WHERE id = $id

Tham số đầu tiên là tên bảng, tham số thứ hai là mệnh đề where. Ta cũng có thể sử dụng hàm where() hoặc or_where() để truyền dữ liệu cho tham số thứ hai như sau:

$this->db->where('id', $id);
$this->db->delete('mytable');

// Sẽ tạo ra:
DELETE FROM mytable WHERE id = $id

Ta cũng có thể truyền một mảng gồm tên của các bảng tới hàm delete() nếu ta muốn xóa nhiều bảng cùng lúc.

$tables = array('table1', 'table2', 'table3');
$this->db->where('id', '5');
$this->db->delete($tables);

Nếu ta muốn xóa tất cả dữ liệu của một bảng thì  ta có thể sử dụng hàm truncate() hoặc empty_table().

$this->db->empty_table()

Hàm này cũng tạo câu lệnh delete và thực thực thi nó như hàm trên, nhưng đơn giản hơn ở chỗ nó không có đối số thứ hai, tức không có mệnh đề where:

$this->db->empty_table('mytable'); // Sẽ tạo ra: DELETE FROM mytable

$this->db->truncate()

Hàm này tạo câu lệnh truncate và thực thi nó:

$this->db->from('mytable');
$this->db->truncate();

// hoặc

$this->db->truncate('mytable');

// sẽ tạo ra:
TRUNCATE mytable

 

Lưu ý
Nếu câu lệnh TRUNCATE không thực thi được thì truncate() sẽ được thực thi theo dạng "DELETE FROM table".

$this->db->get_compiled_delete()

Hàm này làm việc chuẩn xác như hàm $this->db->get_compiled_insert() ngoại trừ việc nó tạo câu lệnh DELETE mà không phải câu lệnh INSERT.

Bạn xem thêm thông tin chi tiết ở hàm $this->db->get_compiled_insert().

Chuỗi phương thức

Chuỗi phương thức cho phép ta đơn giản hóa cú pháp bằng cách kết nối nhiều hàm. Ví dụ:

$query = $this->db->select('title')
                ->where('id', $id)
                ->limit(10, 20)
                ->get('mytable');

Bộ nhớ đệm Query Builder

Khi không tiến hành đệm (caching) thì Query Builder cho phép ta lưu trữ các phần nhất định của các truy vấn để có thể tái sử dụng tại vị trí sau đó khi thực hiện script. Thông thường thì khi Query Builder được gọi hoàn chỉnh thì tất cả các thông tin đã lưu trữ sẽ đượt thiết lập lại (reset) cho lời gọi kế tiếp. Còn khi tiến hành đệm cho Query Builder thì ta có thể ngăn cản việc thiết lập lại cũng như tái sử dụng thông tin một cách dễ dàng.

Những lời gọi đã được đệm là những lời gọi được tích lũy. Nếu ta thực hiện hai lời gọi tới hàm select() đã được đệm và hai lời gọi tới hàm select() không được đệm thì kết quả là ta đã tiến hành bốn lời gọi tới hàm select(). Có ba hàm đệm có thể sử dụng như sau:

$this->db->start_cache()

Hàm này phải được gọi ngay khi bắt đầu đệm. Tất cả các truy vấn Query Builder đúng chuẩn đều sẽ được lưu để sử dụng

$this->db->stop_cache()

Hàm này có thể được gọi để dừng đệm.

$this->db->flush_cache()

Hàm này sẽ xóa tất cả các những gì được lưu trong bộ đệm Query Builder.

Ví dụ về việc sử dụng bộ nhớ đệm

Dưới đây là một ví dụ cơ bản về việc sử dụng bộ đệm cho Query Builder:

$this->db->start_cache();
$this->db->select('field1');
$this->db->stop_cache();
$this->db->get('tablename');
// Sẽ tạo ra:
SELECT `field1` FROM (`tablename`)

$this->db->select('field2');
$this->db->get('tablename');
// Sẽ tạo ra:
SELECT `field1`, `field2` FROM (`tablename`)

$this->db->flush_cache();
$this->db->select('field2');
$this->db->get('tablename');
// Sẽ tạo ra:
SELECT `field2` FROM (`tablename`)

 

Lưu ý
Các câu lệnh trên có thể được đệm như sau: select, from, join, where, like, group_by, having, order_by

Thiết lập lại Query Builder

$this->db->reset_query()

Hàm này cho phép thiết lập lại (resetting) Query Builder giúp bạn có thể làm mới truy vấn mà không cần phải thực thi nó trước thông qua việc sử dụng phương thức như $this->db->get() hay $this->db->insert().

Việc thiết lập lại Query Builder rất hữu dụng trong trường hợp bạn sử dụng nó để tạo truy vấn (ví dụ như $this->db->get_compiled_select()) rồi sau đó thực thi truy vấn đó. Ví dụ:

// Lưu ý rằng tham số thứ hai của phương thức get_compiled_select được đặt là FALSE
$sql = $this->db->select(array('field1','field2'))
                                ->where('field3',5)
                                ->get_compiled_select('mytable', FALSE);

// ...
// Thực hiện điều gì đó mới câu lệnh SQL
// ...

$data = $this->db->get()->result_array();

// Sẽ thực thi và trả về một mảng các kết quả của truy vấn sau:
// SELECT field1, field1 from mytable where field3 = 5;

 

Lưu ý
Hai lời gọi tới get_compiled_select() trong khi ta đang sử dụng chức năng đệm Query Builder và không thiết lập lại các truy vấn thì kết quả là có tới hai lần đệm.

Nguồn: https://codeigniter.com/user_guide/database/query_builder.html