Khởi đầu với CodeIgniter



Dạo này thấy nhiều ngừơi quan tâm đến Framework , tớ cũng xin giới thiệu thêm 1 Framework khá đơn giản nhưng hữu dụng cho các bạn mới tìm hiểu thêm lựa chọn. Bài này viết theo tiêu chí dạy nghề cầm tay chỉ việc là chính cho nên sẽ ko có những lý thuyết mang tính hàn lâm, mong các bạn thông cảm.

1. Giới thiệu về codeigniter

- CodeIgniter (CI) là một PHP Framework theo cấu trúc MVC được viết trên PHP4 và hỗ trợ cả PHP4 và PHP5 .Nói nôm na nó là một tập hợp các thư viện viết sẵn trên PHP giúp chúng ta phát triển web bằng PHP nhanh hơn là cách viết lắp ghép thông thường, các thư viện này giúp chúng ta thực hiện các tác vụ thông thường của một ứng dụng web như kết nối và thực hiện các công việc liên quan đến cơ sở dữ liệu , upload file, xử lý hình ảnh, phân trang, cookie, session, bảo mật … Đồng thời các thư viện này cũng giúp chúng ta tổ chức code tốt hơn với mô hình MVC. Đơn giản chỉ có thế . Những thực tế nó còn nhiều hơn thế, nếu đi sâu vào tìm hiểu bạn sẽ nhận ra.
- CI được viết bởi Rick Ellis ( một ca sĩ nhạc Rock ) trực thuộc Expression Engine . CI ra đời chưa lâu ( khoảng năm 2007 ) nhưng đã có rất nhiều đánh giá tốt và đang trở thành một thế lực trong lĩnh vực PHP Framework ( tớ cho là thế ).Đặc điểm khá nổi bật của CI đó tính là tốc độ và …. tài liệu hướng dẫn cực kỳ chi tiết và dễ hiểu. Nếu bạn đã nắm qua PHP cơ bản thì có thể bạn chỉ mất 1, 2 ngày để có thể làm việc với CI sau khi nghiên cứu tài liệu hướng dẫn đi kèm.

2.Bắt đầu với CodeIgniter 
-Để bắt đầu, bạn cần bỏ ra khoảng 15’ để xem lại bài viết về Framework của bác phpKungfu đế nắm sơ về mô hình MVC trong lập trình PHP. Không cần hiểu cách làm, chỉ cần hiểu cách ứng dụng.

Để bắt tay vào làm việc với CI, việc đầu tiên bạn cần phải làm là … download 1 bản CI về . Và nó ở đây :CodeIgniter , không có gì khó khăn đúng không. Bản mới nhất đến thời điểm này là 1.6.3 .Download về và giải nén, copy nó vào webroot của bạn để bắt đầu, rename nó thành tên bạn muốn ( tôi dùng tên là cidemo). Cấu trúc sau khi giải nén ra như sau :


Tớ sẽ nói qua về cấu trúc thư mục của CI để các bạn nắm và dễ làm việc.
Trong một rừng file và folder ấy bạn chỉ cần chú ý đến file index.php ở ngoài gốc và folderapplication trong folder system. Đó chính là vùng làm việc của bạn với CI , các file và folder khác bạn ko cần quan tâm và chú ý làm gì ( nhưng cũng đừng xóa nó nhá ). Ngoài ra có 1 folder user_guide chứa tài liệu hướng dẫn, bạn có thể xóa đi hoặc copy nó sang nơi khác dành để tham khảo.
- file index.php đóng vai trò là 1 bootstrapper cho ứng dụng, nó sẽ nhận yêu cầu và chuyển đến những nơi cần thiết để xử lý. Nó cũng tiến hành khởi tạo một số thứ cần thiết cho ứng dụng. Tạm thời bạn không cần chỉnh sửa gì file này cả, cứ để nó như thế, khi nào quen bạn sẽ biết cách cấu hình lại một số thứ tại file index.php này.
-Folder application : đây là nơi chứa code của bạn. Và trong folder này cũng có 1 số thư mục con nhằm giúp bạn quản lý code của bạn theo mô hình MVC. Cụ thể các thư mục con đó gồm :
config : Nơi bạn đặt các file dùng cho việc cấu hình ứng dụng như thông tin kết nối cơ sở dữ liệu , tên site. url site …
controllers : Nơi đặt các file thực hiện chức năng controller ( điều hướng và xử lý yêu cầu )
errors: Nơi chứa các file thông báo lỗi của bạn. Mặc định sẽ có 1 số mẫu báo lỗi thông thường đi kèm.
helpers : chứa các thư viện dạng hàm ( function) nhằm phục vụ quá trình phát triển ứng dụng cho bạn tạo.
+ hooks : chứa các file xử lý hooks ( tác động vào core library của CI ko cần sửa file ) . Chức năng này tạm thời chưa tìm hiểu đến Cheesy
+ language : Nếu site của bạn có từ 2 ngôn ngữ trở lên thì đặt các file ngôn ngữ tại đây.
+ libraries : Chứa các lớp tiện ích cho ứng dụng do bạn tự tạo
Models : Chứa các file thực hiện chức năng model trong MVC , cụ thể ở đây có thể là các file giúp bạn thao tác với cơ sở dữ liệu theo yêu cầu từ controller
views : chứa các file thực hiện tác vụ view trong mô hình MVC , cứ tạm xem nó là nơi chứa file giao diện cho ứng dụng.

