How to base64 encode an image from the facebook api - php

I am attempting to convert an image url provided by the facebook api into base64 format with cURL.
the api provides a url as such:
https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-xfp1/v/t1.0-9/p180x540/72099_736078480783_68792122_n.jpg?oh=f3698c5eed12c1f2503b147d221f39d1&oe=54C5BA4E&__gda__=1418090980_c7af12de6b0dd8abe752f801c1d61e0d
The issue is that the url only works with the oh, oe and gda parameters included in the url string, there is no direct img url. Removing the params send you to a facebook error page.
With the parameterized url my curl_exec is not getting correct image data. Is there a way to get the base64 data from facebook, or is there something I can do to get access the pure image url given the parameterized url?
This is what my decode scrip looks like:
header('Access-Control-Allow-Origin: *');
$url = $_GET['url'];
try {
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 3);
$result = curl_exec($c);
curl_close ($c);
if(false===$result) {
echo 'fail';
} else {
$base64 = "data:image/jpeg;charset=UTF-8;base64,".base64_encode($result);
echo $base64;
}
} catch ( \ErrorException $e ) {
echo 'fail';
}

To address your specific problem, your script is likely failing because the required oh, oe, __gda__ parameters are getting separated during the GET request and therefore are not included in $_GET['url'].
Make sure you're using a URL-encoded string so any unencoded & characters aren't handled as delimiters. Then just decode the string before passing it on to cURL.
...
$url = urldecode($_GET['url']);
...
For anyone curious, you can still load any Facebook image from any one of their legacy CDNs without needing the new parameters:
https://scontent-a-iad.xx.fbcdn.net/hphotos-frc3/
https://scontent-b-iad.xx.fbcdn.net/hphotos-frc3/
https://scontent-c-iad.xx.fbcdn.net/hphotos-frc3/
Just append the original image filename to the URL et voila.
Disclaimer: I have no idea how long this little trick will work for so don't use it on anything important in production.

Maybe this won't help much but it seems that the original picture (ending with _o) does not need gda nor oe oh parameters
to get the original profile picture you can do:
var username_or_id = "name.lastname" //Example
get_url ("http://graph.facebook.com/$username_or_id/picture?width=9999")
hth

I had similar problem. My solution:
$url = urldecode($url);
return base64_encode(file_get_contents($url));
Where the URL is to Graph API:
https://graph.facebook.com/$user_id/picture?width=160
(You probably want to also check, if file_get_contents returns something)

You just need to add the CURLOPT_SSL_VERIFYPEER set to false as the url from facebook is https and not http., or you could just as well request the url without ssl by replacing https with http.
Try the code below
$url = 'https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-xfp1/v/t1.0-9/p180x540/72099_736078480783_68792122_n.jpg?oh=f3698c5eed12c1f2503b147d221f39d1&oe=54C5BA4E&__gda__=1418090980_c7af12de6b0dd8abe752f801c1d61e0d';
try {
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 3);
/***********************************************/
// you need the curl ssl_opt_verifypeer
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
/***********************************************/
$result = curl_exec($c);
curl_close ($c);
if(false===$result) {
echo 'fail';
} else {
$base64 = '<img alt="Embedded Image" src="data:image/jpeg;charset=UTF-8;base64,'.base64_encode($result).'"/>';
echo $base64;
}
}
catch ( \ErrorException $e ) {
echo 'fail';
}

Related

How to use GET in PHP with OneNote API?

I've got the OneNote API PHP Sample (thanks jamescro!) working with all the POST examples, but there's no GET example and I haven't managed to put together code of my own that works. Here's what I've tried without success:
// Use page ID returned by POST
$pageID = '/0-1bf269c43a694dd3aaa7229631469712!93-240BD74C83900C17!600';
$initUrl = URL . $pageID;
$cookieValues = parseQueryString(#$_COOKIE['wl_auth']);
$encodedAccessToken = rawurlencode(#$cookieValues['access_token']);
$ch = curl_init($initUrl);
curl_setopt($ch, CURLOPT_URL, $initUrl); // Set URL to download
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (! $response === false) {
curl_close($ch);
echo '<i>Response</i>: '. htmlspecialchars($response);
}
else {
$info = curl_getinfo($ch);
curl_close($ch);
echo '<i>Error</i>: ';
echo var_export($info);
}
It just returns 'Error' with an info dump. What am I doing wrong?
without information on the specific error I'm not sure what issue you are hitting. Try looking at the PHP Wordpress plugin here: https://github.com/wp-plugins/onenote-publisher/blob/master/api-proxy.php
look at what is sent to wp_remote_get - there are necessary headers that are needed.
Also make sure you have the scope "office.onenote" when you request the access token.
If you need more help, please add information about the specific URL you are attempting to call, as well as the contents of your headers. If you have any errors, please include the output.
Solved:
As Jay Ongg pointed out, "there are necessary headers that are needed".
After adding more detailed error checking and getting a 401 response code, I added:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:text/html\r\n".
"Authorization: Bearer ".$encodedAccessToken));
... and could access the requested page.

