如何在 PHP 中对大文件进行 base64 解码

2022-01-21 00:00:00 memory base64 php

我的 PHP Web 应用程序有一个 API,可以接收经过 base64 编码的相当大的文件(最大 32 MB).目标是将这些文件写入我的文件系统的某个位置.当然是解码.什么是最不占用资源的方法?

My PHP web application has an API that can recieve reasonably large files (up to 32 MB) which are base64 encoded. The goal is to write these files somewhere on my filesystem. Decoded of course. What would be the least resource intensive way of doing this?

通过 API 接收文件意味着我的 PHP 应用程序中有一个 32MB 的字符串,而不是磁盘上某处的 32MB 源文件.我需要将该字符串解码到文件系统中.

Recieving the files through an API means that I have a 32MB string in my PHP app, not a 32 MB source file somewhere on disk. I need to get that string decoded an onto the filesystem.

使用 PHP 自己的 base64_decode() 并没有减少它,因为它使用了 lot 内存,所以我一直遇到 PHP 的内存限制(我知道,我可以提高这个限制,但我没有让 PHP 每个进程使用 256MB 左右感觉很好).

Using PHP's own base64_decode() isn't cutting it because it uses a lot of memory so I keep running into PHP's memory limit (I know, I could raise that limit but I don't feel good about allowing PHP to use 256MB or so per process).

还有其他选择吗?我可以手动做吗?还是将文件编码写入磁盘并调用一些外部命令?有什么想法吗?

Any other options? Could I do it manually? Or write the file to disk encoded and call some external command? Any thought?

推荐答案

尽管这有一个公认的答案,但我有不同的建议.

Even though this has an accepted answer, I have a different suggestion.

如果您从 API 中提取数据,则不应将整个有效负载存储在变量中.使用 curl 或其他 HTTP 提取器,您可以自动将数据存储在文件中.

If you are pulling the data from an API, you should not store the entire payload in a variable. Using curl or other HTTP fetchers you can automatically store your data in a file.

假设您通过一个简单的 GET url 获取数据:

Assuming you are fetching the data through a simple GET url:

$url = 'http://www.example.com/myfile.base64';
$target = 'localfile.data';

$rhandle = fopen($url,'r');
stream_filter_append($rhandle, 'convert.base64-decode');

$whandle = fopen($target,'w');

stream_copy_to_stream($rhandle,$whandle);
fclose($rhandle);
fclose($whandle);

好处:

  • 应该更快(减少大量变量的复制)
  • 很少的内存开销

如果您必须从临时变量中获取数据,我可以建议这种方法:

If you must grab the data from a temporary variable, I can suggest this approach:

$data = 'your base64 data';
$target = 'localfile.data';

$whandle = fopen($target,'w');
stream_filter_append($whandle, 'convert.base64-decode',STREAM_FILTER_WRITE);

fwrite($whandle,$data);

fclose($whandle);

相关文章