Và tạm thời chúng ta chỉ làm việc chủ yếu trên config, controllers , models và views . các thứ khác có thể từ từ tìm hiểu sau.

Ok, bắt đầu cài đặt CI,sau khi đã giải nén vào webroot, ta thử duyệt đến trang này xem :http://localhost/[Tên thư mục chứa CI], trong vd của tớ thư mục chứa CI là cidemo =>http://localhost/cidemo
Nếu nó hiện ra 1 trang chứa dòng Welcome To Codeigniter có nghĩa là bạn đã thành công ( Tớ chưa từng thất bại ở bước này nên không rõ thất bại nó sẽ như thế nào :d ).

- Nhưng chưa xong đâu, bạn cần phải cấu hình thêm 1 tí nữa là nó mới làm việc tốt. mở file config.php trong system/application/config ( từ đây về sau phần system/application bạn sẽ tự hiểu nhá, vd tôi nói mở file config.php trong config thì bạn sẽ hiểu làsystem/application/config/config.php ) và tìm dòng $config['base_url'], sửa nó thành đường địa chỉ của bạn, theo như vd tôi sẽ cấu hình
-   $config['base_url']   = "http://localhost/cidemo/";

Mục đích của việc này là giúp cho các hàm trợ giúp tự sinh url của CI làm việc chính xác.
Kế đến bạn mở file config/routes.php và tìm dòng
$route['default_controller'] = 'welcome';
Thay bằng
$route['default_controller'] = 'home';

Thay home bằng bất cứ gì bạn thích, nhưng phải nhớ Cheesy .Đây chính là controller mặc định mà CI sẽ tìm đến khi ko cung cấp controller. Phía sau tớ sẽ giải thích về các controller này.
Nếu ứng dụng của bạn có thao tác với cơ sở dữ liệu thì hãy cấu hình thông tin kết nối cơ sở dữ liệu trong config/database.php
Thế là xong bước cài đặt và cấu hình cơ bản.

Sau khi cấu hình như tôi nói thì bạn ko chạy được ứng dụng theo cách gõ đường dẫnhttp://localhost/cidemo . Có lẽ bạn sẽ lầm bầm chửi rủa tớ xúi dại Cheesy . Nhưng hãy bình tĩnh, chả có gì phải lo, lý do ko chạy được là do Ci ko tìm được controller thích hợp, và để tiếp tục ta phải tạo ra controller thôi.
Vậy controller là gì mà nếu ko có nó ứng dụng ko chạy được. Và tớ xin trân trọng giới thiệu :controller chính là trái tim của ứng dụng viết bằng CI, nó xác định các yêu cầu HTTP được xử lý như thế nào. Yêu cầu HTTP là gì ? Đó là những truy vấn thông qua giao thức HTTP như : Mở trình duyệt đánh url : http://localhost/cidemo/index.php/blog <= 1 yêu cầu HTTP , hoặc gửi dữ liệu dạng POST thông qua 1 form đến địa chỉ trên cũng là 1 yêu cầu HTTP.
Và các yêu cầu HTTP này khi gửi đến ứng dụng viết trên CI  sẽ được phân tích và xác địnhcontroller của yêu cầu đó và tiếp đến sẽ gọi controller đó ra xử lý yêu cầu.
Và hãy tìm hiểu khi 1 URL gửi đến CI nó sẽ được phân tích ra sao .
Hãy xét URL sau :
example.com/index.php/news/article/my_article
Khi yêu cầu HTTP gửi đến có dạng như trên thì CI sẽ phân tích ra :
-   news là controller
-   article : là phương thức
-   my_article : Giá trị
Trong Ci , controller tương ứng với 1 class đặt trong folder controllers. Như VD trên khi nhận yêu cầu như thế CI sẽ tìm trong folder controller file có tên là news.php và trong file này nó sẽ tìm class tên  News và tạo thể hiện của nó . Quyền điều khiển ứng dụng hiện thời sẽ do class News này thực hiện, và trong class News này sẽ gọi phương thức article và truyền cho phương thức này tham số my_article
Nếu như url chỉ là example.com/index.php thì CI sẽ lấy controller mặc định được ra cấu hình bên trên ra thực thi. Và phương thức mặc định sẽ là index không có tham số.
Tổng quát lên ta có :
http://example.com/index.php/class/function/ID

-   Controller ( lớp ) class sẽ được thực thi
-   Phương thức function được gọi
-   ID là tham số được truyền vào.( có thế có nhiều giá trị phân cách theo dấu / )

