Việc kiểm tra mime type, file size... của file upload trong CakePHP 2.x có thể được thực hiện khá đơn giản bằng việc định nghĩa rule validate như sau: ``` php public $validate = array( 'file' => array( 'mimeType' => array( 'rule' => array('mimeType', array('image/gif', 'image/png')), 'message' => 'Mime type is invalid', ), 'fileSize' => array( 'rule' => array('fileSize', '<=', '1MB'), 'message' => 'File size is too big', ), ), ) ``` Nếu ô input upload file trong form là bắt buộc (required) thì với rule như trên hoàn toàn không có vấn đề gì. Tuy nhiên, nếu input upload file là tùy chọn, nghĩa là user có thể upload file hoặc không, thì trong trường hợp user không chọn file khi gửi form lên server, rule trên sẽ sinh ra lỗi tại bước check `mimeType` như sau: ``` php Can not determine the mimetype ``` Nguyên nhân là do không có file nào được upload lên, nên module `php_fileinfo` của PHP không thể tìm được mime type cần check. Thông thường, đối với những input kiểu text hay checkbox, radio..., để bỏ qua không thực hiện validate rule nếu input đó trống, chúng ta có thể thêm tùy chọn `'allowEmpty' => true` vào rule đầu tiên của input đó như bên dưới. Với tùy chọn này, cakePHP sẽ dùng hàm `empty` để check xem input đó có trống hay không, nếu không trống mới thực hiện các validate rule liên quan đến input đó. ``` php public $validate = array( 'name' => array( 'format' => array( 'allowEmpty' => true, // Bỏ qua rule nếu input empty 'rule' => '/^[a-b0-9]+$/i', 'message' => 'Name is invalid', ), 'maxLength' => array( 'rule' => array('maxLength', 20), 'message' => 'Name is too long', ), ), ) ``` Tuy nhiên, do file input sau khi được upload lên server sẽ được PHP quản lý dưới dạng một array có cấu trúc như bên dưới, nên khi định nghĩa validate rule cho file input cho dù có thêm tùy chọn `allowEmpty => true` thì hàm `empty` sẽ luôn trả về `false`, do đó validate rule sẽ luôn được thực hiện. ``` php // Cấu trúc của $this->request->data array( 'item1' => , 'item2' => , //... 'file' => array( 'name' => '', 'type' => '', 'size' => 0, 'tmp_name' => '', 'error' => 4 // 4: Không có file nào được upload lên ) ); ``` Vì vậy, để không xuất hiện lỗi ở bước validate mimeType nếu user không chọn file upload nào cả, trước khi tiến hành validate, chúng ta cần thêm một bước check xem có file nào được upload lên không. Nếu không có file nào được upload lên thì cần xóa field của file input ra khỏi array data chuẩn bị validate. Tất cả các xử lý này có thể được thực hiện trong callback `beforeValidate` như sau: ``` php public function beforeValidate($options = array()) { // Dùng reference để rút ngắn lại tên biến $data =& $this->data[$this->alias]; // Dùng Hash::get để không bị lỗi nếu key 'file' không tồn tại trong $data if (Hash::get($data, 'file.error') == UPLOAD_ERR_NO_FILE) { unset($data['file']); } parent::beforeValidate($options); return true; } ```