NTM Solutions

Facebook Youtube Google+

Thứ Ba, 20 tháng 11, 2018

Tự học CodeIgniter-Bài 02-Controllers

#hoccodeigniter


Controllers là “trái tim” trong ứng dụng web của bạn, vì chúng quyết định cách xử lý các yêu cầu HTTP.
Nội dung bài viết:
  • Controller là gì?
  • Thử tạo controller: Xin chào!
  • Các phương thức
  • Phân đoạn URI truyền tham số vào phương thức
  • Sửa Controller mặc định
  • Gọi phương thức Remap
  • Xuất dữ liệu
  • Phương thức ẩn
  • Sắp xếp các Controllers vào thư mục con
  • Khởi tạo lớp
  • Tên các phương thức tạo sẵn

Ghi chú: nếu các bạn chạy ứng dụng web cài đặt trên localhost-> thay thế tất cả đường dẫn example.com -> http://localhost/thư_mục_CI


01 Controller đơn giản là 01 tập tin chứa lớp có tên trùng với 01 URI.
Hãy xem URI này:
example.com/index.php/blog/

Trong ví dụ trên, CodeIgniter sẽ cố tìm 01 tập tin chứa controller tên là Blog.php và tải nó.
Khi 01 controller có tên trùng với đoạn đầu của 01 URI, nó sẽ được tải.

Ta hãy tạo 01 controller đơn giản để xem cách nó hoạt động. Tạo 01 tập tin tên là Blog.php, và paste đoạn mã này vào:
<?php

class Blog extends CI_Controller {



        public function index()

        {

                echo 'Xin chào!';

        }

}

Sau đó lưu tập tin vào thư mục application/controllers/
Điều quan trọng 01:
Phải viết hoa chữ đầu tiên trong tên tập tin ‘Blog.php’.
Bây giờ bạn thử truy cập vào đường dẫn URL có dạng như vậy:
example.com/index.php/blog/

Nếu làm đúng, bạn sẽ thấy dòng chữ sau xuất hiện:
Xin chào!
Điều quan trọng 02:
Tên lớp phải bắt đầu bằng chữ cái in Hoa.
Như thế này là hợp lệ:
<?php

class Blog extends CI_Controller {

}

Như vầy là không hợp lệ:
<?php

class blog extends CI_Controller {

}

Bạn phải luôn đảm bảo khai báo controller của bạn thừa kế từ lớp controller cha của CI -> thừa hưởng tất cả phương thức của lớp cha.


Trong ví dụ trên, tên phương thức là index(). Phương thức “index” luôn được tải mặc định nếu đoạn thứ 2 trong URI rỗng. Bạn cũng có thể hiện dòng chữ “Xin chào” bằng cách truy cập đường dẫn như thế này:
example.com/index.php/blog/index/

Như vậy, đoạn thứ 2 của URI quyết định phương thức nào trong controller được gọi.
Ta hãy thử thêm 01 phương thức mới vào controller Blog khi nãy:
<?php

class Blog extends CI_Controller {

        public function index()

        {
                echo 'Xin chào!';
        }

        public function comments()
        {
                echo 'Nhìn vào đây!';
        }
}

Bây giờ bạn thử truy cập URL sau để thấy phương thức comment:
example.com/index.php/blog/comments/

Nếu thấy dòng chữ “Nhìn vào đây!” ->bạn đã thành công.

Nếu liên kết URI của bạn chứa hơn 02 phân đoạn chúng sẽ được truyền vào phương thức của bạn như là các tham số.
Ví dụ ta có URI như vầy:
example.com/index.php/products/shoes/sandals/123

Phương thức của bạn sẽ được truyền tham số là đoạn URI 3 và 4 (“sandals” và “123”):

<?php

class Products extends CI_Controller {


        public function shoes($sandals, $id)

        {
                echo $sandals;

                echo $id;
        }

}

Điều quan trọng:
Nếu bạn dùng tính năng URI Routing, các phân đoạn truyền vào phương thức của bạn sẽ được định tuyến lại ngắn hơn.

Sửa Controller mặc định

