superglobal validation

2

I'm developing a class to support multiple uploads using the Codeigniter framework and I've decided to parse my code using some online tools.

One of these was code climate ; I noticed that when checking the reports for code improvement it says that it is not recommended to use superglobals such as $_FILES even in functions specific to the validation, for example;

public function hasFile($key)
{
   if (!isset($_FILES[$key]) {
       throw new Exception("Não existe o indice $key", 1);
   }
   return TRUE;
}

I tried to change this by creating an attribute called key

public $key = 'userFile';

And call it within functions

if (!isset($_FILES[$this->key]) {.....

But I keep getting the report that this is not a good practice! I also looked in the PHP documentation if there is any superglobal filter type $_FILES using the function filter_input and also not found.

What would be the best way to validate the superglobal $_FILES ?

print the report;

In the function in question I do not assign the super-global to any variables, I just perform the validation as in the example above.

    
asked by anonymous 09.08.2016 / 16:04

3 answers

3

Looking at the question, it looks like you want to use a class to be able to apply upload operations.

I would recommend you in such cases do not actually use $_FILES within the class. Because, to that end, there would be no need for the methods to be dynamic, but static.

A good example I always like to use is Symfony , which in its source codes, the Request , Response or UploadedFile class are only entities that aim to treat the data, regardless of how with which they come - which in their case would be through the variable $_FILES .

What Symfony actually does is create a static method that initializes a new instance, based on global elements. So yes, I think it's something more organized, not dependent on just having uploads coming from $_FILES - you could add file_get_contents('php://input') for example.

So in this context, I suggest creating the following static method for instance creation:

class Upload
{
    protected $files = [];

    public function __construct(array $files)
    {
        $this->files = $files;
    }

    public function hasFile($key)
    {
        return isset($this->files[$key]);
    }

    public function getFile($key)
    {
        if ($this->hasFile($key)) {
            return $this->files[$key];
        }

        throw new Exception("Não existe o arquivo $key");
    }


    public static function createFromFilesGlobal()
    {
        return new static($_FILES);
    }
}

So the use would be:

 $files = Upload::createFromFilesGlobals();


 $files->getFile('key');

Note that, in this case, createFromFilesGlobals is a static method - the opposite of dynamic. This method has the purpose of only returning new static , passing as parameter the global variable $_FILES . This will cause a Upload instance to be returned, with the $files property filled with the $_FILES values.

Now, imagine if you want to use this same class to capture some kind of request that might not be passed through $_FILES of PHP. What would be the solution?

Fictitious example:

 // essa função não existe no PHP, é só um exemplo
 $raw_files = parse_uploaded_files_from_php_raw_input('php://input'); 

 $files = new Upload($raw_files);

So, in this way, you have a class that is not limited by a global super variable of PHP, but that only uses its values (or not), if necessary.

    
09.08.2016 / 16:52
1

In programming, in the part of the time (ideally) you should not treat or change external elements within a function, that is, function or method should not be assigned that is not passed as an argument or belongs to the class.

This 'rule' is more or less what your mother said does not accept anything from strangers, this includes variables or objects: P

Remember that this rule can change as the language can be more or less rigid, eg javascript, a function does not access N external elements?

I think the solution to remove this warning is to pass $_FILES to the constructor of your class and always change / return that copy.

    
09.08.2016 / 16:12
1

In the code you submitted there is no bad practice.

A bad practice would be if you were sanitizing or filtering the superglobal data.

Example of what would be a bad practice:

$_POST['foo'] = mysql_real_escape_string($_POST['foo']);

In the case of isset() , there is no change in value. There's nothing wrong with using it that way.

if (isset($POST['foo'])) {
    // bla bla bla
}

In the examples I used $ _POST, however, the same applies $ _GET, $ _FILES, $ _SERVER, in short, the superglobals: link

    
09.08.2016 / 16:13