Unable to download remote image with PHP CURL - php

Edit: I contact the support at scrapestack and confirmed that their api doesn't support image files.
I am trying to download a remote image using CURL with php. Below is my code. But whenever I try to open the downloaded image, I always get:
Cannot read this file. This is not a valid bitmap file, or its format is not currently supported.
Anyone know what is wrong with my code? Thank you.
$image ="http://api.scrapestack.com/scrape?access_key=TOKEN-HERE&url=https://i.imgur.com/Cbiu8Ef.png";
$imageName = pathinfo( $image, PATHINFO_BASENAME );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $image );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTP_CONTENT_DECODING, false);
$source = curl_exec( $ch );
$info = curl_getinfo($ch);
curl_close( $ch );
file_put_contents( $imageName, $source );
I am not able to open the file, when I tried to open it with sublime, it is stuck at Loading Image. When I open it with notepad, I got the following that looks like PNG image, but it is not a valid image. File starts with
�PNG
IHDR � q�I� IDATx�k�]�u�o��(��_�M��m�8:���_r�G
You can see the file here: https://gofile.io/?c=cfsYf2
Looks like the problem is making the curl request through Scrapestack, because if I point the curl to image url directly, the image is downloaded correctly, like below:
$image ="https://i.imgur.com/Cbiu8Ef.png";

Edit: I played around with scrapestack a bit more today, it doesn't seem to support image scraping. It is best if you can reach out to their customer support and find out.
#Towsif is right, you are trying to get the page, not the actual image. I put something together really quick, try and see if this works for you.
$queryString = http_build_query([
'access_key' => 'replace this with your own token',
'url' => 'https://i.imgur.com/Cbiu8Ef.png',
]);
$ch = curl_init(sprintf('%s?%s', 'http://api.scrapestack.com/scrape', $queryString));
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$image_source = curl_exec( $ch );
curl_close( $ch );
file_put_contents( 'Cbiu8Ef.png' , $image_source );

It looks like the response you get is a corrupt PNG image.
If you are using PHP with version prior of 5.1.3 you need to specify an additional option for binary data transfers, like images:
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
If the above options doesn't solve the issue you may try setting
curl_setopt($ch, CURLOPT_HTTP_CONTENT_DECODING, false);
in case the response has the Content-Type header set wrong letting curl do unwanted decoding on the raw output.

Your problem is with this url.
$image ="http://api.scrapestack.com/scrape?access_key=TOKEN-HERE&url=https://imgur.com/a/E5ehGuv";
If you go to this url
https://imgur.com/a/E5ehGuv
You will see the image page but NOT the image path. pathinfo() function does not work here and raises error.
If you right click on that image and Open image in new tab you will then see the image path, in this case that is
https://i.imgur.com/Cbiu8Ef.png
So you may try with this url
$image ="http://api.scrapestack.com/scrape?access_key=TOKEN-HERE&url=https://i.imgur.com/Cbiu8Ef.png";

Related

Prestashop Webservice Image Upload

Hello and thanks in advance, now I'm trying to upload a image to a prestashop 1.7 via webservice and I'm unable to insert a image in a product. I don't know what fails, because I don't get any response of the webservice, even with the debug enabled (I get the xml responses of the rest of the files, but not the ones from curl).
The variable $idProduct is a value passed to the function and is defined.
My code is the following:
$url = PS_SHOP_PATH."api/images/products/".$idProduct;
$dir_path_to_save = 'img/import/';
$img_path = getFile($remoteImageURL, $dir_path_to_save);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, PS_WS_AUTH_KEY.':');
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => '#'.$img_path));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
echo print_r($response);
curl_close($ch);
The getFile function downloads the image to the server where is installed the prestashop and returns the path (returns a string with the real path where the image is stored, already tested).
I tried to make a form to upload the image (just for testing), but it returns "code 66 - unable to save this image". I don't know if this helps.
Thanks
UPDATE
A fellow programmer told me to use curl_file_create()
So I changed the $img_path declaration this way:
$img = curl_file_create($dir_path_to_save.'/'.basename($img_path));
Now everything works as intended.

Curl and php download file from url not working