Mặc định, index.php sẽ đi kèm theo url như ta thấy ở trên , chúng ta hoàn toàn có thể loại bỏ index.php này đi thông qua một số thiết lập, nhưng chúng ta sẽ tìm hiểu việc này sau. Tạm thời cứ để đấy, cũng chả ảnh hưởng gì nhiều đến hòa bình thế giới cả
Tôi nói , các bạn có hiểu không ? Nếu chưa hiểu hãy đọc lại 1 vài lần nữa, tưởng tượng trong đầu để hình dung cách thức làm việc của controller. Không hiểu được chỗ này xem như không thể làm việc được với CI.
Nếu đã hiểu thì ta trở lại với ứng dụng , tiến hành cứu chữa nó thôi . Như tớ đã nói , ứng dụng hiện đang bị lỗi do CI không tìm được Controller mặc định theo như ta cấu hình ( home) . Thế thì ta phải tự tạo ra controller này :
Ta tạo file home.php trong thư mục controller với nọi dung như sau :

Code:
<?phpclass Home extends Controller{  // Tạo phương thức xây dựng cho lớp  function Home()  {    //Gọi phương thức xây dựng của lớp cha    parent::Controller();  }    function index()  {    echo "Default Controller";  }
}
?>

Và chạy thử http://localhost/cidemo
Xong Bài 2 Cheesy
Bài 3 : View
Ở bài trước ta đã tìm hiểu về cách thức hoạt động của controller , bài này ta sẽ tập trung vào phần view, một phần cũng khá quan trọng. Nó đóng vai trò là sân khấu cho dữ liệu trình diễn .
Ở phần cuối của bài trên ta đã xuất ra trình duyệt 1 chuỗi bằng cách echo trực tiếp trong controller . Và nó hoạt động.Nhưng thực chất đó là 1 việc làm trái với thuần phong mỹ tục MVC mà CI đang theo đuổi. Việc xuất dữ liệu ra trình duyệt không phải là nhiệm vụ của controller mà do chuyên gia tổ chức trình diễn View đảm nhận. Để làm việc này ta làm như sau :
Trong controller Home ta sửa lại thành

Code:
<?phpclass Home extends Controller{  // Tạo phương thức xây dựng cho lớp  function Home()  {    //Gọi phương thức xây dựng của lớp cha    parent::Controller();  }    function index()  {    $this->load->view('home_view');  }
}
?>

Khoan hãy chạy vội , chạy bây giờ sẽ gặp lỗi ngay . Hãy tạo 1 file tên là home_view.php trong folder views có nội dung

Code:
<p>Default Controller </p>

Bây giờ chạy http://localhost/cidemo sẽ có kết quả tương tự như bài trước . Thế mới đúng luật.
Giải thích :
- Để gọi 1 file view vào xử lý bạn dùng $this->load->view('Tên view'); Với Tên view là 1 file theo dạng [Tên view.php] đặt trong thư mục views.
- Khi bạn gọi view ứng dụng chưa kết thúc ngay mà nó vẫn chạy cho hết các lệnh trong controller xong mới chuyển sang view, và view là bước xử lý sau cùng của ứng dụng.
Trong file view bạn thấy ở trên chỉ đơn thuần là HTML , nhưng bạn hoàn toàn có thể đặt mã PHP ở đây, và bạn có thể truyền giá trị từ controller sang .
Hãy sửa file controller Home của bạn , sửa nội dung function index() thành

Code:

<?php
$data 
= array('var1'=>'Var 1 value','var2'=>'var2 value');$this->load->view('home_view',$data);?>
Và sửa file home_view.php trong folder views thành

Code:

<p>
Var1 = <?php echo $var1 ?>
<br />
Var2 = <?php echo $var2?>
</p>
Và chạy lại ứng dụng sẽ thấy kết quả.

Ở đây ta thấy rằng ta truyền cho  view 1 mảng , nhưng khi truy xuất lại dùng trực tiếp qua biến mà ko thông qua mảng . Điều này là nhờ CI đã chuyển hết các cặp khóa và giá trị trong mảng thành biến mang giá trị tương ứng giúp ta làm việc dễ dàng hơn.
Hết bài 3 , bài sau tớ sẽ bắt tay vào xây dựng 1 ứng dụng đơn giản với CI .

Để thêm sinh động, ta sẽ tiến hành dùng CI để viết một ứng dụng nho nhỏ cho vui nhà vui cửa Cheesy
Ứng dụng của chúng ta chỉ thực hiện 1 vài tác vụ đơn giản như sau :
- Upload 1 file hình lên
- Tạo thumbnail cho nó
- Lưu thông tin về hình ảnh vào database
- Show link file gốc và thumbnail ra .
.... Hết . Giống thằng Imageshack nhỉ Cheesy

Để thực hiện công việc ấy ta cần tạo 1 database với cấu trúc như sau :
- Database name : cidemo
- Table : img
   + id int auto_increment
   + title varchar(255) not null
   + img varchar(255) not null
   + thumb varchar(255) not null
Và ... vẽ ra 1 template đơn giản để dùng
Template của tớ vẽ ra như sau ( hơi xấu  , nhưng dùng được )

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta name="author" content="DoanGia (phpvn.org)" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link rel="stylesheet" xhref="css/style.css" type="text/css" />
  <title>CodeIgniter Demo</title>
