We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

File Validation

Hi, I send some files from client (Vue Js) to Api (Phalcon) by multipart/form-data header and when I'm using file validation I'm getting "Field files must not be empty" error.

What is wrong ?

My sent data: files[0]: (binary) files[1]: (binary)

My code in phalcon:

    <?php
    $validation = new Validation();
    $fileValidator = new File([
        "maxSize"              => "2M",
        "messageSize"          => ":field exceeds the max filesize (:max)",
        "allowedTypes"         => [
            "image/png",
        ],
        "messageType"          => "Allowed file types are :types",
        "maxResolution"        => "800x600",
        "messageMaxResolution" => "Max resolution of :field is :max",
    ]);

    $validation->add('files', $fileValidator);
    $messages = $validation->validate($_FILES);

    $data['ok'] = false;
    if (count($messages)) {
        foreach ($messages as $message) {
            $data['message'][] = $message->getMessage();
        }
        return $this->setResponse(400, $data);
    }

output of $_FILES by var_dump:

array(1) { ["files"]=> array(5) { ["name"]=> array(2) { [0]=> string(7) "158.jpg" [1]=> string(12) "100_1237.JPG" } ["type"]=> array(2) { [0]=> string(10) "image/jpeg" [1]=> string(10) "image/jpeg" } ["tmp_name"]=> array(2) { [0]=> string(24) "E:\xampp\tmp\php4D63.tmp" [1]=> string(24) "E:\xampp\tmp\php4D93.tmp" } ["error"]=> array(2) { [0]=> int(0) [1]=> int(0) } ["size"]=> array(2) { [0]=> int(1099386) [1]=> int(1283710) } } }


739
public function uploadAttachments() {
        $uploads     = $this->request->getUploadedFiles();
        $attachments = [];

        #do a loop to handle each file individually
        foreach ( $uploads as $upload ) {
            // Checks whether the file has been uploaded via Post.
            if ( ! $upload->isUploadedFile() ) {
                continue;
            }

            // do real upload to local sever and save to cloud such s3/aliyun oss etc.
            // and return a Attachments model instance included all uploaded file's info
            // such as file name, local path, cloud path, file size, md5, file metadata etc.
            $attachment = $this->uploadFile( $upload );

            if ( $attachment ) {
                $attachments[] = $attachment->toArray( [ 'id', 'url' ] );
            }
        }

        return [
            'ApiStatus' => 201,
            'message'   => 'All files uploaded successfully',
            'data'      => $attachments,
        ];
    }

Where is file validation ?!!!

my challange is file validation.

public function uploadAttachments() {
      $uploads     = $this->request->getUploadedFiles();
      $attachments = [];

      #do a loop to handle each file individually
      foreach ( $uploads as $upload ) {
          // Checks whether the file has been uploaded via Post.
          if ( ! $upload->isUploadedFile() ) {
              continue;
          }

          // do real upload to local sever and save to cloud such s3/aliyun oss etc.
          // and return a Attachments model instance included all uploaded file's info
          // such as file name, local path, cloud path, file size, md5, file metadata etc.
          $attachment = $this->uploadFile( $upload );

          if ( $attachment ) {
              $attachments[] = $attachment->toArray( [ 'id', 'url' ] );
          }
      }

      return [
          'ApiStatus' => 201,
          'message'   => 'All files uploaded successfully',
          'data'      => $attachments,
      ];
  }

$_FILES 是一个二维数组, 你可以使用 foreach 来进行验证 。 请参考文档 https://docs.phalcon.io/3.4/zh-cn/request



1.6k
Accepted
answer

I've solved this problem by create a new array($fileData) from $_FILES:

    $files = $_FILES['files'];

    foreach($this->request->getUploadedFiles() as $index => $file) {
                $fileData['file'] = [
                    'name'     => $files['name'][$index],
                    'type'     => $files['type'][$index],
                    'tmp_name' => $files['tmp_name'][$index],
                    'error'    => $files['error'][$index],
                    'size'     => $files['size'][$index],
                ];

                $validation = new Validation();
                $validation->add('file', new File([
                    "maxSize"      => "10M",
                    "messageSize"  => ":field exceeds the max filesize (:max)",
                    "allowedTypes" => [
                        "image/png",
                        "image/jpeg",
                        "video/mp4",
                    ],
                    "messageType" => "Allowed file types are :types",
                ]));

                $messages = $validation->validate($fileData);

                $data['ok'] = false;

                if (count($messages)) {
                    foreach ($messages as $message) {
                        $data['message'][] = $message->getMessage();
                    }
                    return $this->response->setJsonContent($data);
                }

                // Then upload
        }