How to make curl call for remote url which contain space

This question is continuation of my previous question
<?php
$remoteFile = 'http://cdn/bucket/my textfile.txt';
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch);
print_r($data)
curl_close($ch);
if ($data === false) {
echo 'cURL failed';
exit;
}
$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
$status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$contentLength = (int)$matches[1];
}
echo 'HTTP Status: ' . $status . "\n";
echo 'Content-Length: ' . $contentLength;
?>
I am using above code to get the file size in server side from CDN url but when I use the CDN url with space in it. it is throwing below error
page not found 09/18/2014 - 16:54 http://cdn/bucket/my textfile.txt
Can I make curl call for remote url which contain space ?
To give little bit more info on this
I am having interface where user will be saving file to CDN (so user
can give whatever title user want, it may contain space )and all
information in saved in back end db. I have another interface where I
retrieve the saved information and show it in my page along with file
size which I am getting using above code.
You have to encode your url's which have space's in it.
echo urlencode('http://cdn/bucket/my textfile.txt');
Ref: urlencode
or you can use,
echo '<a href="http://example.com/department_list_script/',
rawurlencode('sales and marketing/Miami'), '">';
Ref: rawurlencode
Yes you need to URL / URI encode
In an encoded URL, the spaces are encoded as: %20, so your URL would be: http://cdn/bucket/my%20textfile.txt so you could just use this url.
Or as this is PHP, you could use the urlencode function.
ref: http://php.net/manual/en/function.urlencode.php
e.g.
$remoteFile = urlencode('http://cdn/bucket/my textfile.txt');
or
$ch = curl_init(urlencode($remoteFile));

Getting a gmail contact Photo using Curl

I have created a class managing the connection to Google Contacts API, authenticate and return the contacts.
I've successfully got the contacts list, But I didn't yet manage to get the contact photo. This is my html code :
<img src="<?= $service->getPhoto($contact['image']) ?>" />
and this is my php:
public function getPhoto($url = false){
if(!$url)
return false;
$url = urlencode($url.'&access_token='.$this->_access_token);
//echo $url.'&access_token='.$this->_access_token;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 15);
$image = curl_exec($curl);
curl_close($curl);
return $image;
}
Note that the $url argument is the url provided by the contacts data returned by the Google API, it's like as the following:
https://www.google.com/m8/feeds/photos/media/{userEmail}/{contactID}
This is an exemple of an URL (according to my project) :
https://www.google.com/m8/feeds/photos/media/example%40gmail.com/ABCDEFGHIJK2345
Sometimes the contactId contains a '/'
The error message from Google is :
401. That's an error.
There was an error in your request. That's all we know.
Did I miss something?
NOTE: I tried with urlencode, urldecode and tried without using them...But I got the same problem. Also, the contacts I'm testing with have gmail photos.
You are encoding your whole url and probably which is causing the mess!?
$url = $url . '&access_token=' . urlencode($this->_access_token);
I've finally solved the problem, and this is what I did:
I changed the '&' to '?' in the $url
$url.'&access_token='.$this->_access_token
changed to :
$url.'?access_token='.$this->_access_token
Since access_token is the first parameter ... and I removed the curl, I just returned the $url as it is and put it in the image src.
Although it's somehow solved, I don't know if it's okey to put the access_token in the src of the image (which can be viewed by any client side user).

Use PHP to get embed src page information?

