CODEIGNITER TUTORIALS
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Tìm hiểu quy trình load model trong codeigniter

Việc load model rất quen thuộc với những bạn sử dụng framwork codeigniter nhưng đôi lúc ta lại tò mò không biết quá trình nó load như thế nào, bài này tôi và các bạn sẽ tìm hiểu quy trình load model như thế nào nhé.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Function load model codeigniter nằm ở đâu?

Đây là câu hỏi đầu tiên để tìm hiểu một chức năng, đối tượng trong một framwork nào đó, và cách đơn giản nhất các bạn hãy dùng chương trình search project của các editor, ở đây tui dùng netbeans để search và tôi đã tìm ra nó nằm trong file system/core/Loader.php. Các bạn mở file này lên và tìm tới dòng 232 sẽ có một function load model như sau:

public function model($model, $name = '', $db_conn = FALSE)
	{
		if (is_array($model))
		{
			foreach ($model as $babe)
			{
				$this->model($babe);
			}
			return;
		}

		if ($model == '')
		{
			return;
		}

		$path = '';

		// Is the model in a sub-folder? If so, parse out the filename and path.
		if (($last_slash = strrpos($model, '/')) !== FALSE)
		{
			// The path is in front of the last slash
			$path = substr($model, 0, $last_slash + 1);

			// And the model name behind it
			$model = substr($model, $last_slash + 1);
		}

		if ($name == '')
		{
			$name = $model;
		}

		if (in_array($name, $this->_ci_models, TRUE))
		{
			return;
		}

		$CI =& get_instance();
		if (isset($CI->$name))
		{
			show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
		}

		$model = strtolower($model);

		foreach ($this->_ci_model_paths as $mod_path)
		{
			if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
			{
				continue;
			}

			if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
			{
				if ($db_conn === TRUE)
				{
					$db_conn = '';
				}

				$CI->load->database($db_conn, FALSE, TRUE);
			}

			if ( ! class_exists('CI_Model'))
			{
				load_class('Model', 'core');
			}

			require_once($mod_path.'models/'.$path.$model.'.php');

			$model = ucfirst($model);

			$CI->$name = new $model();

			$this->_ci_models[] = $name;
			return;
		}

		// couldn't find the model
		show_error('Unable to locate the model you have specified: '.$model);
	}

Nhìn hơi căng nhỉ, bây giờ ta sẽ mổ xẻ nó nhé

Bài viết này được đăng tại [free tuts .net]

Mổ xẻ function load model trong codeigniter

tham số truyền vào

Trong function load model có 3 tham số truyền vào gồm $model, $name, $db_conn, trong đó:

  • $model là tên model cần load, có thể truyền vào một mảng danh sách các model cần load nhưng trường hợp này tham số $name sẽ không có tác dụng.
  • $name là tên alias mà bạn muốn sau khi load model nó sẽ gán vào instance của Codeigniter
  • $db_conn là tên database mà bạn khai báo ở file application/config/database.php, mặc định là defaul

code xử lý bên trong hàm

Ta có quy trình xử lý gọi model trong codeigniter như sau:

Đoạn 1:

// Nếu model truyền vào là một mảng
    // thì duyệt danh sách mảng và gọi đệ quy load từng model
    if (is_array($model)) {
        foreach ($model as $babe) {
            $this->model($babe);
        }
        return;
    }

Qua phần comment giải thích tôi đã nói rõ rồi phải không nào. Riêng phần gọi lại đệ quy hơi khó chút xíu, tức là nếu model truyền vào là một danh sách thì sẽ lặp các mảng và load lại từng model một, các bạn có thể tham khảo bài đệ quy trong php để tìm hiểu thêm nhé.

Đoạn 2:

// Nếu model truyền vào rỗng thì ngưng xử lý
    if ($model == '') {
        return;
    }

    // Định nghĩa một biến $path để lưu đường dẫn đến file model
    $path = '';

Đoạn 3:

// Nếu model truyền vào ở dạng subfolder, ví dụ news/category_model
    // thì xử lý để lấy tên subfolder và tên model 
    if (($last_slash = strrpos($model, '/')) !== FALSE) {
        // Lấy đường dẫn đến model
        $path = substr($model, 0, $last_slash + 1);

        // Lấy tên model
        $model = substr($model, $last_slash + 1);
    }

Trong đoạn code này nó sẽ kiểm tra model truyền vào có phải dạng subfolder hay không, ví dụ news/category_model.php, shop/news/category_model.php.

Biến $last_slash là vị trí xuất hiện dấu / cuối cùng trong chuỗi string model nhập vào, dựa vào vị trí này ta lấy được đường dẫn đến file model $path và tên model $model bằng cách dùng hàm substr($string, $start, $end), nếu bạn chưa biết cách sử dụng hàm substr này thì đọc qua bài này nhé.

Đoạn 4:

