我正在编写简单的php代理,我在显示png文件时遇到问题,输出是
应该是:
图像在Notepad ++中打开。我的php curl代码如下所示:
$ua = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
curl_setopt($ch, CURLOPT_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$content = curl_exec($ch);
$info = curl_getinfo($ch);
header('Content-Type:' . $info['content_type']);
echo $content
我尝试使用和不使用CURLOPT_BINARYTRANSFER输出相同且图像不显示。如何显示图像?
编辑:当我将数据保存到文件并使用位置标题重定向时,图像会正确显示:
$file = fopen('proxy_tmp~', 'w');
fwrite($file, $content);
fclose($file);
header('Location: ' . DIR . 'proxy_tmp~');
编辑2 :我有gzip压缩,当我禁用它时我有同样的问题,当我在Notepad ++中打开两个文件时,一个是DOS / Windows ANSI(原始),另一个是DOS / Windows UTF-8(由脚本打开的文件)。当我在记事本中打开文件并将编码更改为ANSI并保存文件时,一切正常。
编辑3 :我认为我在GNU / Linux上做了同样的事情,但没有CURLOPT_BINARYTRANSFER
选项,而且工作正常,这是我的项目https://github.com/jcubic/yapp。我也在Windows 10上使用Wamp进行测试,并且工作正常。
答案 0 :(得分:1)
请勿使用'w'
模式。它表示“文本模式”,因为不幸的是默认值为文本模式。
在Windows上,“文本模式”的意思是:每当您尝试写入\n
字节(ascii 10,换行符)时,它都没有前面的\r
字节(ascii 13,回车符) ,在写入\ n字节之前插入\ r字节。 (在Linux /现代MacOS上,这也意味着文本模式,但是在Linux /现代MacOS上,文本模式完全不执行任何操作,并且与二进制模式相同。*对于<= 2001之后的经典MacOS <= 9,不适用经典的MacOS,文本模式就像Windows上一样怪异的东西
始终使用二进制模式,例如wb
,以使您的程序可在Windows和Linux上移植。
(实际上,现代版本的PHP在未指定时会自动将其转换为二进制模式,但是在2013年提出了这个问题,如果您使用PHP以外的任何其他语言,这仍然是非常重要的经验法则。您实际上想要使用文本模式,请使用wt
明确启用文本模式,但是您几乎从不希望使用文本模式,这是一件可怕的事情,因为它是默认的默认模式实际上,它是如此可怕,以至于Linux根本不支持它。Apple/ MacOS在2001年随MacOS X的发布而放弃了对它的支持。AFAIKWindows是最后一个真正支持它的主要OS,东西向后兼容
答案 1 :(得分:0)
以下是如何将文件直接发送回用户进行下载(使用$ content var):
$file_array = explode("\n\r", $content, 2);
$header_array = explode("\n", $file_array[0]);
foreach($header_array as $header_value) {
$header_pieces = explode(':', $header_value);
if(count($header_pieces) == 2) {
$headers[$header_pieces[0]] = trim($header_pieces[1]);
}
}
header('Content-type: ' . $headers['Content-Type']);
header('Content-Disposition: ' . $headers['Content-Disposition']);
echo substr($file_array[1], 1);
这里有一个完整的例子:
http://ryansechrest.com/2012/07/send-and-receive-binary-files-using-php-and-curl/
答案 2 :(得分:0)
您使用的是哪个php版本? 你是PHP版本5.1.3吗?然后CURLOPT_BINARYTRANSFER将无效。
来源: http://php.net/manual/en/function.curl-setopt.php
查看该文件,您应该将以下标题添加到您的页面:
header('Content-Type: image/png');
答案 3 :(得分:0)
我使用了以下基本标头验证。使用postman获取验证密钥
// key : > converted to basic auth
// Content type
header('Content-Type: image/jpeg');
$url = 'http://com.com.com/api/images/products/264/7971';
$headers = array(
'Content-Type: image/png',
'Authorization: Basic @#$%@#$%@#$%@#$%@#$%@#$%' );
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
//curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
$file = curl_exec($ch);
curl_close($ch);
//echo($result);
// create image from output of the screen
$img = @imagecreatefromstring($file);
if ($img === false) {
echo $file;
exit;
}
$width = imagesx($img);
$height = imagesy($img);
$newWidth = 300;
$ratio = $newWidth / $width;
$newHeight = $ratio * $height;
$resized = @imagecreatetruecolor($newWidth, $newHeight);
if ($resized === false) {
echo $file;
exit;
}
$quality = 90;
if (@imagecopyresampled($resized, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height)) {
@imagejpeg($resized, NULL, $quality);
} else {
echo $file;
}
答案 4 :(得分:0)
使用EF
将内容划分为标题和正文,设置image / png标题然后执行$content_arr = explode("\r\n\r\n",$content,2);
以删除阻止浏览器无法读取的空格或空行图像。
答案 5 :(得分:0)
在我的情况下,添加Content-Length
标题修复了二进制文件代理问题。
答案 6 :(得分:0)
即使我从磁盘读取了png内容(file_get_contents函数),我仍然遇到这个问题。一个php源文件的编码是带有签名的UTF-8,这就是“我的”问题的根源。
所以我用Notepad2删除了签名。可以选择更改文件编码。