Sort of a weird question.
From 4shared video site, I get the embed code like the following:
<embed src="http://www.4shared.com/embed/436595676/acfa8f75" width="420" height="320" allowfullscreen="true" allowscriptaccess="always"></embed>
Now, if I access the url in that embed src, the video is loaded up and the URL of the page is changed with information about the video.
I am wondering if there is any way for me to access that info using PHP? I tried file_get_contents but it gives me lots of weird characters.
So, can I use PHP to load the embed url and get the information present in the address bar?
Thanks for all your help! :)
Yes, e.g. with the curl-library of php. This one will handle the redirect-headers from the server, which result in the new/real url of the video.
Here's a sample code:
<?php
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.4shared.com/embed/436595676/acfa8f75");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
// we want to further handle the content, so return it
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// grab URL and pass it to the browser
$result = curl_exec($ch);
// did we get a good result?
if (!$result)
die ("error getting url");
// if we got a redirection http-code, split the content in
// lines and search for the Location-header.
$location = null;
if ((int)(curl_getinfo($ch, CURLINFO_HTTP_CODE)/100) == 3) {
$lines = explode("\n", $result);
foreach ($lines as $line) {
list($head, $value) = explode(":", $line, 2);
if ($head == 'Location') {
$location = trim($value);
break;
}
}
}
if ($location == null)
die("no redirect found in header");
// close cURL resource, and free up system resources
curl_close($ch);
// your location is now in here.
var_dump($location);
?>

Callback from API not happening after posting parameters to API URL from server side

API integration description
The API needs a form to be posted to the API URL with some input fields and a customer token. The API processes and then posts response to a callback.php file on my server. I can access the posted vals using $_POST in that file. That's all about the existing method and it works fine.
Requirement
To hide the customer token value from being seen from client side. So I started with sending server side post request.
Problem
I tried with many options but the callback is not happening -
1) CURL method
$ch = curl_init(API_URL);
$encoded = '';
$_postArray['customer_token'] = API_CUSTOMER_TOKEN;
foreach($_postArray as $name => $value)
{
$encoded .= urlencode($name).'='.urlencode($value).'&';
}
// chop off last ampersand
$encoded = substr($encoded, 0, strlen($encoded)-1);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
$resp = curl_exec($ch);
curl_close($ch);
echo $resp;
$resp echoes 1 if the line curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); is removed but the callback does not happen. I am setting a session variable in the callback script to verify.Is it needed that the API be synchronous in order to use curl method, so that curl_exec returns the response?
2) without CURL as given in Posting parameters to a url using the POST method without using a form
But the callback is not happening.
I tried with the following code too, but looks like my pecl is not installed properly because the HttpRequest() is not defined.
$req = new HttpRequest($apiUrl, HttpRequest::METH_POST);
$req->addQueryData($params);
try
{
$r->send();
if ($r->getResponseCode() == 200)
{
echo "success";
// success!
}
else
{
echo "failure";
// got to the API, the API returned perhaps a RESTful response code like 404
}
}
catch (HttpException $ex)
{
// couldn't get to the API (probably)
}
Please help me out! I just need to easily send a server side post request and get the response in the callback file.
Try to debug your request using the curl_get_info() function:
$header = curl_getinfo($ch);
print_r($header);
Your request might be OK but it my result in an error 404.
EDIT: If you want to perform a post request, add this to your code:
curl_setopt($ch, CURLOPT_POST, true);
EDIT: Something else I mentioned at your code: You used a '1' at the 'CURLOPT_RETURNTRANSFER' but is should be 'true':
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
At least this is how I usually do it, and you never know if the function will also understand a '1' as 'true';
EDIT: The real problem: I copy-pasted your source and used it on one of my pages getting this error:
Warning: urlencode() expects parameter 1 to be string, array given in C:\xampp\htdocs\phptests\test.php on line 8
The error is in this line:
foreach($_postArray as $name => $value)
$_postArray is an array with one value holding the other values and you need either another foreach or you simple use this:
foreach($_postArray['customer_token'] as $name => $value)
As discussed in the previous question, the callback is an entirely separate thing from your request. The callback also will not have your session variables, because the remote API is acting as the client to the callback script and has its own session.
You should really show some API documentation here. Maybe we're misunderstanding each other but as far as I can see, what you are trying to do (get the callback value in the initial CURL request) is futile, and doesn't become any less futile by asking twice.

Categories