// Nếu không sử dụng alias thì lấy tên model làm alias
    if ($name == '') {
        $name = $model;
    }

    // Kiểm tra tên này có trong danh sách model đã load chưa? 
    // Nếu có rồi thì không cần load lại
    if (in_array($name, $this->_ci_models, TRUE)) {
        return;
    }

    // Kiểm tra tên alias tồn tại trong hệ thống CI chưa,
    // nếu tồn tại rồi thì ngưng xử lý
    $CI = & get_instance();
    if (isset($CI->$name)) {
        show_error('The model name you are loading is the name of a resource that is already being used: ' . $name);
    }

Đoạn code 1 kiểm tra xem biến alias $name có truyền vào hay không, nếu không thì lấy tên model làm alias luôn, tức là $name = $model.

Đoạn code 2 kiểm tra xem model này có nằm trong danh sách model đã load của hệ thông hay không, nếu có tức là load rồi nên không cần load lại làm gì.

Đoạn code 3 kiểm tra tên alias có trong danh sách đối tượng load của CI chưa (gồm library, model), nếu có rồi thì ngưng không xử lý tiếp, điều này có nghĩa giả sử bạn 1 model tên news và một library tên news, nếu bạn load library news trước sau đó load model news thì model này sẽ không được load, bởi vì đối tượng news đã tồn tại trong hệ thống CI.

Đoạn 5:

// Đưa tên model về dạng chữ thường
    $model = strtolower($model);

Đoạn này sẽ đưa tên model về chữ thường, phòng trường hợp bạn truyền tên model vào có chữ hoa.

Đoạn 6:

// Duyệt qua danh sách folder đã khai báo với CI
    // mặc định là folder application/models
    foreach ($this->_ci_model_paths as $mod_path) 
    {
        if (!file_exists($mod_path . 'models/' . $path . $model . '.php')) {
            continue;
        }

        // Nếu có truyền tên database cần load khai báo ở file config/database.php
        // thì thực hiện load kết nối với database
        if ($db_conn !== FALSE AND ! class_exists('CI_DB')) {
            if ($db_conn === TRUE) {
                $db_conn = '';
            }

            $CI->load->database($db_conn, FALSE, TRUE);
        }

        // Load thư viện core Model
        // Kiểm tra core đã load chưa
        // nếu chưa load thì mới load
        if (!class_exists('CI_Model')) {
            load_class('Model', 'core');
        }

        // Require model
        require_once($mod_path . 'models/' . $path . $model . '.php');

        // Chuyển tên model thành chữ hoa đầu tiên
        $model = ucfirst($model);

        // khởi tạo model và gán vào danh sách object của CI
        $CI->$name = new $model();

        // đưa model vào danh sách models đã load
        $this->_ci_models[] = $name;
        return;
    }

Đoạn này hơi căng nên các bạn đọc phần comment nhé. Mình sẽ giải thích một hàm quan trọng đó là hàm load_class('Model', 'core'), hàm này có ý nghĩa load thư viện Model nằm trong folder core của system, như vậy muốn load file nào trong hệ thống nào thì chỉ cần truyền vào tên file và tên hệ thống, ví dụ:

load_class('Loader', 'core') load file Loader.php trong thư mục core của system.

load_class('Router', 'core') load file Router.php nằm trong thư mục core của system

Khai Báo Thêm Một Thư Mục Chứa Model

Phần này rất có ích với những bạn muốn custom bộ core của CI nên nếu có hứng thì bạn nên xem kỹ nhé.

Trước tiên tôi sẽ giải thích thư mục chứa folder là gì? Như bạn biết mặc định hệ thống có một thư mục chứa danh sách model đó là application/models, và thư mục chứa library là application/libraries, vậy thêm một thư mục chứa model tức là thêm một thư mục nào đó để chứa model, ví dụ thư mục application/my_model_folder.

Như tôi giải thích ở trên hàm load model sẽ duyệt qua hết danh sách các thư mục chứa model nên việc bạn tạo model ở thư mục nào nó đều load được.

Để thêm một thư mục ta dùng hàm sau trong file system/core/Loader.php, tức là cùng file với hàm load model.

        public function add_package_path($path, $view_cascade=TRUE)
	{
		$path = rtrim($path, '/').'/';

		array_unshift($this->_ci_library_paths, $path);
		array_unshift($this->_ci_model_paths, $path);
		array_unshift($this->_ci_helper_paths, $path);

		$this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;

		// Add config file path
		$config =& $this->_ci_get_component('config');
		array_unshift($config->_config_paths, $path);
	}

Hàm này sẽ thêm một thư mục chứa các thư viện model, library, helper. Như vậy ở controller ta sẽ thêm nó bằng cách sau.

Bạn tạo 1 folder tên models trong thư mục third_party.

Sau đó ở controller nào đó bạn thêm dòng này

$this->load->add_package_path('third_party');

Như vậy là folder third_party/models cũng có thể chứa model của bạn.

Nhưng lời khuyên là không nên dùng hàm này ở controller, vì như vậy controller nào ta cũng phải thêm đoạn code add package này. Giải pháp là bạn tạo một file MY_Loader trong application/core, nếu bạn chưa biết tạo thì tham khảo tại đây, sau đó copy nội dung này vào.

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

