Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP fwrite()文件导致内部服务器错误_Php_File_Memory_Fwrite - Fatal编程技术网

PHP fwrite()文件导致内部服务器错误

PHP fwrite()文件导致内部服务器错误,php,file,memory,fwrite,Php,File,Memory,Fwrite,我想把大文件上传到我的服务器上。我在上传这些文件之前将它们拼接成最大1MB的块。如果上载了一个区块,则会将该区块追加到文件中。 在我的本地服务器上,一切都很好,但是如果我在我的Web服务器(由Strato-.-)上测试这个脚本,每当服务器上的附加文件变大64MB时,进程就会退出,并出现内部服务器错误。 我认为这(当然?)是因为Strato的限制。也许是记忆的问题,但我无法向自己解释为什么会发生这种情况。 这是脚本(PHP版本5.6): 在我看来,这段代码中没有一行文件被加载到内存中导致此错误,或

我想把大文件上传到我的服务器上。我在上传这些文件之前将它们拼接成最大1MB的块。如果上载了一个区块,则会将该区块追加到文件中。 在我的本地服务器上,一切都很好,但是如果我在我的Web服务器(由Strato-.-)上测试这个脚本,每当服务器上的附加文件变大64MB时,进程就会退出,并出现内部服务器错误。 我认为这(当然?)是因为Strato的限制。也许是记忆的问题,但我无法向自己解释为什么会发生这种情况。 这是脚本(PHP版本5.6):

在我看来,这段代码中没有一行文件被加载到内存中导致此错误,或者是其他原因导致此错误

我检查了te服务器日志,但如果发生此错误,则没有条目

我可以创建多个63MB文件。只有当文件超过64MB时,服务器才会中止

更新: 我编写了以下脚本,将服务器上的文件块与cat连接起来。 但我总是能得到8192B的文件。 这个脚本有什么问题吗? $command类似于:
/bin/cat../files/8_0../files/8_1../files/8_2../files/8_3

我检查了结果。8192B文件中的字节与原始文件开头的字节完全相同。所以有些东西似乎起作用了

更新: 我找到了

更新:

$handle1 = popen($command, "r");
while(!feof($handle1))  
{ 
    $read = fread($handle1, 1024);
    echo $read;
}
这很有效,我可以从手柄上逐段读取。但当然,这样我会遇到超时限制。如何将文件传递给客户端?如果回答了这个问题,我所有的问题都消失了;)

(参见底部的更新)

内存限制错误看起来会有所不同(但您可以编写一个脚本,通过将大型对象添加到不断增长的数组中来连续分配内存,然后看看会发生什么)。此外,内存限制与PHP核心、脚本、结构以及任何文件内容有关;即使要根据内存限制加载或计数附加到的文件(可能通过
mmap
,即使它看起来很奇怪),也不太可能达到64兆字节的限制

因此,在我看来,这似乎是对单个文件大小的文件系统限制。有几个云文件系统有这样的限制;但据我所知,在本地磁盘存储上没有这样的存储。我会询问托管技术支持的线索

我会做一些尝试:

  • 仔细检查
    $uploadDir
    ,除非您亲自指定

  • 尝试在不同于
    $uploadDir
    的路径中创建文件,除非确实在同一文件系统上

  • 尝试检查错误:

    if (!fwrite($server_chunk, fread($new_chunk, 1024))) {
       die("Error writing: ");
    }
    
  • 对phpinfo()进行偏执检查,以确保不存在诸如。你可以通过调查和查看他们(是的,但不太可能)

更新 它看起来确实像是一个文件大小限制,与PHP无关。同一主机的早期用户报告为32MB。见和。有些人无法运行
mysqldump
tar
备份。它与PHP没有直接关系

解决方法。。。这似乎有效! 您可以通过将文件分块存储,分几次下载,或者通过向Apache传递管道到
cat
程序(如果可用)来解决这个问题

