codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.35k stars 1.9k forks source link

Bug: `hasFile()` with no file return true #5503

Closed totoprayogo1916 closed 2 years ago

totoprayogo1916 commented 2 years ago

PHP Version

7.4

CodeIgniter4 Version

4.1.5

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

cli-server (PHP built-in webserver)

Database

No response

What happened?

hasFile() always returns true even if no file is selected

Steps to Reproduce

Controller (Home.php)

<?php

namespace App\Controllers;

use CodeIgniter\HTTP\Files\FileCollection;

class Home extends BaseController
{
    public function index()
    {
        helper('form');
        return view('form');
    }

    public function upload()
    {
        $coll = new FileCollection();
        var_dump($_FILES);
        var_dump($this->request->getFile('file'));
        var_dump($coll->hasFile('file'));
    }
}

This my view (form.php)

<?= form_open_multipart('home/upload') ?>
<?= form_upload('file') ?>
<?= form_button(['type' => 'submit', 'content' => 'upload']) ?>
<?= form_close() ?>

Then click upload with no file selected.

The result is like: image

Expected Output

hasFile() should return false if no files were submitted.

Anything else?

No response

kenjis commented 2 years ago

I've confirmed this behavior.

But I'm not sure hasFile() should return false if no files were submitted.

Because $this->files in FileCollection represents $_FILES, and if hasFile() returns false, there is no way to get the $_FILES data. As you see there is $_FILES.

array (size=1)
  'file' => 
    array (size=5)
      'name' => string '' (length=0)
      'type' => string '' (length=0)
      'tmp_name' => string '' (length=0)
      'error' => int 4
      'size' => int 0
totoprayogo1916 commented 2 years ago

so, we have to check with similar $_FILES['file']['name'] === ''? whereas we have the hasFile() function.

kenjis commented 2 years ago

@totoprayogo1916 What do you want to do? Do you need to use hasFile()?

AkinOlawale commented 2 years ago

What you can do is to check the error array key.

if (isset($_FILES['file']['error']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
   //we have a file
}

Reference: https://www.php.net/manual/en/features.file-upload.errors.php

Might be worth it to update the hasFile() function to check for valid file. Or create a new function entirely to avoid this "bug"

kenjis commented 2 years ago

There is already isValid() in UploadedFile. https://codeigniter.com/user_guide/libraries/uploaded_files.html?highlight=isvalid#verify-a-file

AkinOlawale commented 2 years ago

Oh I didn't see that. Thanks for pointing that out. I'm new to the framework and would like to start contributing.. I guess I need to install the framework and see what's happening. But thanks for the clarification.

kenjis commented 2 years ago

@AkinOlawale If you would like to contribute, I recommend you read the current in-progress User Guide https://codeigniter4.github.io/CodeIgniter4/ and the CI4 source code.