I'm trying do retrieve and download a file (image) from a remote location.
Inside the php.ini the allow_url_fopen is enabled, but i can't download the image.
Code i'm using is described below
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
with any other url that contains a real jpg file, it's working perfectly, i suppose that the issue is that the url use some special characters that doesn't like to curl.
If i try to execute the php snippet above,page load for almost 1 minute,and it seems that no error are displayed,the image test.jpg is created, but it's empty.
Do you have any suggestion?
Thanks!
Try this
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
function getPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function saveToFile($base, $decode=false, $output_file)
{
$ifp = fopen($output_file, "wb");
if ($decode){
fwrite($ifp, base64_decode($base));
}else{
fwrite($ifp, $base);
}
fclose($ifp);
return($output_file);
}
$remote_page = getPage($remote_file);
$saved_file = saveToFile($remote_page , false, $local_file);
when debugging issues like this, set CURLOPT_VERBOSE, it will probably reveal why the page loaded for almost 1 minute, with no apparent output.
i suppose that the issue is that the url use some special characters - this is fully possible, for example your username and password, they're supposed to be urlencoded. urlencoding is binary safe, meaning you can have any special characters you'd like, you just need to encode it properly. use urlencode() or http_build_query() for that, eg
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?" . http_build_query ( array (
'cmd' => 'snapPicture2',
'usr' => 'username',
'pwd' => 'password'
) );
now http_build_query will properly urlencode any special characters in your username and password (for example, if your username is an email address, the # becomes %40).
if that doesn't fix it, what does CURLOPT_VERBOSE say?
also, final note, here you're sending the download request with credentials in a GET request. that's very unusual, the vast majority of websites want you to login with a POST request, and there are good security-related reasons for that, are you sure your website allows sending credentials in GET parameters? the vast majority of websites doesn't allow it... (and the best way to find out, is to record a browser logging in, does the browser use GET parameters, or POST parameters?)

PHP - How to display image source as an img

I am using Wialon SDK and I am trying to get a map, everything works fine but it returns a result with image code, and outputs some question marks, (don't know how to explain it, but when you open img file in notepad or something like that) how can I save the output into a png file or display it on web?
here is the function
function get_map($sid){
$params = array(
"width" => 600,
"height" => 600
);
$url = "mywebpage.com/ajax.html?svc=report/get_result_map";
$json = json_encode($params);
$ch = curl_init($sid);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,"&params=".$json."&ssid=".$sid);
$server_output = curl_exec($ch);
curl_close($ch);
return $server_output;
}
and I call it like this:
$get_map = $pro->get_map($sid);
var_dump($get_map);
In PHP you need to set the HEADER to tell the browser to display this data as an image.
<?php
header('Content-Type: image/png');
echo $get_map; // The PNG data
?>
That should do the trick.

Downloading remote image via php (securely)

PHP:
Any ideas where I could find a script similar to what stackoverflow uses? Or would it be easy to make something like that myself? I'm sure downloading the image is not a problem, but I'm more worried about security. I'm building an user avatar upload/remote upload system.
Jquery:
The reason I added jquery to the tags, perhaps it is possible to let the user point the URL of the image and somehow upload it via the normal file upload input himself (without having to manually download the image to the computer first)
You can use cURL to download the image and then use getimagesize() to check whether it's actually an image - for security purposes.
<?php
$limit = 1024*1024*10 // Max. file size in bytes (1024*1024*10 = 10MB)
$ch = curl_init();
$fh = fopen('image.jpg', 'w');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_setopt($ch, CURLOPT_RANGE, '0-' . $limit);
curl_exec($ch);
curl_close($ch);
if ($image = getimagesize ("image.jpg")) {
// It's an image
}
else {
// Not an image; delete!
}

Updating Twitter background via API

I'm having a little trouble updating backgrounds via Twitter's API.
$target_url = "http://www.google.com/logos/11th_birthday.gif";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html = curl_exec($ch);
$content = $to->OAuthRequest('http://twitter.com/account/update_profile_background_image.xml', array('profile_background_image_url' => $html), 'POST');
When I try to pull the raw data via cURL or file_get_contents, I get this...
Expectation Failed The expectation given in the Expect request-header
field could not be met by this server.
The client sent
Expect: 100-continue but we only allow the 100-continue expectation.
OK, you can't direct Twitter to a URL, it won't accept that. Looking around a bit I've found that the best way is to download the image to the local server and then pass that over to Twitter almost like a form upload.
Try the following code, and let me know what you get.
// The URL from an external (or internal) server we want to grab
$url = 'http://www.google.com/logos/11th_birthday.gif';
// We need to grab the file name of this, unless you want to create your own
$filename = basename($url);
// This is where we'll be saving our new file to. Replace LOCALPATH with the path you would like to save the file to, i.e. www/home/content/my_directory/
$newfilename = 'LOCALPATH' . $filename;
// Copy it over, PHP will handle the overheads.
copy($url, $newfilename);
// Now it's OAuth time... fingers crossed!
$content = $to->OAuthRequest('http://twitter.com/account/update_profile_background_image.xml', array('profile_background_image_url' => $newfilename), 'POST');
// Echo something so you know it went through
print "done";
Well, given the error message, it sounds like you should load the URL's contents yourself, and post the data directly. Have you tried that?

Categories