如何处理发布到非base64编码的PHP的图像?

Dan*_*Dan 4 php base64

我正在尝试为桌面客户端提供追溯支持,该客户端将图像数据错误地发布到我的PHP表单.

问题是发布的图像数据没有base64编码,我无法更改分布式客户端,所以我想知道我是否可以做服务器端的事情.

通过写入服务器时图像的数据

file_put_contents($filePath,$_POST['rawImageData']);
Run Code Online (Sandbox Code Playgroud)

导致JPEG损坏(我知道上传的所有图片都是JPEG).

编码似乎是默认的HTTP POST编码,ISO-8859-1.

我尝试使用iconv,utf_decode,mb_convert_encoding以及其他几个没有运气来转换发布的数据.

在这种情况下可以恢复吗?

Aus*_*tin 6

PHP可能不正确地填充$_POST数组,因为它将JPEG数据解释为可能包含&字符或其他会使其混淆的内容的表单数据.如果您手动读取输入流而不是依赖$_POST,则应该能够恢复数据.

我写了一些快速代码来尝试重现您的问题并测试它:

client.php

此代码模拟您的客户端; 它只是读取一个JPEG文件并通过POST请求原始写入.

$url = 'http://localhost/server.php';
$input = __DIR__ . '/input.jpg';

$parts = parse_url($url);
$sock = fsockopen($parts['host'], 80);

$out = "POST ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".(filesize($input) + strlen("rawImageData="))."\r\n";
$out.= "\r\n";
$out.= "rawImageData=";

fwrite($sock, $out);
$fd = fopen($input, 'r');
stream_copy_to_stream($fd, $sock);
fclose($fd);
fclose($sock);
Run Code Online (Sandbox Code Playgroud)

server.php(版本1)

这会尝试$_POST像您的代码一样使用该值.

$tmp = "/tmp/output.jpg";
file_put_contents($tmp, $_POST['rawImageData']);
Run Code Online (Sandbox Code Playgroud)

server.php(版本2)

这将从POST正文中读取原始输入流.

$tmp = "/tmp/output.jpg";
$fd = fopen('php://input', 'r');
fread($fd, strlen("rawImageData=")); //throw this data out
$out = fopen($tmp, 'w');
stream_copy_to_stream($fd, $out);
fclose($out);
fclose($fd);
Run Code Online (Sandbox Code Playgroud)

因为input.jpg我使用了维基百科的~10k JPEG文件.

结果

服务器版本1只向output.jpg写入大约50个字节,当我尝试用查看器打开它时,我得到了一个损坏的JPEG错误.服务器版本2写入完整的10k字节,我的JPEG查看器显示图像就好了.