Bài 16: Upload file trong PHP

Để có thể upload được một file hoặc nhiều file chúng ta cần có: Form phải chỉ định thuộc tính enctype="multipart/form-data" Thẻ Input field có thuộc tính type="file" Để có thể upload được nhiều file bạn có thể thiết lập thêm thuộc tính multiple="multiple" ...

Để có thể upload được một file hoặc nhiều file chúng ta cần có:

  • Form phải chỉ định thuộc tính enctype="multipart/form-data"
  • Thẻ Input field có thuộc tính type="file"
  • Để có thể upload được nhiều file bạn có thể thiết lập thêm thuộc tính multiple="multiple"
  • Một file xử lý upload server-slide e.g upload.php
  • Một folder chứa các file được upload. e.g /upload (CHMODE 0777)

Sau đây chúng ta sẽ tạo 1 form để thực hiện chức năng upload file lên.

<table awidth="500" border="0" cellpadding="0" cellspacing="1">
  <tr>
    <form action="upload.php" method="post" enctype="multipart/form-data">
    <td>
        <table awidth="100%" border="0" cellpadding="3" cellspacing="1">
            <tr>
                <td style="background:#CCC">
                    <strong>Upload File </strong>
                </td>
            </tr>
            <tr>
                <td>Lựa chọn file
                  <input name="ufile" type="file" id="ufile" size="50" />
                </td>
            </tr>
            <tr>
                <td align="center">
                    <input type="submit" name="submit" value="Upload" />
                </td>
            </tr>
        </table>
    </td>
    </form>
  </tr>
</table>

Các bạn thấy form trên có thuộc tính action="upload.php",như vậy khi form được submit toàn bộ dữ liệu trong form sẽ được gửi tới trang upload.php theo phương thức POST Bây giờ chúng ta sẽ thực hiện viết code xử lý dữ liệu trong file upload.php như sau:

if(isset($_POST['submit'])){
   //thực hiện upload
}else{
   echo "Vui lòng chọn hình ảnh trước";
}

Trong PHP Hàm isset() là hàm kiểu tra sự tồn tại của biến nào đó, Với đoạn code trên trước tiên chúng ta cần kiểm tra xem người dùng đã ấn nút submit chưa thông qua câu điều kiện isset($_POST['submit'])

Khi thực hiện upload hệ thống sẽ tự sinh ra 1 biến môi trường có tên là $_FILES[‘image'] ,đây là biến chứa mảng thông tin của file upload lên nó bao gồm các thông tin sau:

  • $_FILES['image']['name']: Tên file mà người dùng chọn để uploads
  • $_FILES['image'][‘tmp_name']: Tên file tạm khi một file được chọn để upload thường chúng đu
  • $_FILES['image']['type']: Kiểu của file,dựa vào biến này để kiểm tra các file được phép tải lên
  • $_FILES['image']['size']: kích thước của file (byte),dựa vào biến này để kiểm tra dung lượng tối đa được phép tải lên

Nhân tiện mình sẽ nêu ra một số phương pháp xác định loại file. 

1.Hàm pathinfo()

$file = 'http://example.com/imgs/attachments.gif';
$info = pathinfo($file);
$extension = $info['extension']; // gif
$filename = $info['filename']; //attachments.gif 
$basename = $info['basename']; //attachments

2. Hàm strrchr() và substr

Hàm này trả về một con trỏ tới sự xuất hiện cuối cùng của ký tự trong str. Nếu giá trị không được tìm thấy, hàm trả về một con trỏ NULL.

Cú pháp: strrchr(string $haystack, $needle)

$file = 'http://example.com/imgs/atta...chments.gif';
$ret = strrchr($file,'.');
$extension = strtolower(substr($ret,1));
print_r($extension); die(); // gif

3. Sử dụng hàm explode() và hàm end()

Trong các bài trước mình đã nói về hàm explode() và hàm end() rồi. Các bạn có thể xem lại tại Các hàm xử lý chuỗi trong php

  • Hàm end(array &array): Hàm này trả về phần tử mảng cuối cùng trong mảng truyền vào.
  • Hàm reset(array &array): Hàm này trả về phần tử mảng đầu tiên trong mảng truyền vào.
$file = 'http://example.com/imgs/atta...chments.gif';
$ret = explode('.',$file);
print_r(end($ret)); die(); // Kết quả: gif

Tiếp tục với chủ đề trên.

Việc xử lý tiền upload file cũng rất quan trọng và có một số lý do sau đây:

  • Chỉ định loại file được upload.
  • Chỉ định kích thước file được phép upload.

Chú ý: Form upload file là nơi để hacker dễ dàng khai thác lỗ hỏng nhằm upload shellscript lên trên webserver. Vì vậy chúng ta cần kiểm tra kỹ định dạng file trước khi di chuyển nó sang thư mục được chỉ định trên website.

- Để thực hiện kiểm tra điều kiện file tải lên chỉ là file ảnh ta có thể dựa vào biến $_FILES['image']['type'] và kiểm tra như sau.

if($_FILES['file']['type'] == "image/jpeg"
  || $_FILES['file']['type'] == "image/png"
  || $_FILES['file']['type'] == "image/gif"){
  // là file ảnh
  // Thực hiện upload
}else{
  // không phải file ảnh
  echo "Kiểu file không hợp lệ";
}

- Để thêm điều kiện giới hạn dung lượng tối đa của file upload lên ta dựa vào biến $_FILES['image']['size'] và sẽ kiểm tra như sau.

Giả sử tôi chi cho phép người dùng upload nên các file có kích thước tối thiểu là 2MB. (2MB = 2*1024 kb * 1024 bytes = 2097152))

if($_FILES['file']['size'] > 2097152){
 echo "File không được lớn hơn 2mb";
}else{
 //dung lượng hợp lệ,thực hiện code upload
}

Trong PHP để có thể upload một file nên server-side bạn có thể sử dụng một trong các hàm và phương pháp sau.

  • Hàm move_uploaded_file($filename, $dest)
  • Hàm copy($resouce, $dest)
  • Hàm file_put_contents($filename,$data)
  • Các hàm FTP

1. move_uploaded_file($filename, $dest)

if(isset($_POST['submit'])){
    $upload_path = dirname(__FILE__).'/uploads/';
    if(!is_null($_FILES['ufile']['name'])){ // Kiểm tra xem người dùng chọn file chưa
        $name = $_FILES['ufile']['name']; // File name
        $tmp_name = $_FILES['ufile']['tmp_name']; // File tạm
        $type = $_FILES['ufile']['type']; // Kiểu file
        $size = $_FILES['ufile']['size']; // Kích thước file
        
        $valid = 1;
        if($type='image/jpeg' 
        || $type=='image/gif' 
        || $type=='image/png'){ // Kiểm tra kiểu file
            if($size 
0