如何优雅地处理超过PHP的`post_max_size`的文件?

Nat*_*ong 84 php upload

我正在开发一个将文件附加到电子邮件的PHP表单,并试图优雅地处理上传文件太大的情况.

我了解到有两个设置php.ini会影响文件上传的最大大小:upload_max_filesizepost_max_size.

如果文件的大小超过upload_max_filesize,PHP将文件的大小返回为0.这很好; 我可以检查一下.

但如果超过post_max_size,我的脚本会无声地失败并返回到空白表单.

有没有办法抓住这个错误?

Mat*_*ick 54

文档:

如果发布数据的大小大于post_max_size,则$ _POST和$ _FILES超全局变量为空.这可以通过各种方式跟踪,例如将$ _GET变量传递给处理数据的脚本,即<form action ="edit.php?processed = 1">,然后检查$ _GET ['processed']是否为组.

所以不幸的是,它看起来不像PHP发送错误.因为它发送的是空的$ _POST数组,这就是为什么你的脚本会回到空白表单 - 它不认为它是一个POST.(相当糟糕的设计决定恕我直言)

这位评论者也有一个有趣的想法.

似乎更优雅的方式是post_max_size和$ _SERVER ['CONTENT_LENGTH']之间的比较.请注意,后者不仅包括上传文件的大小加上帖子数据,还包括多部分序列.

  • 请阅读粗体部分.也就是说,如果文件大小超过upload_max_filesize,则用户询问当表单超过post_max_size时会发生什么.post_max_size应设置为高于upload_max_filesize以尽量避免此问题,但OP可能有理由保持相同. (3认同)

小智 41

有一种方法来捕获/处理超过最大邮件大小的文件,这是我的首选,因为它告诉最终用户发生了什么以及谁有错;)

if (empty($_FILES) && empty($_POST) &&
        isset($_SERVER['REQUEST_METHOD']) &&
        strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
    //catch file overload error...
    $postMax = ini_get('post_max_size'); //grab the size limits...
    echo "<p style=\"color: #F00;\">\nPlease note files larger than {$postMax} will result in this error!<br>Please be advised this is not a limitation in the CMS, This is a limitation of the hosting server.<br>For various reasons they limit the max size of uploaded files, if you have access to the php ini file you can fix this by changing the post_max_size setting.<br> If you can't then please ask your host to increase the size limits, or use the FTP uploaded form</p>"; // echo out error and solutions...
    addForm(); //bounce back to the just filled out form.
}
else {
    // continue on with processing of the page...
}
Run Code Online (Sandbox Code Playgroud)

  • 这在track_errors = Off时有效,在php.ini中也可能是display_errors = Off和display_startup_errors = Off.否则PHP甚至不会那么远并发送警告,就像在问题标题中一样.但是在生产系统中,这应该是php.ini设置,所以这很好用. (2认同)
  • 这个简洁的想法在我的测试中运行良好(PHP/5.5.8).它也可以通过考虑`$ _SERVER ['CONTENT_LENGTH']`和`upload_max_filesize`来增强. (2认同)

sta*_*abm 6

我们遇到了SOAP请求的问题,其中检查$ _POST和$ _FILES的空白不起作用,因为它们在有效请求时也是空的.

因此我们实施了一项检查,比较了CONTENT_LENGTH和post_max_size.抛出的异常后来被我们注册的异常处理程序转换为XML-SOAP-FAULT.

private function checkPostSizeExceeded() {
    $maxPostSize = $this->iniGetBytes('post_max_size');

    if ($_SERVER['CONTENT_LENGTH'] > $maxPostSize) {
        throw new Exception(
            sprintf('Max post size exceeded! Got %s bytes, but limit is %s bytes.',
                $_SERVER['CONTENT_LENGTH'],
                $maxPostSize
            )
        );
    }
}

private function iniGetBytes($val)
{
    $val = trim(ini_get($val));
    if ($val != '') {
        $last = strtolower(
            $val{strlen($val) - 1}
        );
    } else {
        $last = '';
    }
    switch ($last) {
        // The 'G' modifier is available since PHP 5.1.0
        case 'g':
            $val *= 1024;
            // fall through
        case 'm':
            $val *= 1024;
            // fall through
        case 'k':
            $val *= 1024;
            // fall through
    }

    return $val;
}
Run Code Online (Sandbox Code Playgroud)