您将存储文件123.0001、文件123.0002,…,然后在下载时检查所有片段,发送适当的
内容长度
,为
/bin/cat
(如果可以访问…)构建命令行,并将流连接到服务器。你可能仍然会遇到时间限制,但值得一试

例如:

<?php
    $pattern    = "test/zot.*"; # BEWARE OF SHELL METACHARACTERS
    $files      = glob($pattern);
    natsort($files);
    $size       = array_sum(array_map('filesize', $files));
    ob_end_clean();
    Header("Content-Disposition: attachment;filename=\"test.bin\";");
    Header("Content-Type: application/octet-stream");
    Header("Content-Length: {$size}");
    passthru("/bin/cat {$pattern}");
结果是:


当然,Strato可能会对脚本的运行时间进行更严格的检查。另外,我已经安装了PHP作为一个模块;对于作为独立进程运行的CGI,可能会应用不同的规则。

您可以更改内存大小限制吗?您的服务器在PHP中使用CGI或FastCGI吗?@Ericsh不可以。我的网站管理员非常严格;)但我认为这不是重点。我希望有一种方法可以编写脚本,它可以在不改变任何内容的情况下在不同的WebHoster上工作。“那太好了!”吉尔默纳西门托是的,我想是的。php.ini说:“服务器API:CGI/FastCGI”@kristokomlossy post php.ini在你的问题:)嗨,谢谢你的详细回答。我已经尝试过将文件存储在块中,并在前面使用readfile()下载这些块。但正如你所说,脚本是在时间限制(120秒)内运行的。你说我必须试着将文件分块存储在服务器上?没有其他可能避免层流限制?也许uplaod会和其他主持人合作得很好?太好了-我会试试你对猫的建议,很快就会回来;)这是否来自php信息帮助:
post_max_size 48M
post_max_size 48M
我已经进行了一些有希望的实验:-)@lserni我用passthru()尝试过,但仍在运行时间限制内。php.net说:“如果一个程序是用这个函数启动的,为了让它在后台继续运行,程序的输出必须重定向到一个文件或另一个输出流。否则会导致php挂起,直到程序的执行结束。”我该怎么做?有什么方法可以脱离php过程吗?也许可以使用php调用cat命令,让服务器在cat进程之后下载文件。不知道;)不,如果你重定向了流,它不会帮助你。从PHP中,不可能将子进程(cat)与父进程(web服务器)连接起来,然后让它们安静地工作。恐怕你得把这事告诉斯特拉托。
if (!fwrite($server_chunk, fread($new_chunk, 1024))) {
   die("Error writing: ");
}
<?php
    $pattern    = "test/zot.*"; # BEWARE OF SHELL METACHARACTERS
    $files      = glob($pattern);
    natsort($files);
    $size       = array_sum(array_map('filesize', $files));
    ob_end_clean();
    Header("Content-Disposition: attachment;filename=\"test.bin\";");
    Header("Content-Type: application/octet-stream");
    Header("Content-Length: {$size}");
    passthru("/bin/cat {$pattern}");
<pre>
<?php
    print "It is now " . date("H:i:s") . "\n";
    passthru("sleep 4; echo 'Qapla!'");
    print "It is now " . date("H:i:s") . "\n";
    $x = 0;
    for ($i = 0; $i < 5; $i++) {
        $t = microtime(true);
        while (microtime(true) < $t + 1.0) {
            $x++;
        }
        echo "OK so far. It is now " . date("H:i:s") . "\n";
    }
It is now 20:52:56
Qapla!
It is now 20:53:00
OK so far. It is now 20:53:01
OK so far. It is now 20:53:02
OK so far. It is now 20:53:03


( ! ) Fatal error: Maximum execution time of 3 seconds exceeded in /srv/www/rumenta/htdocs/test.php on line 9

Call Stack
#   Time    Memory  Function    Location
1   0.0002  235384  {main}( )   ../test.php:0
2   7.0191  236152  microtime ( )   ../test.php:9