CodeIgniter có thể chỉ định tải 01 controller mặc định khi phần liên kết URI không tồn tại (vị trí thư mục gốc). Ta có thể sửa controller tải mặc định -> sửa tập tin application/config/routes.php và thiết lập biến sau:
$route['default_controller'] = 'blog';

Chữ ‘blog’ là tên của lớp controller mà bạn muốn dùng mặc định. Bây giờ nếu bạn gõ index.php mà không có bất kỳ đoạn URI phía sau bạn sẽ thấy dòng chữ “Xin chào” mặc định.
->Nếu ta chỉ gõ thư mục gốc chứa CI cũng ra kết quả tương tự:
http://localhost/thư_mục_chứa_CI
Để biết thêm thông tin, các bạn vào phần “Các đường dẫn đặt sẵn-Reserved Routes” trong bài viết URI Routing

Như đã nói ở trên, phân đoạn thứ 02 của URI thông thường sẽ định phương thức trong  controller được gọi. CodeIgniter cho phép bạn sửa lại hành vi này bằng cách dùng phương thức _remap()

public function _remap()

{
        // Đặt mã ở đây...
}

Điều quan trọng:
Nếu controller của bạn chứa 01 phương thức có tên là _remap(), nó sẽ luôn được gọi bất kể  URI có chứa cái gì. Nó viết đè lên hành vi gọi phương thức định trong URI, cho phép bạn xác định phương thức riêng sẽ chạy theo đường liên kết tùy biến của bạn.

Việc gọi phương thức chồng (thay vì phân đoạn thứ 02 của URI) sẽ truyền tham số vào phương thức _remap()
public function _remap($method)

{

        if ($method === 'method_nào_đó')

        {
                $this->$method();
        }

        else
        {
                $this->method_mặc_định();
        }

}

Ví dụ: nếu truyền tham số sau controller không trùng với tên phương thức comments->chuyển đến gọi phương thức mặc định là index
Như vậy, muốn chế “cái đuôi” URI phía sau controller-> tạo 01 phương thức trùng tên cái đuôi đó và gọi nó trong _remap($method)
public function _remap($method)

{
        if ($method === 'comments')
        {
                $this->$method();
        }

        else

        {
                $this->index();
        }

}

Bất kỳ đoạn nào thêm vào sau tên phương thức sẽ được truyền vào _remap() như tham số phụ thứ 02 tùy chọn. Mảng này có thể được dùng kết hợp với hàm call_user_func_array() để giả lập các hành vi mặc định của CodeIgniter.
Ví dụ:
public function _remap($method, $params = array())

{

        $method = 'process_'.$method;

        if (method_exists($this, $method))

        {
                return call_user_func_array(array($this, $method), $params);

        }
        show_404();
}


CodeIgniter có 01 lớp xuất dữ liệu đảm nhận việc tự động gửi dữ liệu sau cùng đến trình duyệt. Để biết thêm thông tin các bạn có thể tìm đọc trong mục ViewsOutput Class. Tuy vậy trong 01 vài trường hợp, bạn có thể muốn tự mình gửi các dữ liệu đăng lên đến trình duyệt. CodeIgniter cho phép bạn thêm 01 phương thức tên là _output() vào controller của bạn để nhận dữ liệu xuất ra sau cùng.
Điều quan trọng
Nếu controller của bạn chứa 01 phương thức tên là _output(), nó sẽ luôn được gọi bởi lớp xuất dữ liệu thay vì echo thẳng dữ liệu ra. Tham số đầu tiên của phương thức sẽ chứa dữ liệu xuất sau cùng.
Ví dụ:
public function _output($output)
{
        echo $output;

}
Ghi chú:
Hãy chú ý rằng phương thức _output() của bạn sẽ nhận dữ liệu  trong trạng thái cuối cùng của nó. Benchmark và dữ liệu sử dụng bộ nhớ sẽ được rendered, các tập tin cache sẽ được ghi (nếu bạn có kích hoạt caching), và các headers sẽ được gửi đi (nếu bạn dùng tính năng đó) trước khi phương thức _output() xử lý nó. Để đảm bảo phần xuất dữ liệu trong controller của bạn cached chính xác, trong phương thức _output() có thể dùng như sau:
if ($this->output->cache_expiration > 0)