</head>
<body>
  <div id="page" align="center">
    <div id="header">
      <div id="sitename" align="left">CodeIgniter Demo</div>
      <div align="right" id="menu"><a xhref="http://www.nguyenanhung.com/admin.php#">Home</a> | <a xhref="http://www.nguyenanhung.com/admin.php#">Upload</a> | <a xhref="http://www.nguyenanhung.com/admin.php#>About Me</a></div>
    </div>
<div id="content">
      <div id="contenttext">
        <h1>Welcome</h1>
        <p>
Nội Dung ở đây
        </p>
      </div>
<div class="footer">
        <br />
        DoanGia 2008 . powered by <a xhref="http://codeigniter.com" target="_blank">CodeIgniter</a>
      </div>
    </div>
  </div>
</body>
</html>

Và CSS
Code:
body {
  margin-top: 0px;
  margin-left: 0px;
  margin-right: 0px;
  margin-bottom: 0px;
}
h1
{
  margin:0;
  padding:0;
  text-align:left;
  color:#FF9933;
  font-size:24px;
}

label{
font-weight: bold;
}

p {
  text-align:justify;
  color:#777777;
  font-size: 90%;
  line-height: 1.5em;
}

.error
{
  color:red;
}
.img
{
  width:200px;
  float:left;
}
.image
{
  background-color:#F0F0F0;
  border-style:dotted; border-width:1px; border-color:#0080ff;
}
/*HEADER*/
#header{
  width: 800px;
  position:relative;
  height: 80px;
  border-bottom:1px solid #7DA5E0;
  }

#sitename {
  position:absolute;
  font-family: Verdana, Arial, Helvetica, sans-serif;
  color :#7DA5E0;
  font-size: 32px;
  font-weight: bold;
  margin-top:10px;
  margin-left:40px;
  left: 0px;
  top: 0px;
}
/*MENU IN HEADER*/
#menu{
  position:absolute;
  bottom: 5px;
  right: 30px;
  font-family: Verdana, Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: bold;
}
#menu a{
  font-family: Verdana, Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: bold;
  color:#FF9933;
  text-decoration:none;
}
#menu a:hover{
  text-decoration:underline;
}

/*CONTENT*/
#content{
  width: 800px;
}
#contenttext{
  width: 800px;
  margin-top:30px;
}

/*FOOTER*/
.footer{
  width: 800px;
  height: 30px;
  clear:both;
  font-family: Verdana, Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: bold;
  color:#000000;
  border-top:1px solid #7DA5E0;
}
/*FOOTER LINKS*/
.footer a{
  font-family: Verdana, Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: bold;
  color:#FF9933;
  text-decoration:none;
}
.footer a:hover{
  text-decoration:underline;
}

Và ta sơ chế nguyên liệu để dễ làm việc. Tạo 1 folder css trong cidemo và cho đoạn css trên vào 1 file tên là style.css
Từ template trên ta cắt nhỏ ra thành 3 phần để dễ chỉnh sửa và làm việc.
Và tớ cắt thế này
header
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="author" content="DoanGia (phpvn.org)" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" xhref="css/style.css" type="text/css" />
<title>CodeIgniter Demo</title>
</head>
<body>
<div id="page" align="center">
<div id="header">
<div id="sitename" align="left">CodeIgniter Demo</div>
<div align="right" id="menu"><a xhref="http://www.nguyenanhung.com/admin.php#">Home</a> | <a xhref="http://www.nguyenanhung.com/admin.php#">Upload</a> | <a xhref="http://www.nguyenanhung.com/admin.php#>About Me</a></div>
</div>
Content
Code:
<div id="content">
<div id="contenttext">
<h1>Welcome</h1>
<p>
Nội Dung ở đây
</p>
</div>
Footer
Code:
<div class="footer">
<br />
DoanGia 2008 . powered by <a xhref="http://codeigniter.com" target="_blank">CodeIgniter</a>
</div>
</div>
</div>
</body>
</html>

Không cắt ra cũng không sau, nhưng cắt ra thì dễ làm việc hơn ( theo tớ)
Từ 3 mảnh cắt ấy ta tạo thành 3 file header.php, content.php và footer.php đặt vào folder views
Xong bước chuẩn bị nguyên liệu . Đến bước cấu hình thêm CI 1 tí .
Ở các bài trước ta đã cấu hình thông tin về base url và default controller . Và ở bài này ta sẽ cấu hình thêm 2 phần quan trọng nữa là database và auto load .

Vì ứng dụng của chúng ta có thao tác với cơ sở dữ liệu nên ta phải cung cấp thông tin kết nối cơ sở dữ liệu Cheesy . Mở file database.php trong folder config
Code:
$active_group = "default";
$active_record = TRUE;

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "";
$db['default']['database'] = "cidemo";
$db['default']['dbdriver'] = "mysql";
$db['default']['dbprefix'] = "";
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = "";
$db['default']['char_set'] = "utf8";
$db['default']['dbcollat'] = "utf8_general_ci";
Tạm thời ta chỉ cung cấp thông tin cơ bản là hostname, username, password và databasename là đủ, các thông tin khác cứ để mặc định.

Và để khỏi mất công Load thư viện database khi dùng , ta sẽ nhờ CI tự load bằng cách mở file autoload.php trong folder config và tìm :
$autoload['libraries'] = array();
và sửa thành:
$autoload['libraries'] = array('database');

