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 tuts về CI căn bản, vì một số lý do khách quan cũng mong các bạn rộng lòng thông cảm, ở các bài trước chúng ta đã cùng nhau tìm hiểu qua các thao tác kết nối model, phân trang và sử dụng helper form & url. Tiếp tục loạt bài trong serie CI căn bản, chúng ta sẽ cùng nhau tìm hiểu một thư viện tiếp theo đó là File Upload, đây là môt trong những thư viện mà tôi nghĩ rằng nó cũng khá là phổ biến và quan trọng, vì trong thực tế bất kể chúng ta xây dựng một trang web này cũng phải upload hình ảnh lên.

Giới thiệu library upload:

Bất kể khi bạn làm việc với bất kì framework nào thì đều cũng phải trải qua quá trình upload file và với Codeigniter cũng không ngoại lệ, các sáng lập viên đã xây dựng cho chúng ta một library khá là hay với thao tác hỗ trợ chúng ta tối đa trong việc upload hình ảnh, vậy với Library upload chúng ta sẽ làm được những gì với nó.

  1. Hỗ trợ định dạng file được chỉ định khi upload (Ví dụ: Cho phép upload với 3 định dạng hình ảnh).
  2. Tùy chỉnh độ rộng & cao tấm hình đc phép upload một cách dễ dàng.
  3. Giới hạn dung lượng file hình ảnh được upload.
  4. Hỗ trợ chúng ta resize ảnh theo nhu cầu.
  5. Đóng dấu bản quyền watermark với định dạng text hoặc chèn logo lên bất kể vị trí nào trong tấm hình.

Với 5 ưu điểm trên , tôi thấy rằng đã là quá good rồi phải không nào, vừa bảo mật, vừa resize ảnh, đóng dấu bản quyền luôn còn dễ dàng cho phép độ rộng và cao của tấm ảnh được upload lên, theo tôi như thế là quá đủ cho thao tác upload hình ảnh rồi. Để không làm mất thời gian của các bạn, chúng ta sẽ tìm tiến hành tìm hiểu cách làm viêc, cũng như cấu hình library diễn ra như thế nào.

Cấu hình library upload:

Cũng như các library khác, để có thể thao tác với nó thì cẩn phải gọi nó ra bằng cú pháp sau.

1
$this->load->library('upload')
Và sau đó chúng ta sẽ có một số thông tin cấu hình như thế này.
1
2
3
4
5
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '100';
$config['max_width']  = '1024';
$config['max_height']  = '768';
Với thông tin trên thì các bạn có thể dễ dàng nhận ra rằng chúng ta đang cấu hình đường dẫn , định dạng hình ảnh được phép upload, kích thước tấm hình, cũng như dung lượng tấm hình được phép upload. Sau khi cấu hình xong các thông tin trên chúng ta sẽ có câu lệnh để thực thi việc upload như sau.
1
$this->upload->do_upload('Ten file')

Và tất nhiên là sau khi upload xong chúng ta có thể test xem mình upload có thành công hay không, sẽ có câu lệnh debug như sau, với câu lệnh này chúng ta sẽ dễ dàng lấy ra được tên của tấm hình, file tạm của nó...vv.
1
$this->upload->data();
Trong quá trình upload file nếu tấm hình của chúng ta bị lỗi cũng như có một số chuẩn mực không hợp lệ thì phải xuất ra câu thông báo lỗi, để người dùng có thể hiểu rằng , hình họ vừa upload bị lỗi thao tác như là định dạng không đúng, kích thước hình vượt quá yêu cầu cho phép, thì lúc bấy giờ chúng ta cần phai sự dụng thêm một câu lệnh nửa đó là.
1
$this->upload->display_errors();
Như vậy thì chúng ta sẽ chỉ cần nhớ vỏn vẹn 3 lệnh và một số thông tin cấu hình ở phía trên thì chúng ta hoàn toàn dễ dàng upload hình ảnh một cách thoải mái nhất. Và để cho các ban dễ hình dung hơn thì chắc chắn tôi sẽ phải demo một ví dụ nhỏ rồi.

