Php 如何处理非';t base64编码?

Php 如何处理非';t base64编码?,php,base64,Php,Base64,我试图为一个桌面客户端提供追溯支持,该客户端错误地将图像数据发布到我的PHP表单中 问题是,发布的图像数据尚未进行base64编码,我无法更改分布式客户端,因此我想知道是否可以在服务器端做些事情 通过写入服务器时图像的数据 file_put_contents($filePath,$_POST['rawImageData']); 导致损坏的JPEG(我知道上传的所有图像都是JPEG) 该编码似乎是默认的HTTP POST编码ISO-8859-1 我尝试过使用iconv、utf_解码、mb_con

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

问题是,发布的图像数据尚未进行base64编码,我无法更改分布式客户端,因此我想知道是否可以在服务器端做些事情

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

file_put_contents($filePath,$_POST['rawImageData']);
导致损坏的JPEG(我知道上传的所有图像都是JPEG)

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

我尝试过使用iconv、utf_解码、mb_convert_编码和其他一些方法来转换发布的数据,但没有成功


在这种情况下是否可以恢复?

PHP可能不正确地填充
$\u POST
数组,因为它将JPEG数据解释为表单数据,其中可能包含
&
字符或其他会混淆它的内容。如果您手动读取输入流而不是依赖于
$\u 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);
server.php(第1版)

这将尝试像代码一样使用
$\u POST

$tmp = "/tmp/output.jpg";
file_put_contents($tmp, $_POST['rawImageData']);
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);
对于
input.jpg
我使用了来自维基百科的~10k JPEG文件

结果


服务器版本1只将大约50个字节写入output.jpg,当我试图用查看器打开它时,会出现损坏的JPEG错误。服务器版本2写入完整的10k字节,我的JPEG查看器显示的图像很好。

您可能看过了吗?对不起,我应该提到-是的,我看过。@Darren JPEG图像数据是二进制数据,不是文本。试图像文本一样操纵它,比如使用在文本编码之间转换的函数,是不会正常工作的。@Dashwolf-这是合理的,也是有意义的。有没有办法将文本转换回二进制?与其依赖PHP理解请求并找到正确的POST参数,不如从原始输入流开始:
file\u put\u contents($filePath,file\u get\u contents($s)来获得更好的成功php://input'));
然后自己删除非图像数据