{

        $this->output->_write_cache($output);

}
Nếu bạn đang dùng tính năng này thời gian xử lý trang và trạng thái sử dụng bộ nhớ có thể không chính xác vì since they will not take into account any further processing you do. Ta có thể điều khiển xuất dữ liệu theo cách khác trước khi bất kỳ tiến trình cuối cùng nào hoàn tất, vui lòng xem thêm các phương thức có sẵn trong Output Library.

Trong 01 vài trường hợp bạn có thể muốn phương thức của mình ẩn đi khỏi sự truy cập từ bên ngoài (ví dụ trang login chẳng hạn). Để làm được điều này, đơn giản ta chỉ việc khai báo phương thức là private hoặc protected và nó sẽ không thể truy cập thông qua yêu cầu URL. Ví dụ như bạn có 01 phương thức như vầy:
private function _utility()

{
        // đoạn mã
}

Nếu ta cố truy cập bằng URL sẽ không được.
example.com/index.php/blog/_utility/

Chú ý:
Dấu gạch dưới trong _tenphuongthuc cũng có thể ngăn nó không bị gọi.

Nếu bạn đang xây dựng 01 ứng dụng lớn bạn có thể cần phải lập 01 cấu trúc chứa các controller trong các thư mục con. CodeIgniter cho phép ta làm điều này.
Đơn giản ta chỉ việc tạo các thư mục con nằm trong thư mục chính application/controllers/ và đặt các lớp controller ở bên trong.
Ghi chú:
Khi sử dụng tính năng này phân đoạn thứ 01 trong URI sẽ là tên thư mục. Ví dụ ta có 01  controller lưu ở đây:
application/controllers/products/Shoes.php

Để gọi controller trên liên kế URI sẽ trông giống như vầy:
example.com/index.php/products/shoes/show/123

Mỗi thư mục con có thể chứa 01 controller mặc định sẽ được gọi nếu URL chỉ chứa tên thư mục con. Để làm điều này ta  chỉ việc đặt trùng tên với mục ‘default_controller’ ở trong tập tin application/config/routes.php
CodeIgniter cũng cho phép bạn thiết lập lại liên kết URIs bằng cách dùng tính năng URI Routing

Nếu bạn muốn dùng 01 hàm khởi tạo trong bất kỳ Controllers nào của mình, nhất định bạn PHẢI đặt dòng mã này bên trong hàm đó:
parent::__construct();

Lí do cần phải có dòng mã này là vì hàm khởi tạo của bạn sẽ chép đè lên 01 phương thức trong lớp controller cha vì lẽ đó ta phải gọi nó ra.
Ví dụ:
<?php

class Blog extends CI_Controller {

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

                // Mã khởi tạo của bạn
        }
}

Hàm khởi tạo hữu dụng khi bạn cần thiết lập 01 vài giá trị mặc định, hoặc chạy 01 tiến trình mặc định khi lớp của bạn khởi tạo. Hàm khởi tạo không thể trả về 01 giá trị, nhưng có thể thực hiện 01 hành động mặc định nào đó.

Bởi vì các lớp controller của bạn sẽ mở rộng controller của ứng dụng chính ->bạn phải cẩn thận tránh đặt trùng tên các phương thức khác đã có trong lớp , bằng không các hàm mới của bạn sẽ ghi đè lên các hàm này. Xem mục Reserved Names để có toàn bộ danh sách các hàm có sẵn trong Code Igniter.
Điều quan trọng:
Bạn cũng không nên đặt tên phương thức trùng với tên lớp của nó.
Ví dụ: khai báo phương thức index trong lớp Index.
Vì nếu làm như vậy mà không khái báo 01 phương thức __construct() trong cùng lớp, điều đó có nghĩa là ví dụ như phương thức Index::index() sẽ thực thi việc khởi tạo lớp! Đây là 01 tính năng trong PHP4.
+Các tập tin tạo mới trong bài viết này:
  • application/controllers/Blog.php
  • application/controllers/Products.php
  • application/controllers/products/Shoes.php

+Các tập tin đã sửa trong bài viết này:
·         application/config/routes.php
Nếu vẫn chưa rõ các bạn xem thêm video clip sau:


By #tiensim

Nguồn: User Guide – General Topics