Thực hành upload file từ máy tính lên web server:

Đến với bài này thì chắc chắn các bạn cũng đã biết cách tạo ra môt controller rồi, nên tôi sẽ không nhắc lại vấn đề này nữa để tránh mất thời gian hơn tôi đã chuẩn bị sẵn cho chúng ta một controller upload với các tham số như sau, do trong ví dụ này tôi sử dụng helper form & url nên tôi sẽ tiến hành load nó ra ngay tại constructor. Tạo thêm một folder uploads ngang cấp với folder application, tôi cũng tạo ra action index và load cái form ra.

1
2
3
4
5
6
7
8
9
class Upload extends CI_Controller{
    public function __construct(){
        parent::__construct();
        $this->load->helper(array("form", "url"));
    }
     
    public function index(){
        $this->load->view("upload_view");
    }

Tôi tạo trong folder view một file có tên là upload_view, và bắt đầu thao tác với form helper như sau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
$upload=array(
    "name" => "img",
    "size" => "25",
);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Freetuts.net</title>
</head>
 
<body>
    <?php
        echo form_open_multipart(base_url()."index.php/upload/doupload");
        echo form_label("Avartar: ").form_upload($upload)."<br />";
        echo form_label(" ").form_submit("ok", "Upload");
        echo form_close();
    ?>
</body>
</html>
Hàm form_open_multipart cũng giống như , multipart/form-data trong html bình thường thôi nhé các bạn., tôi tạo $upload với name là img, ở form_submit cũng có name là ok, dùng để check thao tác của người dúng với form, và với hàm base_url thì tôi sẽ chỉ ra đường dẫn tuyệt đối như sau, controller là upload & action sẽ là doupload, thực hiện xong 2 thao tác này các bạn có thể view source để xem phần hiển thị html của nó.

Chúng ta sẽ tạo ra action doupload và check xem người dùng đã nhấn nút submit hay chưa bằng thao tác $this->input->post('ok'). Nếu nó thỏa điều này thì chúng ta mới tiến hành cho thông tin cấu hình upload file vào được. việc check như thế này sẽ kiểm tra xem người dùng có chọn hình chưa, nếu chưa chọn hình mà nhấn nút submit thì trình duyệt sẽ trả về thông báo lỗi.

Khi cấu hình các thông tin xong, tôi sẽ load cái library ra phía dưới các thông tin, kèm theo đó sẽ là $config chính là các cấu hình mình đã khai báo ở phía trên, tất nhiên chỉ như vậy thôi là chưa đủ đâu nhé, để có thể upload file thì cần phải có lệnh để thực thi thao tác. Truyền vào tên file đã tạo ở phần view, hoàn thành xong bước này thì chúng ta có thể upload rồi đấy, upload xong thì cần phải show ra toàn bộ thông tin của tấm ảnh, tôi đặt một tên biến bất cừ cho phương thức show info tấm hình, tôi sẽ kiểm tra dữ liệu trong cặp thẻ pre. Còn ngược lại nếu như mà quá trình upload thất bại thì chúng ta sẽ xuất ra câu thông báo lỗi, khi đó sẽ phải tạo ra một cái biến để đổ câu thông báo lỗi sang view, tôi tạo biến $data['errors'] = $this->upload->display_errors();, vậy ngay vị trí của controller index chúng ta phải khai báo biến $errors bằng rỗng  để nó ẩn câu thông báo lỗi chỉ khi nào có lỗi thì mới show ra thôi. Nếu errors khác rỗng thì chúng ta mới xuất thông báo lỗi ra. Ra trình duyệt và gõ localhost/citest/index.php/upload để test nào.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public function index(){
        $data['errors'] = '';
        $this->load->view("upload_view", $data);
}
 
public function doupload(){
        if($this->input->post("ok")){
            $config['upload_path'] = './uploads/';
            $config['allowed_types'] = 'gif|jpg|png';
            $config['max_size'] = '900';
            $config['max_width']  = '1024';
            $config['max_height']  = '768';
            $this->load->library("upload", $config);
            if($this->upload->do_upload("img")){
                echo 'Upload Ok';
                    $check = $this->upload->data();
                    echo "<pre>";
                    print_r($check);
                    echo "</pre>";
            }else{
                $data['errors'] = $this->upload->display_errors();
                $this->load->view("upload_view", $data);
            }
    }
}      
Nếu upload thành công thì sẽ xuất ra các thông số như sau:
Upload Ok
Array
(
    [file_name] => Koala.jpg
    [file_type] => image/jpeg
    [file_path] => D:/freetuts/www/cietest/uploads/
    [full_path] => D:/freetuts/www/cietest/uploads/Koala.jpg
    [raw_name] => Koala
    [orig_name] => Koala.jpg
    [client_name] => Koala.jpg
    [file_ext] => .jpg
    [file_size] => 762.53
    [is_image] => 1
    [image_width] => 1024
    [image_height] => 768
    [image_type] => jpeg
    [image_size_str] => width="1024" height="768"
)

Để check lỗi, thì tôi sẽ chọn thử một file .doc nào đó tiến hành nhấn nút submit xem kết quả trả về ntn.

The filetype you are attempting to upload is not allowed.

Kết quả là file này không đúng định dạng nên không được phép upload, Với viêc cấu hình định dạng file cho phép upload thì các bạn đã phần nào hạn chế đươc việc hacker upload file shell hoặc các mã độc khác lên website của mình.

Full Code Upload:

1/ Controller Upload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
class Upload extends CI_Controller{
    public function __construct(){
        parent::__construct();
        $this->load->helper(array("form", "url"));
    }
     