Nếu cần tự load thêm thư viện gì nữa bạn có thể thêm vào VD:
$autoload['libraries'] = array('database', 'session');
Nhưng tạm thời ta chỉ dùng database thôi.

Và có 1 helper hữ dụng luôn cần đến là url , ta tìm
$autoload['helper'] = array();
Sửa thành
$autoload['helper'] = array('url');


Ý nghĩa của việc cấu hình autoload là thế nào ? Thông thường, mỗi khi muốn dùng thư viện hay helper nào , ta sẽ phải tự load lên bằng cách :
$this->load->helper('Tên Helper') hoặc $this->load->library('tên Library')
Điều này chỉ có tác dụng trong controller hiện tại. Và nếu ở controller nào bạn cũng cần dùng helper ấy thì ... mỗi lần như thế phải load lên , rất vất vả. Thay vì làm như thế bạn sẽ nhờ CI load giúp lúc khởi tạo ứng dụng, như thế chỗ nào cũng có thể dùng mà ko cần phải load lên.
---
Thế là xong phần cấu hình.Bây giờ có thể chuyên tâm code

Đầu tiên ta sẽ thực hiện một vài vấn đề râu ria đơn giản làm quen trước.Ta sẽ tạo 2 trang gần như tĩnh là trang chủ chào mừng và trang giới thiệu ( about me Cheesy )
Như đã nói , mọi chuyện bắt đầu từ controller, trái tim của ứng dụng. Ta lại quay lại với controller Home và sửa nội dung function index
Code:
function index()
  {
    $this->data['heading'] = 'Welcome to CodeIgniter Demo';
    $this->data['content'] = 'Đây là website xây dựng dựa trên CodeIgniter Framework. Website minh họa một số chức năng cơ bản của CodeIgniter . Hi vọng sẽ giúp ích được cho các bạn mới làm quen với CodeIgniter.
                 <br />Các bạn có thể tham khảo thêm CodeIgniter User Guide được kèm trong bản phân phối của CodeIgniter để tìm hiểu thêm các chức năng khác mà CodeIgniter hỗ trợ.';
    $this->load->view("content",$this->data);
  }

Không có gì mới lạ đúng ko ?
Tiếp đến bạn mở file content.php trong folder view và sửa nó lại thành
Code:
<?php
$this
->load->view("header");?>

<div id="content">
      <div id="contenttext">
        <h1><?=$heading?></h1>
        <p>
        <?=$content?>
        </p>
      </div>
<?php
$this
->load->view("footer");?>

Tại đây chúng ta sẽ load 2 file view là header và footer vào , như thế trong controller bạn chỉ cần gọi thằng content là đủ , nó sẽ kéo theo 2 thằng kia Cheesy

Và sửa tiếp file header.php trong folder views lại 1 tí .
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta name="author" content="DoanGia (phpvn.org)" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link rel="stylesheet" xhref="<?=base_url()?>css/style.css" type="text/css" />
  <title>CodeIgniter Demo</title>
</head>
<body>
  <div id="page" align="center">
    <div id="header">
      <div id="sitename" align="left">CodeIgniter Demo</div>
      <div align="right" id="menu"><a xhref="<?=base_url()?>">Home</a> | <a xhref="<?=site_url('upload')?>">Upload</a> | <a xhref="<?=site_url("home/about")?>">About Me</a></div>
    </div>

Ta dùng 2 hàm của helper url là base_url và site_url để tự sinh url cho ứng dụng
base_url sẽ cho ra đường dẫn đến ứng dụng ( như ta đã config) , ở đây nó cho ra :http://localhost/cidemo
Và site_url tạo 1 url chuẩn cho trang web , như trên site_url('upload') sẽ cho rahttp://localhost/cidemo/index.php/upload

----
Việc dùng 2 hàm này rất hữu ích khi ta đưa ứng dụng vào sử dụng không phải chỉnh lại từng đường dẫn ...

Chạy ứng dụng bạn sẽ thấy...

Hôm qua đang cao hứng viết thì bị gọi về , mất hết cả hứng.  Cheesy
Hôm nay cố lấy lại cảm hứng để viết. Thực ra thì ứng dụng này tớ đã viết xong rồi , bây giờ chỉ cố tìm cách giải thích thôi  Cheesy
---

Trở lại với ứng dụng, sau bài trước ta đã tạo ra được một trang chào mừng khá đơn giản. Và ta tiếp tục đà đơn giản đó để tạo thêm một trang about me giới thiệu cho có vẻ hoành tráng.

Tiếp tục với controller Home , ta thêm vào một phương thức nữa như sau:
Code:
<?phpfunction about()  {    $this->data['heading'] = "About Me";    $this->data['content'] = 'Tui: Một người đẹp trai đến khó tin, nói chuyện có duyên đến kỳ lạ, hát hay đáng hâm mộ, code tốt, design được, giỏi ngoại ngữ, học đâu biết đó, thói hư tật xấu gần như không có, chỉ mắc phải một tật xấu nho nhỏ : NỖ';    $this->load->view('content',$this->data);  }?>