class MY_Loader extends CI_Loader 
{
    function __construct() {
        parent::__construct();
        $this->add_package_path(APPATH.'third_party/');
    }
}

?>

Vậy là xong.

Lời kết

Bài viết này dành cho những bạn có kiến thức sử dụng codeigniter thuần thục muốn tìm hiểu nâng cao bộ core của Codeigniter để dễ dàng custom trong quá trình làm việc. Hy vọng qua bài tìm hiểu quy trình load model này sẽ giải đáp được một số thắc mắc của các bạn, xin chào và hẹn gặp lại ở một bài gần nhất.

Cùng chuyên mục:

Chia sẻ theme web blog mobile đơn giản (Theme FMB1)

Chia sẻ theme web blog mobile đơn giản (Theme FMB1)

Freetuts Mobile Blog được code trên nền tảng PHP và MySQL, sử dụng Codeigniter Framework.

Bài 19: Rewrite URL trong Codeigniter

Bài 19: Rewrite URL trong Codeigniter

Sau một khoảng thời gian không đụng tới Codeigniter thì hôm nay lại có dịp…

Tự tạo thư viện load widget trong codeigniter

Tự tạo thư viện load widget trong codeigniter

Như các bạn biết mặc định hệ thống của Codeigniter hoạt động theo mô hình…

Hướng dẫn custom bộ core codeigniter

Hướng dẫn custom bộ core codeigniter

Có khi nào bạn đặt câu hỏi có nên sửa các file nằm trong bộ…

Bài 18: Tìm Hiểu Library Shopping Cart trong Codeigniter

Bài 18: Tìm Hiểu Library Shopping Cart trong Codeigniter

Chào mừng các bạn đã quay trở lại freetuts.net. Như vậy ở bài trước chúng…

Bài 17: Xây dựng crud add - update - edit user

Bài 17: Xây dựng crud add - update - edit user

Crud là một thuật ngữ không hề xa lạ với dân lập trình, nó là…

Bài 16: Kỹ thuật master layout trong codeigniter

Bài 16: Kỹ thuật master layout trong codeigniter

Đây là một vấn đề mở rộng mà CI không đề cập trong user guide,…

Bài 15: Tìm Hiểu Helper Language Trong Codeigniter

Bài 15: Tìm Hiểu Helper Language Trong Codeigniter

Trong bài viết này , chúng ta chỉ tìm hiểu ở khái niệm cơ bản…

Bài 14: Tìm Hiểu Helper Text Trong Codeigniter

Bài 14: Tìm Hiểu Helper Text Trong Codeigniter

Nhìn tiêu đề, hẳn các bạn đã đoán ra hôm nay chúng ta sẽ tìm…

Bài 13: Tìm Hiểu Helper Date Trong Codeigniter

Bài 13: Tìm Hiểu Helper Date Trong Codeigniter

Hôm nay chúng ta sẽ tiếp tục tìm hiểu sâu hơn về các helper mà…

Bài 12: Đóng dấu watermark image trong codeigniter

Bài 12: Đóng dấu watermark image trong codeigniter

Đầu tiên xin gửi lời cảm ơn các bạn đã quan tâm và theo dõi…

Bài 11: Tìm Hiểu Library Image Trong Codeigniter

Bài 11: Tìm Hiểu Library Image Trong Codeigniter

Kết thúc bài trước, chúng ta đã hoàn thành khá xuất sắc phần upload hình…

Bài 10: Tìm hiểu library upload trong codeigniter

Bài 10: Tìm hiểu library upload trong codeigniter

Chào mừng các bạn đã quay trở lại freetuts.net, đã lâu rồi tôi không viết…

Bài 9: Tìm Hiểu Library Form Validation

Bài 9: Tìm Hiểu Library Form Validation

Cho tới bài viết này, chắc hẵn các bạn đều đã biết rõ cách load…

Bài 8: Tìm hiểu Helper Url Và Form Trong Codeigniter

Bài 8: Tìm hiểu Helper Url Và Form Trong Codeigniter

Trong Codeigniter Framework nó chia ra 2 khái niệm đó là helper & library, vậy…

Bài 7: Load Library Pagination Trong Codeigniter

Bài 7: Load Library Pagination Trong Codeigniter

Đây là một library cũng khá là phổ biến, hay được sử dụng trong quá…

Bài 6: Load Library Database Trong Codeigniter

Bài 6: Load Library Database Trong Codeigniter

Tôi sẽ không giới thiệu về library này mà sẽ xoáy sâu vào các thao…

Bài 5: Load Library Session Trong Codeigniter

Bài 5: Load Library Session Trong Codeigniter

Đây là một thư viện khá là quan trọng , trong framework CI (Codeigniter) .…

Bài 4: Load Model Trong Codeigniter

Bài 4: Load Model Trong Codeigniter

Trong Codeigniter để kết nối với Database chúng ta phải cấu hình thông tin cho…

Bài 3: Load View Trong Codeigniter

Bài 3: Load View Trong Codeigniter

Trong Codeigniter tất cả các Views đều được đặt trong thư mục application/views. Các bạn…

Top