使用PHP创建单文件上载表单的最佳方法是什么?

时间:2008-10-13 17:30:33

标签: php upload file-upload

我在网上找到了一些样本,但我想得到每天使用PHP的人的反馈,以了解潜在的安全性或性能考虑因素及其解决方案。

请注意,我只对一次上传单个文件感兴趣。

理想情况下,不需要浏览器插件(Flash / Java),尽管了解使用插件的好处会很有趣。

我想知道最好的HTML表单代码和PHP处理代码。

4 个答案:

答案 0 :(得分:33)

文件上传教程

HTML

<form enctype="multipart/form-data" action="action.php" method="POST">
  <input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
  <input name="userfile" type="file" />
  <input type="submit" value="Go" />
</form>
  • action.php是将处理上传的PHP文件的名称(如下所示)
  • MAX_FILE_SIZE必须出现在输入之前,类型为file。这个值很容易在客户端上操作,所以不应该依赖它。它的主要好处是在用户上传之前向用户提供文件过大的早期警告。
  • 您可以使用类型file更改输入的名称,但请确保它不包含任何空格。您还必须更新PHP文件中的相应值(如下所示)。

PHP

<?php
$uploaddir = "/www/uploads/";
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "Success.\n";
} else {
    echo "Failure.\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";
?>

上传到文件夹不应位于可通过HTTP访问的位置,否则可以上传PHP脚本并在服务器上执行。

打印$_FILES的值可以提示发生了什么。例如:

    Array
    (
        [userfile] => Array
        (
            [name] => Filename.ext
            [type] => 
            [tmp_name] => 
            [error] => 2
            [size] => 0
        )
    )

此结构提供了有关文件名,MIME类型,大小和错误代码的一些信息。

错误代码

  

0表示没有错误,文件已成功上传
  1表示该文件超过了php.ini中定义的最大文件大小。如果要更改最大文件大小,则需要打开php.ini文件,标识读取的行:upload_max_filesize = 2M并将值从2M(2MB)更改为您需要的任何内容   2表示已超出页面脚本中手动定义的最大文件大小   3表示文件仅部分上载了
  4表示尚未指定文件(空文件字段)
  5尚未定义
  6表示没有临时文件夹
  7表示无法将文件写入磁盘

php.ini配置

使用较大的文件运行此设置时,您可能会收到错误。检查php.ini文件中的这些键:

max_execution_time = 30
upload_max_filesize = 2M

适当增加这些值可能会有所帮助。使用Apache时,需要重新启动对此文件的更改。

最大内存允许值(通过memory_limit设置)在此处不起作用,因为文件在上载时写入tmp目录。可选择通过upload_tmp_dir控制tmp目录的位置。

检查文件mimetypes

您应该检查用户上传内容的文件类型 - 最佳做法是根据允许的文件类型列表进行验证。允许任何文件的潜在风险是用户可能将PHP代码上传到服务器然后运行它

您可以使用非常有用的fileinfo扩展名(取代旧的mime_content_type功能)来验证mime类型。

// FILEINFO_MIME set to return MIME types, will return string of info otherwise
$fileinfo = new finfo(FILEINFO_MIME);
$file = $fileinfo->file($_FILE['filename']);

$allowed_types = array('image/jpeg', 'image/png');
if(!in_array($file, $allowed_types))
{
    die('Files of type' . $file . ' are not allowed to be uploaded.');
}
// Continue

更多信息

您可以在PHP.net manual上阅读有关处理文件上传的更多信息。

对于PHP 5.3 +

//For those who are using PHP 5.3, the code varies.
$fileinfo = new finfo(FILEINFO_MIME_TYPE);
$file = $fileinfo->file($_FILE['filename']['tmp_name']);
$allowed_types = array('image/jpeg', 'image/png');
if(!in_array($file, $allowed_types))
{
    die('Files of type' . $file . ' are not allowed to be uploaded.');
}
// Continue

更多信息

您可以在PHP.net documentation了解有关FILEINFO_MIME_TYPE的更多信息。

答案 1 :(得分:5)

阅读this introduction,告诉您需要知道的一切。用户评论也非常有用。

答案 2 :(得分:4)

Flash的主要优点是它允许您上传多个文件。 Java的主要优点是它允许从文件系统中拖放。很抱歉没有回答中心问题,但我认为我会把它扔进去,因为它很简单。

答案 3 :(得分:3)

在文件上传方面,安全性是一件非常重要的事情,在uploads文件夹中添加.htaccess会停止从中运行脚本,这样可以方便地添加额外的安全层。

的.htaccess

Options -Indexes
Options -ExecCGI
AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi 

参考:http://www.mysql-apache-php.com/fileupload-security.htm