file_put_contents在32位php上将内容截断为max int

时间:2020-08-08 19:09:09

标签: php nextcloud

我在使用32位体系结构的Raspberry Pi 4上运行了nextcloud。

当尝试上传大于2147483647字节的文件时,该文件将完全上传并且可以通过ssh访问。但是,当我尝试通过Web客户端以任何方式访问它时,都会失败。在webclient的日志中看到的错误如下:

file_put_contents(): content truncated from 4118394086 to 2147483647 bytes at /var/www/html/nextcloud/lib/private/Files/Storage/Local.php#556

当我尝试访问文件时,会记录以下错误消息:

Sabre\DAV\Exception\RequestedRangeNotSatisfiable: The start offset (0) exceeded the size of the entity (-176573210)

这里涉及的文件是.mp4文件,但是我已经能够使用其他文件类型来复制该问题。

我已经了解到32位架构的2GB上传限制已修复,但是我不知道为什么我的情况可能会失败。

1 个答案:

答案 0 :(得分:1)

问题

好吧,您无法通过调整任何配置来解决此问题,因为它是hard limit set by PHP(32位架构上的PHP_INT_MAX为2G(2 ^(32-1)-1))

有希望

您可以手动打补丁,甚至可以更好地覆盖responsible nextcloud code

手动修补(因为您不使用作曲家,所以可能要这样做)

// this one is pretty memory expensive, but works with resouce and string
// Test: 4GB file, 2GB chunks (at 32bits)
// 12GB memory usage! - hell no
public function file_put_contents($path, $data) {
    $bytesWritten = 0;
    foreach (explode(PHP_EOL, chunk_split($data, PHP_INT_MAX, PHP_EOL)) as $chunk) {
        $bytesWritten += file_put_contents($this->getSourcePath($path), $chunk, FILE_APPEND|LOCK_EX);
    }
    
    return $bytesWritten;
}

// better use this, in case $data is a resource - I dont know, you have to test it!
// Test: 4GB file, 1MB chunks
// 2MB memory usage - much better :)
public function file_put_contents($path, $data) {
    $bytesWritten = 0;
    while ($chunk = fread($data, 2**20)) {
        $bytesWritten += file_put_contents($this->getSourcePath($path), $chunk, FILE_APPEND|LOCK_EX);
    }

    return $bytesWritten;
}

如果您想覆盖(编写者)

class PatchedLocal extends OC\Files\Storage\Local {
    public function file_put_contents($path, $data) {
        // same as above ...
    }
}

然后here,您需要了解的所有信息也可以迫使自动装带器使用您的PatchedLocal。 -如前所述,您想为此使用composers PSR-4实现-通过composer.json。

相关问题