【问题标题】:MAX_FILE_SIZE in PHP - what's the point?PHP 中的 MAX_FILE_SIZE - 有什么意义?
【发布时间】:2009-09-04 20:22:33
【问题描述】:

我试图制作一个文件上传表单并检查了 PHP 文档以刷新我对该主题的记忆。 Here is a link to the relevant article.突然看到这条信息:

MAX_FILE_SIZE 隐藏字段(以字节为单位)必须在文件输入字段之前,其值是 PHP 接受的最大文件大小。应始终使用此表单元素,因为它为用户节省了等待传输大文件却发现文件太大而传输失败的麻烦。请记住:在浏览器端欺骗此设置非常容易,因此切勿依赖此功能阻止更大大小的文件。它只是为应用程序客户端的用户提供的便利功能。然而,最大尺寸的 PHP 设置(在服务器端)不能被愚弄。

好的……说什么?首先它告诉它必须在文件上传字段之前。然后它告诉我们这只是为了方便。此外 - 它无论如何都在客户端,所以任何人都可以弄乱它。谷歌搜索后,我还发现没有已知的浏览器支持它。

WTF?如果文件上传字段似乎(出于所有意图和目的)绝对没有意义,为什么说它必须在文件上传字段之前?我应该把它放在我的 HTML 中吗?

【问题讨论】:

  • Vilx - 我对它如何工作的假设似乎是错误的。您能否对其进行测试并让我知道是否实际发布了大于max_file_size 的文件?我有兴趣被发现错了!
  • 当然是!至少在我的 WinXP SP3 + Apache 2.2 + PHP 5 上。PHP 也无法阻止它 - 它最多只能关闭连接(即使是那么多),但它无法提供任何对用户完全错误。
  • @Vilx - 谢谢 - 最有趣的!
  • 关于must precede the file input field,我认为这只是意味着如果您决定包含该字段,则它必须位于相关输入字段之前。
  • @Sebas,多么随意的限制。如果我们要上传多个文件怎么办? No wonder browsers don't support it,连设计都不好。

标签: php


【解决方案1】:

在尝试查找有关 MAX_FILE_INFO 的任何权威信息失败后,我决定采取严厉措施 - 并查看 PHP 的神圣来源。

我使用 grep 递归扫描了整个 PHP 源代码:

grep -ri MAX_FILE_SIZE .

唯一提到这个变量的地方是(不包括测试文件夹) - rfc1867.c 文件。 完全可以预料,因为 rfc1867 标准处理文件上传。

相关C代码:

......
if (!strcasecmp(param, "MAX_FILE_SIZE")) {                                                                                                                                                                              
   max_file_size = atol(value);
}
......
......
if (PG(upload_max_filesize) > 0 && (total_bytes+blen) > PG(upload_max_filesize)) {
    cancel_upload = UPLOAD_ERROR_A;
} else if (max_file_size && ((total_bytes+blen) > max_file_size)) {
    cancel_upload = UPLOAD_ERROR_B;
} else if
....

所以 - 这是上述代码的简短说明

1) 首先我们将 MAX_FILE_SIZE 的值放入 max_file_size 变量中。

2) 然后我们检查是否存在 max_file_size 值,以及是否已经接受的字节的总和 (total_bytes) + 缓冲区中的字节大小 (blen) 超过 max_file_size。

3) 如果 2 为真 - 此时我们取消上传,并使用此常量设置的一些错误代码:UPLOAD_ERROR_B

但是 - 正如你所看到的 - 在检查 max_file_size 变量之前 - PHP 对 upload_max_filesize 变量执行完全相同的检查! 所以 - 我们有它。

结论: 恕我直言 - 操作是正确的 - 将 MAX_FILE_SIZE 包含到您的表单中是 0 点!只需在 php.ini 文件中设置 upload_max_filesize 或通过 ini_set() 动态设置。

【讨论】:

  • 请注意:您不能使用 ini_set 设置 upload_max_filesize!
  • 我把它读成,“这个 HTML 表单处理的扩展是为了限制上传超大文件的尝试。这个想法是 浏览器 甚至不会 如果文件太大,则开始上传。不幸的是,目前很少有(如果有的话)浏览器遵循此扩展/指令,但未来可能会有更多的浏览器这样做。最后,它很容易被欺骗,所以不要'不要指望它(检查服务器端)。”阅读准确吗?
  • @PhilPerry,除了浏览器根本没有计划支持此功能。我没有看到RFC1867 在任何地方提到MAX_FILE_SIZE这只是 PHP 的发明吗?
  • 唯一真正的答案。
  • 感谢您为这个问题提供可靠的答案。我今天浪费了一个多小时阅读人们对这个功能如何工作的幻想。
【解决方案2】:

目前没有浏览器真正关心 MAX_FILE_SIZE 指令,所以它毫无意义。我想它确实可以让您更精细地控制上传时的最大尺寸(如上面的海报所述),而不是使用 php.ini,但我个人只是忽略它,您可能也应该这样做。它当然不会阻止用户上传比要求更大的文件 - 手册在这方面相当具有误导性。

