为什么php://input拒绝我上传大文件?


Why is php://input rejecting my large file uploads?

为了让我的Symfony2应用程序获得大块文件上传,我一直在把互联网弄得一团糟。为了简化程序,我将测试程序与应用程序的其余部分分开。它所做的唯一一件事是尝试测试php://input是否可以使用本文中描述的方法接受我上传的大文件:

http://www.webiny.com/blog/2012/05/07/webiny-file-upload-with-html5-and-ajax-using-php-streams/

我的理解是,如果用户上传一个2GB以上的大型视频文件,那么这将在服务器上占用2GB以上的RAM,本文中的方法将其减少到每个并发上传者4096位。(我不确定如何在本地主机服务器上测试RAM使用情况)

然而,当我尝试上传大文件时,浏览器只等待一两秒,然后发布一个1kb的视频文件。

我为php.ini设置了很高的值。

以下是PHP代码的相关部分:
     public function lastoppAction(Request $request)
{
    $videofilename = (string)$request->request->get("filnavn");
    $inputHandler = fopen("php://input", "rb");
    $fileHandler = fopen("videoer''myfile.tmp", "wb") or die('fopen failed');;
    while(true) {
$buffer = fgets($inputHandler, 4096);
if (strlen($buffer) == 0) {
    fclose($inputHandler);
    fclose($fileHandler);
            break;
}
fwrite($fileHandler, $buffer) or die('fwrite failed');;
    }
     $url = $this->generateUrl('largefile_navngi', array('filnavn' => $videofilename));
     return $this->redirect($url);
}
public function navngiAction(Request $request)
{
        $filnavn = $request->query->get('filnavn');
        $sti = $this->container->getParameter('kernel.root_dir');
        $websti = preg_replace('/app/','web',$sti,1);
        print_r("Filnavn: " . $filnavn);
        rename($websti . "/videoer/myfile.tmp",$websti . "/videoer/" . $filnavn);
        $url = $this->generateUrl('largefile_index');
        return $this->redirect($url);
}

重定向的原因是为了使rename能够正确接收文件名变量。

AJAX代码与上面链接的文章类似,但有以下区别:

xhr。open("POST", url, false);使用我自己的localhost url。我在这里也试过了。不同之处在于,如果我们在第三个参数中设置false,它将适用于小文件。

如果async为真,似乎只会给出两个文件:我打开的原始myfile.tmp和它重命名为的0kb文件。"filename.mp4"。

奇怪的是,当ajax代码运行:

xhr.onreadystatechange = function()
                {
                    if(xhr.readyState == 4)
                    {
                        if(xhr.status == 200)
                        {
                            //alert("success");// process success
                                                            alert("Filnavn: " + filnavn);
                        }else{
                            // process error
                                                            alert("Status: " + xhr.status);
                        }
                    }
                };

状态变为500,即使像16 MB这样的小文件完全上传而没有其他问题。

这是树枝文件:

    <h1>Test av å laste opp større filer</h1>
    <form method="post" action="{{path('largefile_lastopp')}}">
        <label>Fil: </label>
        <input type="file" name="fil" id="video" /><br /><br />
         <input type="hidden" name="filnavn" id="filnavn" />
         <input type="hidden" name="mimetype" id="mimetype" />
        <input onclick="upload('video',0)" type="submit" name="submit" />
    </form>
     ::1 - - [10/Jun/2015:15:41:36 +0200] "POST /LargeFileUpload/web/app_dev.php/lastopp HTTP/1.1" 302 436 "http://localhost/LargeFileUpload/web/app_dev.php/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36"

我认为这里的问题是客户端代码一次读取整个文件,然后从中创建blob。如果您尝试上传一个1GB的文件,这意味着在ist发送第一个字节之前,浏览器至少需要2GB的RAM。

我可以想象,可能有安全措施来防止这种内存(ab-)的使用。