Lại chạy ứng dụng, click vào link about trên menu , ta sẽ thấy kết quả Cheesy , hoặc gõ vào địa chỉ http://localhost/cidemo/index.php/home/about

Xong phần râu ria trang trí không mấy khó khăn.
Bây giờ ta bắt đầu đi vào phần chính của ứng dụng : upload và tạo thumbnail cho ảnh. Quá trình đó tớ có thể mô tả như sau :
- Tạo form để người dùng chọn ảnh upload
- Khi người dùng nhấn upload , ta sẽ xử lý quá trình upload lên server . Nếu có lỗi sẽ quay về trang upload để người dùng nhập thông tin lại kèm theo thông báo lỗi.

- Nếu quá trình upload thành công ta sẽ tạo thumbnail cho ảnh vừa upload
- Sau khi tạo thumbnail xong, ta sẽ ghi thông tin về ảnh vào cơ sở dữ liệu
- Bước cuối cùng là in thông tin về ảnh ra cho người dùng xem.

Để bắt đầu thực hiện ta tạo 1 controller mới tên là upload với nội dung ban đầu như sau
Code:
<?phpclass Upload extends Controller{  var $data = array();      function Upload()  {    parent::Controller();    $this->load->helper('form');  }    function index()  {    $this->data['error'] = '';    $this->load->view('upload_form',$this->data);  }?>


Lúc ban đầu ta sẽ load upload form lên cho người dùng nhập , nhìn vào đoạn mã trên chắc chắn rằng ta phải tạo một file view tên là upload_form.php . Và đây là nội dung của file đó :
Code:
<?php
$this
->load->view("header");?>

<div id="content">
      <div id="contenttext">
        <h1>Upload Form</h1>
        <p>
        Chấp nhận các loại file ảnh png, gif, jpg có dung lượng nhỏ hơn 2 Mb<br />
        <div align="left">
        <?php
  
      echo form_open_multipart('upload/do_upload');        echo form_label('Image Title (*)','title');        echo '<br />';        echo form_input('title');        echo '<br /><br />';        echo form_label('Images File (*)','img');        echo '<br />';        echo form_upload('img');        echo '<br /><br />';        echo form_submit('submit''Upload!');        echo form_close();        ?>

        </div>
        </p>
        <p class="error"><?=$error?></p>
      </div>
<?php
$this
->load->view("footer");?>

Ở đây có một vài điểm khác thường so với các file view từ đầu đến giờ ta vẫn hay tạo. Ở đây tớ dùng một helper khác của CI là form helper ( các hàm hỗ trợ thao tác với form). Để sử dụng helper này trong controller tớ đã load nó lên trong phương thức xây dựng thế này :
Code:
$this->load->helper('form');
Và trong file view tớ sử dụng chúng một cách trực tiếp bằng cách gọi hàm thông thường. Và công dụng của chúng như sau :
Code:
form_open_multipart('upload/do_upload');
Hàm này sẽ cho ra một thẻ mở form dùng cho việc upload , thay vì dùng hàm đó ta sẽ phải viết HTML thế này
Code:
<form enctype="multipart/form-data" action="upload/do_upload" method="POST">
Rõ ràng cách dùng helper sẽ khỏe người hơn.
- form_label('Image Title (*)','title');
Cho ra
Code:
<label for="title">Image Title (*)</label>
- form_input('title');
cho ra
Code:
<input type="text" name="title">
....
Các hàm sau cũng tương tự thế , các bạn xemhttp://codeigniter.com/user_guide/helpers/form_helper.html để biết thêm chi tiết.

Bên dưới tớ để một vùng để in ra lỗi nếu có , mặc định lúc ban đầu biến này sẽ là rỗng ( định bên trong controller) , nếu có lỗi sẽ truyền thông điệp qua biến này.

Ok, bây giờ bạn có thể chạy ứng dụng để xem thử :http://localhost/cidemo/index.php/upload

Ở trên ta đã qui định nơi xử lý việc upload file này là trong phương thức do_upload của controller upload
Vì thế ta sẽ tạo ra phương thức do_upload trong controller upload

Đầu tiên việc cần làm trong phương thức này là kiểm tra dữ liệu nhập vào đã hợp lệ hay chưa. CI có một thư viện hỗ trợ việc kiểm tra dữ liệu đầu vào này khá tốt là library Validation . Để sử dụng đầu tiên bạn phải load nó lên :
Code:
$this->load->library('validation');

Và cho nó biết "đòi hỏi" của chúng ta với từng field của form như thế nào, trong tường hợp này tôi muốn field không được để trống , tôi sẽ làm như sau
Code:
$rules['title'] = "required";
$this->validation->set_rules($rules);
Và để tiến hành kiểm tra ta dùng phương thức run của lớp validation , phương thức này sẽ trả về true nếu dữ liệu đầu vào đạt yêu đầu , ngược là sẽ false và kèm theo thông tin lỗi được gửi kèm trong thuộc tính error_string . Sau khi load thư viện lên ta có thể truy xuất nó bằng cú pháp : $this->[tên thư viện]->[phương thức/thuộc tính] .Tớ tiến hành kiểm tra như sau :
Code:
<?phpfunction do_upload()  {    $this->load->library('validation');    $rules['title'] = "required";    $this->validation->set_rules($rules);    if ($this->validation->run() == FALSE)    {      $this->data['error'] = 'Vui lòng nhập tiêu đề ảnh';      $this->load->view('upload_form',$this->data);    }    else    {
                           
// xu ly upload
                         
}
}
?>
Nếu xác thực không đạt yêu cầu ta sẽ cho quay về form upload kèm theo thông báo lỗi. Xem thêm tại : http://codeigniter.com/user_guide/libraries/validation.html
Ở đây tớ không xác thực field file , tớ sẽ dành phần đó cho phần upload xử lý Cheesy ( thích thế )
Nếu xác thực ok , ta sẽ tiến hành upload ... ta lại dùng tiếp một thư viện cung cấp sẵn của CI để xử lý việc này. Thư viện này mang tên upload Cheesy .
Quá trình thực hiện diễn ra như sau:
Code:
<?php
                                      $config
['upload_path'] = UPLOAD_DIR;      $config['allowed_types'] = 'gif|jpg|png';      $config['max_size']  '2048';      $config['encrypt_name']  TRUE;      $this->load->library('upload'$config);      if ( ! $this->upload->do_upload('img'))      {        $this->data['error'] = $this->upload->display_errors();              $this->load->view('upload_form'$this->data);      }        else      {
                                        
// Da upload xog                                       }?>

Đầu tiên ta load thư viện lên và truyền cho nó một số thông tin khởi tạo về quá trình upload , ở đâu tớ dùng một số cấu hình:

$config['upload_path'] = $this->upload_dir;  //qui định thư mục chứa hình
$config['allowed_types'] = 'gif|jpg|png';  // chấp nhận định dạng file nào ( ở đây là .gif,.png và . jpg )
$config['max_size']   = '2048'; //Kích thước tối đa của file upload tính bằng kb , ở đây là 2 Mb
$config['encrypt_name']   = TRUE; // Mã hóa tên file upload lên

Sau khi khởi tạo , bạn gọi phương thức do_upload để tiến hành upload , nếu upload thành công sẽ trả về true và kèm theo một thuộc tính lưu giữ thông tin về file đã upload , ngược lại trả về false
Code:
function do_upload()
  {
    $this->load->library('validation');
    $rules['title'] = "required";
    $this->validation->set_rules($rules);
    if ($this->validation->run() == FALSE)
    {
      $this->data['error'] = 'Vui lòng nhập tiêu đề ảnh';
      $this->load->view('upload_form',$this->data);
    }
    else
    {
      $config['upload_path'] = $this->upload_dir;
      $config['allowed_types'] = 'gif|jpg|png';
      $config['max_size']  = '2048';
      $config['encrypt_name']  = TRUE;
      $this->load->library('upload', $config);
      if ( ! $this->upload->do_upload('img'))
      {
        $this->data['error'] = $this->upload->display_errors();
      
        $this->load->view('upload_form', $this->data);
      }  
      else
      {
                                           //xu ly tao thumbnail
      }
}
}

ta sẽ khai báo 2 thuộc tính trong controller này để lưu thư mục chứa hình upload và hình thumbnail
Ta thêm
Code:
var $upload_dir = "uploads/";
var $thumb_dir = "upload/thumb";
Vào sau dòng var $data;
Tạm thời khoan hãy chạy vội, ta sẽ tiếp tục quá trình tạo thumbnail . Để dễ nhìn tớ tách việc tạo thumbnail này ra thành một phương thức riêng , do phương thức này chỉ là phương thức tiện ích nên ta đặt tên khác thông thường 1 tí là thêm dấu _ ở phía trước , việc đặt tên thế này CI sẽ xem phương thức đó là private và không cho bên ngoài truy xuất vào , phương thức này có nội dung như sau :
Code:
function _thumb($img)
  {
    $config['image_library'] = 'gd';
    $config['source_image'] = $img;
    $config['new_image'] = $this->thumb_dir;
    $config['create_thumb'] = TRUE;
    $config['maintain_ratio'] = TRUE;
    $config['width'] = 200;
    $config['height'] = 200;
    $this->load->library('image_lib', $config);
    if(!$this->image_lib->resize())
      return false;
    else
      return true;
  }
Ở đây là dùng thư viện image_lib của CI để thực hiện việc tạo thumbnail . Cách cấu hình cơ bản như thế, $img là biến nhận đường dẫn của hình cần tạo thumbnail .
Và ở phương thức do_upload ta gọi đến nó như sau :
Code:
<?phpfunction do_upload()  {    $this->load->library('validation');    $rules['title'] = "required";    $this->validation->set_rules($rules);    if ($this->validation->run() == FALSE)    {      $this->data['error'] = 'Vui lòng nhập tiêu đề ảnh';      $this->load->view('upload_form',$this->data);    }    else    {      $config['upload_path'] = $this->upload_dir;      $config['allowed_types'] = 'gif|jpg|png';      $config['max_size']  '2048';      $config['encrypt_name']  TRUE;      $this->load->library('upload'$config);      if ( ! $this->upload->do_upload('img'))      {        $this->data['error'] = $this->upload->display_errors();              $this->load->view('upload_form'$this->data);      }        else      {        $img $this->upload->data();        if($this->_thumb($img['full_path']))        {        //Luu vap database                                    }      }    }  }?>
Đó là xong quá trình upload và tạo thumbnail
Cheesy
Tạm nghỉ tí , mai tớ sẽ tiếp phần cuối Cheesy . Tớ gửi kèm ứng dụng mẫu tớ đã vất vả code hơn 1h cho các bạn test .


Xin lỗi vì delay lâu quá Cheesy , hôm nay có thời gian vào viết nốt phần cuối

Bài 4 :   MODEL
Trong MVC , Model đóng vai trò là người giữ kho ( tớ cho là thế ) . Muốn đưa thông tin và cơ sở dữ liệu => model , muốn lấy thông tin từ cơ sở dữ liệu => model . Trong CI tớ thấy như thế , nhưng trong MVC design pattern hình như Model còn đóng vai trò xử lý nữa thì phải ... Tớ ko thật sự rành lắm . Tạm thời cứ cho nó là ông thần giữ cửa kho báo thôi Cheesy

trong CI , để sử dụng model , đầu tiên ta phải tạo ra model chứa trong folder model , và khuôn dạng nó như sau
Code:
<?phpclass demo_model extends Model{
     function 
Model()
   {
        
parent::Model();
   }
}
?>
Nó như thế , muốn xử lý gì nữa thì cứ cho thêm phương thức vào .
Và trong Controller ta gọi đến model để xử lý như sau
Code:
<?phpclass Demo extends Controller{
       function 
Demo()
       {
            
parent::Controller();
       }

       function 
index()
       {
           
$this->load->model('Demo_model');
       }
}
?>

Sau khi gọi vào có thể sử dụng như sau
$this->Demo_model->[ phương thức]

Sơ lược chỉ có thế , và trong Model bạn hoàn toàn có thể làm thế này :

Code:
<?phpclass demo_model extends Model{
     function 
Model()
   {
        
parent::Model();
   }

   function 
insert($name)
    {
        
$conn mysql_connect($host,$user,$pass);
        
$db mysql_select_db($database,$conn);
        return 
$query mysql_query("insert into table values(null,'$name')");
    }

}
?>

Nhưng như thế không sướng Cheesy , CI có hỗ trợ cho ta một công cụ thao tác đơn giản với database là Active Record - một design pattern nữa và mang màu sắc của Ruby on Rails ( nghe nói thế chứ tớ cũng chả biết RoR là gì , dịch theo kiểu tớ là hồng ngọc trên đường rây :d ) . Active Record này giúp ta tiết kiệm 1 khoảng thời gian đáng kể trong việc viết code .

Vd ... thay vì viết thế này để insert một mẩu tin vào cơ sở dữ liệu :
Code:
$query = mysql_query("insert into table(title,name,date) values('$title','$name',$date)");

ta có thể dùng Active Record thế này trong CI
Code:
$data = array(
               'title' => $title,
               'name' => $name,
               'date' => $date
            );
$this->db->insert('mytable', $data);

Với Active Record dữ liệu truyền vào sẽ qua một bước sàng lọc và escape tốt hơn

Với Active Record này bạn không cần phải viết bất kỳ câu SQL nào cả mà vẫn làm việc tốt , nó hỗ trợ gần như đầy đủ các thao tác về database như thêm , sửa , xóa , truy xuất ....
Bạn nên tìm hiểu thêm trong User Guide Cheesy


---
Bây giờ trở lại với ứng dụng mẫu , bây giờ đến bước ta lưu vào cơ sở dữ liệu , cũng là lúc dùng đến Model Cheesy

Ở bài trước ta đã tạo xong thumbnail , chỉ còn chờ lưu vào cơ sở dữ liệu .
Đây là quá trình đó
Code:
if($this->_thumb($img['full_path']))
        {
          $dt['title'] = $this->input->post('title');
          $dt['img'] = $this->upload_dir.$img['file_name'];
          $dt['thumb'] = $this->thumb_dir_dir.$img['raw_name'].'_thumb'.$img['file_ext'];
          $this->load->model('Img_model');
          $id=$this->Img_model->add($dt);
                
          redirect('upload/view/'.$id, 'location', 301);          
        }

Có 1 vài điểm cần nói :
- Để nhận dữ liệu người dùng post lên ta dùng $this->input->post('title'); thay cho $_POST['title'];
- Dữ liệu cần add vào cơ sở dữ liệu ta cho vào 1 mảng mới khóa ứng với tên trường .Xong truyền vào cho model xử lý
Tất nhiên ta phải tạo 1 file model thế này
Code:
<?phpclass Img_model extends Model{  var $table 'img';    function Img_model()  {    parent::Model();  }    function add($data)  {    $this->db->insert($this->table,$data);    return $this->db->insert_id();  }  
}
?>
post-edit

1 nhận xét :

- Không bình luận các vấn đề to lớn như chính trị và tôn giáo
- Nội dung nên liên quan tới bài viết.
- Hãy đóng góp ý kiến của bạn để Blog hoàn thiện hơn.