【讨论】:

  • 它不是为了安全——它是为了用户体验。 “它省去了用户等待一个大文件被传输却发现它太大而传输失败的麻烦。”它也不适用于浏览器——如果在检查 max_file_size 后设置了cancel_upload,请参阅 PHP 源代码stops reading from the buffer
【解决方案3】:

在我们找到支持它的浏览器之前,客户端方面没有意义。

但是,在服务器方面,MAX_FILE_SIZE确实会影响您从$_FILES['your_file'] 获得的值。

假设浏览器的请求实际上是通过post_max_size,通常这是PHP给出的:

array(5) {
    ["name"]=> string(11) "my_upload.dll"
    ["type"]=> string(24) "application/x-msdownload"
    ["tmp_name"]=> string(26) "C:\WINDOWS\Temp\php86A.tmp"
    ["error"]=> int(0) // UPLOAD_ERR_OK
    ["size"]=> int(238592)
}

但如果上传的文件大小超过MAX_FILE_SIZE,你会看到:

array(5) {
    ["name"]=> string(11) "my_upload.dll"
    ["type"]=> string(0) ""
    ["tmp_name"]=> string(0) ""
    ["error"]=> int(2) // UPLOAD_ERR_FORM_SIZE
    ["size"]=> int(0)
} 

MAX_FILE_SIZE 必须在文件输入字段之前”部分不是开玩笑。它确实有效,因为 PHP 将按顺序解释浏览器的 POST 请求负载:

<input name=F1 type=file> 
<input name=F2 type=file>
F1 and F2 will not be affected by MAX_FILE_SIZE

<input name=MAX_FILE_SIZE value=1024 type=hidden>
<input name=F3 type=file>
<input name=F4 type=file>
F3 and F4 will have MAX_FILE_SIZE = 1024 bytes

<input name=MAX_FILE_SIZE value=0 type=hidden>
<input name=F5 type=file>
<input name=F6 type=file>
F5 and F6 will have MAX_FILE_SIZE = 0 (infinite)

<input name=MAX_FILE_SIZE value=1 type=hidden>
<input name=F7 type=file> 
<input name=F8 type=file>
F7 and F8 will have MAX_FILE_SIZE = 1 byte

另请注意,PHP 不区分大小写地解释 MAX_FILE_SIZE,因此 maX_fILe_sIZEMax_File_SIZE 也可以工作。

【讨论】:

  • @Vilx-,不,我只是在页面中添加一些有用的信息,因为前两个答案并不完整。
  • 欣赏,刚刚偶然看到这篇文章。
【解决方案4】:

我认为关键在于,在用户选择的文件太大的情况下,符合标准的浏览器会阻止表单提交,这样他们就不必执行至少部分上传(这可能需要一段时间)将被拒绝的文件。

在服务器端,PHP 仍然会检查并强制执行 PHP.ini 中设置的各种限制,并且会以正常方式引用上传过大的事实,即 $_FILES 中设置的错误代码。您可能会认为该字段类似于 JavaScript 验证 - 我们可能会为用户的方便进行快速的客户端检查,但我们仍然会进行适当的服务器端测试并对所有请求强制执行。

正如其他人所说,似乎没有任何浏览器实际上会费心执行此检查,因此它相对没用。

【讨论】:

  • 实际上,除了 PHP 自己的文档之外,它甚至没有在任何标准中,所以难怪没有浏览器甚至插件实现了这一点。在这里查看:bugs.php.net/bug.php?id=40387
  • 确实如此。我使用该文档范围内的“符合”一词。
【解决方案5】:

接下来是我错了,请阅读其他更明智、更准确的答案 (AFAIK)。

我认为这正是它所说的:

此表单元素应始终 使用,因为它为用户节省了麻烦 等待一个大文件 转移才发现它是 太大,传输失败

是的,它可能会被欺骗,因此不应依赖它来阻止上传较大的文件,但对于非恶意用户,如果上传的文件大于此字段中的整数,PHP 会禁止此上传并且在 $_FILES 数组中显示错误代码(来源 - comments on php.net)。

【讨论】:

  • 如果浏览器忽略它,这将如何警告用户?
  • @Vilx - 我希望能澄清我的答案。我认为 PHP 在处理发布数据之前会以某种方式检查 max_file_size 字段的存在,但我不太确定它是如何工作的。
  • 那很有趣,因为它在我的 WinXP + Apache 2.2 + PHP 5 上肯定不会这样做。而且谷歌显示我并不孤单。
  • 给我 +1 的用户,看来我错了,你能取消 +1 我吗?那么在 cmets 中的引用和问题的其他答案将是有意义的,但没有人会听我写的内容!
【解决方案6】:

当特定应用程序需要比php.ini 中的限制更小的文件时,我使用它来设置文件大小限制。我的 php 脚本会检查它,但它是在 HTML 表单中设置的。不同的表格有不同的文件大小限制。我不确定这是否与预期用途有很大关系,但它可以更轻松地重用我的脚本。如果可以在浏览器级别检查它会很好,但这不是它有用的唯一原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 2011-09-20
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2018-02-24
    • 2010-09-23
    相关资源
    最近更新 更多