php - 使用 PHP 创建单个文件上传表单的最佳方法是什么?

标签 php upload file-upload

我在网上找到了一些示例,但我想从每天使用 PHP 的人那里获得关于潜在安全或性能注意事项及其解决方案的反馈。

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

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

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

最佳答案

文件上传教程

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>";
?>

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

打印 $_FILES 的值可以提示正在发生的事情。例如:

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

This structure gives some information as to the file's name, MIME type, size and error code.

Error Codes

0 Indicates that there was no errors and file has been uploaded successfully
1 Indicates that the file exceeds the maximum file size defined in php.ini. If you would like to change the maximum file size, you need to open your php.ini file, identify the line which reads: upload_max_filesize = 2M and change the value from 2M (2MB) to whatever you need
2 Indicates that the maximum file size defined manually, within an on page script has been exceeded
3 Indicates that file has only been uploaded partially
4 Indicates that the file hasn't been specified (empty file field)
5 Not defined yet
6 Indicates that there´s no temporary folder
7 Indicates that the file cannot be written to the disk

php.ini Configuration

When running this setup with larger files you may receive errors. Check your php.ini file for these keys:

max_execution_time = 30
upload_max_filesize = 2M

Increasing these values as appropriate may help. When using Apache, changes to this file require a restart.

The maximum memory permitted value (set via memory_limit) does not play a role here as the file is written to the tmp directory as it is uploaded. The location of the tmp directory is optionally controlled via upload_tmp_dir.

Checking file mimetypes

You should check the filetype of what the user is uploading - the best practice is to validate against a list of allowed filetypes. A potential risk of allowing any file is that a user could potentially upload PHP code to the server and then run it.

You can use the very useful fileinfo extension (that supersedes the older mime_content_type function) to validate mime-types.

// 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 的更多信息。 .

关于php - 使用 PHP 创建单个文件上传表单的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/198346/

相关文章:

asp.net-mvc - 如何在 asp.net mvc、web.config 文件中为特定位置设置 maxRequestLength 和 maxAllowedContentLength?

node.js - multer nodejs 模块 onFileUploadStart file.size 返回 0

javascript - Node.js 和 Multer - 在回调函数 (req,res) 中处理上传文件的目的地

php - 插入语句和状态下拉列表不起作用

javascript - 从 $.(ajax) 获取单选按钮值并将其传递到 SQL 查询中

php - 从 css 读取值

安卓图片上传: Use Activity or Service?

ios - 使用 PHP 在 Objective-C 中上传录制的音频文件

java - 将上传的文件保存在特定位置

php - 是否可以将汇编代码包含到 php 脚本中?