    public function index(){
        $data['errors'] = '';
        $this->load->view("upload_view", $data);
    }
     
    public function doupload(){
        if($this->input->post("ok")){
            $config['upload_path'] = './uploads/';
            $config['allowed_types'] = 'gif|jpg|png';
            $config['max_size'] = '900';
            $config['max_width']  = '1024';
            $config['max_height']  = '768';
            $this->load->library("upload", $config);
            if($this->upload->do_upload("img")){
                echo 'Upload Ok';
                    $check = $this->upload->data();
                    echo "<pre>";
                    print_r($check);
                    echo "</pre>";
            }else{
                $data['errors'] = $this->upload->display_errors();
                $this->load->view("upload_view", $data);
            }
        }
    }       
}


2/ View:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$upload=array(
    "name" => "img",
    "size" => "25",
);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Freetuts.net</title>
</head>
 
<body>
    <?php
        if($errors != ""){
            echo $errors;
        }
        echo form_open_multipart(base_url()."index.php/upload/doupload");
        echo form_label("Avartar: ").form_upload($upload)."<br />";
        echo form_label(" ").form_submit("ok", "Upload");
        echo form_close();
    ?>
</body>
</html>

Kết thúc bài học:

Xem như chúng ta vừa tìm hiểu xong library upload trong CI, các bạn thấy thao tác của nó cực là basic và dễ sử dụng đúng không nào, ở bài tiếp theo chúng ta sẽ cùng nhau đi sâu vào việc kiểm soát việc resize hình ảnh, watermark cho hình, làm một lúc 3 thao tác là upload ảnh, resize ảnh, watermark. Còn bây giờ việc của các bạn là xoắn áo lên và gõ lại những gì mà tôi vừa trình bày ở trên, chúc các bạn học tốt và đừng quên ủng hộ freetuts bằng cách like & share nếu cảm thấy nội dung này hay và thật sự bổ ích, cảm on các bạn đã đọc hết bài viết này của tôi.