note 102043 deleted from reserved.variables.files by danbrown
| From: | danbrown@php.net | Date: | Tue, 25 Jan 2011 00:23:05 +0000 |
| Subject: | note 102043 deleted from reserved.variables.files by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-176269@lists.php.net to get a copy of this message | ||
Note Submitter: Luke Scott
----
The way $_FILES array is formatted is insane. The second level of the array always contains name,
type, tmp_name, error, and size.
Basically if you have <input type="file" name="upload" /> it will be
formatted as upload[name], upload[type], etc... If you have <input type="file"
name="upload[file]" /> it will be formatted as upload[name][file], upload[type][file],
etc...
Ideally it would be better to have the file represented by an object and merged into POST. I've
written a class that does this:
<?php
class Post
{
protected static $_request;
public static function Grab()
{
if(! isset(self::$request))
{
self::$_request = array_replace_recursive($_POST, self::_getFiles());
}
return self::$_request;
}
protected static function _getFiles()
{
$files = array();
$keys = array('name', 'type', 'tmp_name', 'error',
'size');
foreach($_FILES as $name => $file)
{
foreach($keys as $key)
{
if(is_array($file[$key]))
{
array_walk_recursive($file[$key], __CLASS__ . '::_walk_multi_file',
array('key' => $key,
'num' =>
&$num,
'objects' =>
&$objects));
$num = NULL;
}
else
{
$value = $file[$key];
if($key == 'name')
{
$file['name'] = ! empty($value) ? new FileUpload() : NULL;
}
if(isset($file['name']))
{
$file['name']->$key = $value;
}
}
}
unset($objects);
$files[$name] = $file['name'];
}
return $files;
}
protected static function _walk_multi_file(&$v, $k, $data)
{
$value = $v;
if($data['key'] == 'name')
{
$v = $data['objects'][$data['num']] = ! empty($value) ? new FileUpload :
NULL;
}
if(isset($data['objects'][$data['num']]))
{
$data['objects'][$data['num']]->$data['key'] = $value;
}
$data['num']++;
}
}
class FileUpload
{
public $name;
public $type;
public $tmp_name;
public $error;
public $size;
public function __toString()
{
return (string)$this->name;
}
}
if(! function_exists('array_replace_recursive'))
{
function array_replace_recursive()
{
$arrays = func_get_args();
$original = array_shift($arrays);
if(! is_array($original))
{
return array();
}
foreach($arrays as $array)
{
if(is_array($array))
{
foreach($array as $key => $value)
{
if(isset($original[$key]) AND is_array($original[$key]) AND is_array($value))
{
$original[$key] = array_replace_recursive($original[$key], $value);
}
else
{
$original[$key] = $value;
}
}
}
}
return $original;
}
}
?>
Note that if a file isn't uploaded the corresponding key will be set to NULL.