📜 ⬆️ ⬇️

Strange $ _FILES or “the problem of using array syntax in fields of type file”

I have always been tormented by the question of why the $ _FILES array in PHP is arranged this way, or rather, why it forms it in a very strange way. In case the form field names are decorated using the array syntax, $ _REQUEST, $ _GET or $ _POST will contain the correct representation, but ... such use is not suitable for $ _FILES!

Problem

We have the form:
<form action="" method="post" enctype="multipart/form-data"> <input type="file" name="oneLevel[]"> <input type="file" name="oneLevel[]"> <input type="submit"> </form> 

When uploading files through this form, we get the $ _FILES array of the following form:
 array( 'files' => array ( 'name' => array ( 0 => 'Lighthouse.jpg', 1 => 'Hydrangeas.jpg', ), 'type' => array ( 0 => 'image/jpeg', 1 => 'image/jpeg', ), 'tmp_name' => array ( 0 => '/tmp/phpQR67Qp', 1 => '/tmp/phpJjnAHA', ), 'error' => array ( 0 => 0, 1 => 0, ), 'size' => array ( 0 => 561276, 1 => 595284, ), ), ) 

To me, this “feature” in most cases does not fit and seems illogical. The simplest solution is to use simple (string) names for file-type fields, for example file_0, file_1, ..., file_N, but this is not so convenient. If, after all, you are interested in solving this problem - read on ...

Decision

In the autoprepend file or anywhere during the initialization of your application, it is worth processing the $ _FILE array as follows:
 /** *      * * @param array $arrayForFill   . *     "" *  $_FILES * @param string $currentKey    * @param mixed $currentMixedValue    * @param string $fileDescriptionParam     * (name, type, tmp_name, error  size) * @return void */ function rRestructuringFilesArray(&$arrayForFill, $currentKey, $currentMixedValue, $fileDescriptionParam) { if (is_array($currentMixedValue)) { foreach ($currentMixedValue as $nameKey => $mixedValue) { rRestructuringFilesArray($arrayForFill[$currentKey], $nameKey, $mixedValue, $fileDescriptionParam); } } else { $arrayForFill[$currentKey][$fileDescriptionParam] = $currentMixedValue; } } // ,     "" $_FILES $arrayForFill = array(); //      foreach ($_FILES as $firstNameKey => $arFileDescriptions) { //        , //        foreach ($arFileDescriptions as $fileDescriptionParam => $mixedValue) { rRestructuringFilesArray($arrayForFill, $firstNameKey, $_FILES[$firstNameKey][$fileDescriptionParam], $fileDescriptionParam); } } //  $_FILES   $_FILES = $arrayForFill; 

As a result, we have a more “logical” miss:
 array( 'files' => array ( 0 => array ( 'name' => 'Lighthouse.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpKNqlsc', 'error' => 0, 'size' => 561276, ), 1 => array ( 'name' => 'Hydrangeas.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpB8X3E8', 'error' => 0, 'size' => 595284, ), ), ) 

I posted this decision in the official documentation comment, because There are many questions, but there is no concrete example. But, at the time of its publication, it has not yet appeared there (I don’t know if it will appear?).

Thank you for your attention, I hope someone will come in handy.
')
UPD: Looking at how my words “In the autoprepend file or somewhere during the initialization of your application, it is worth processing the $ _FILE array” and overwriting the $ _FILES code in the code caused some indignation of some part of the community, I declare: this is an example of You can implement the necessary functionality, and I do not urge to use this code "as is" in combat projects.

Source: https://habr.com/ru/post/133072/


All Articles