问题
I'm writing simple php proxy and I have trouble displaying png file, the output is
and it should be:
The images are opened in Notepad++. My php curl code look like this:
$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
I try with and without CURLOPT_BINARYTRANSFER the output is the same and the image is not displaying. How can I display the image?
EDIT: when I'm saving the data to the file and redirect using Location header the image is displayed correctly:
$file = fopen('proxy_tmp~', 'w');
fwrite($file, $content);
fclose($file);
header('Location: ' . DIR . 'proxy_tmp~');
EDIT 2: I had gzip compression, bu when I disabled it I have the same issue, when I open both files in Notepad++ one is DOS/Windows ANSI (original) and the other is DOS/Windows UTF-8 (the file opened by a script). When I open a file in Notepad and change encoding to ANSI and save the file, everything is ok.
EDIT 3: I think I did the same thing on GNU/Linux but without CURLOPT_BINARYTRANSFER
option and it's working fine, here is my project https://github.com/jcubic/yapp. I've also test it on Windows 10 with Wamp and also work fine.
回答1:
Here is how to send the file directly back to the user for download (uses your $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);
There is a full example here:
http://ryansechrest.com/2012/07/send-and-receive-binary-files-using-php-and-curl/
回答2:
Which php version are you using? Are you above PHP version 5.1.3? Then the CURLOPT_BINARYTRANSFER will have no effect.
Source: http://php.net/manual/en/function.curl-setopt.php
Looking at the file, you should add the following header to you're page:
header('Content-Type: image/png');
回答3:
I have used following with basic header authentication.. used postman to get auth key
// 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:
Use $content_arr = explode("\r\n\r\n",$content,2);
to divide the content into headers and body, set the image/png header and then do echo trim($content_arr[1]);
to get rid of spaces or blank lines that prevent the browser from being able to read the image.
回答5:
In my case adding Content-Length
header fixed problems with binary files proxy.
来源:https://stackoverflow.com/questions/17520987/how-to-display-binary-data-from-curl-in-php