gpt4 book ai didi

php - 内存高效的 base64 解码

转载 作者:搜寻专家 更新时间:2023-10-31 21:56:19 24 4
gpt4 key购买 nike

我们在我们的应用程序中遇到了一些问题,人们将图像粘贴到我们的富文本 WYSIWYG 中,此时它们作为 base64 编码的字符串存在。例如:

<img src="data:image/png;base64,iVBORw..." />

提交表单被提交和处理得很好,但是当我们的应用程序生成一个包含多个图像的页面时,它可能会导致 PHP 达到其内存限制,以及膨胀页面源等。

我所做的是编写一些代码添加到我们的表单处理器中以提取嵌入的图像,将它们写入文件,然后将 URL 放在 src 中。属性。问题在于,在处理图像时,内存使用量会飙升至数据大小的 4 倍,这也可能会破坏表单处理器。

我的POC代码:
<?php
function profile($label) {
printf("%10s %11d %11d\n", $label, memory_get_usage(), memory_get_peak_usage());
}

function handleEmbedded(&$src) {
$dom = new DOMDocument;
$dom->loadHTML($src);
profile('domload');
$images = $dom->getElementsByTagName('img');
profile('getimgs');
foreach ($images as $image) {
if( strpos($image->getAttribute('src'), 'data:') === 0 ) {
$image->setAttribute('src', saneImage($image->getAttribute('src')));
}
}
profile('presave');
$src = $dom->saveHTML();
profile('postsave');
}

function saneImage($data) {
$type = explode('/', substr($data, 5, strpos($data, ';')-5))[1];
$filename = generateFilename('./', 'data_', $type);
//file_put_contents($filename, base64_decode(substr($data, strpos($data, ';')+8)));
$fh = fopen($filename, 'w');
stream_filter_append($fh, 'convert.base64-decode');
fwrite($fh, substr($data, strpos($data, ';')+8));
fclose($fh);
profile('filesaved');
return $filename;
}

function generateFilename($dir, $prefix, $suffix) {
$dir = preg_replace('@/$@', '', $dir);
do {
$filename = sprintf("%s/%s%s.%s", $dir, $prefix, md5(mt_rand()), $suffix);
} while( file_exists($filename) );
return "foo.$suffix";
return $filename;
}

profile('start');
$src = file_get_contents('derp.txt');
profile('load');
handleEmbedded($src);
profile('end');

输出:
     start      236296      243048
load 1306264 1325312
domload 1306640 2378768
getimgs 1306880 2378768
filesaved 2371080 4501168
presave 1307264 4501168
postsave 244152 4501168
end 243480 4501168

正如您所看到的,尽管尝试使用流过滤器来减少字节数,但在保存文件时内存使用量仍会跳到 4MB 范围内。我认为后台发生了一些缓冲,如果我只是在文件之间进行转录,我会将数据分成块,但我不知道在这种情况下这是否可行/可取。

有什么地方可以减少我的内存使用量吗?

笔记:
  • file_put_contents()和改变 handleEmbedded()不通过引用传递具有相同的内存使用量。
  • derp.txt包含带有单个 base64 编码图像的 HTML 片段。
  • 4MB 并不是世界末日,但是就在昨天,有人试图上传 61MB 的 JPEG,所以谁知道有人会在富文本框中放什么。 :I
  • 最佳答案

    诺伯特在我的心理障碍上打洞的 Prop :

    function saneImage($data) {
    $type = explode('/', substr($data, 5, strpos($data, ';')-5))[1];
    $filename = generateFilename('./', 'data_', $type);
    writefile($filename, $data);
    profile('filesaved');
    return $filename;
    }

    function writefile($filename, $data) {
    $fh = fopen($filename, 'w');
    stream_filter_append($fh, 'convert.base64-decode');
    $chunksize=12*1024;
    $offset = strpos($data, ';')+8;
    for( $i=0; $chunk=substr($data,($chunksize*$i)+$offset,$chunksize); $i++ ) {
    fwrite($fh, $chunk);
    }
    fclose($fh);
    }

    输出:
         start      237952      244672
    load 1307920 1327000
    domload 1308296 2380664
    getimgs 1308536 2380664
    filesaved 2372712 2400592
    presave 1308944 2400592
    postsave 245832 2400592
    end 245160 2400592

    关于php - 内存高效的 base64 解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33312854/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com