Get Facebook real profile image URL - php

According to Facebook graph API we can request a user profile picture with this (example):
https://graph.facebook.com/1489686594/picture
We don't need any Token since it's a public information.
But the real image URL of the previous link is: http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs356.snc4/41721_1489686594_527_q.jpg
If you type the first link on your browser, it will redirect you to the second link.
Is there any way to get the full URL (second link) with PHP, by only knowing the first link?
I have a function that gets the image from a URL to store it in the database, but it does work only if it get the full image URL.
Thanks

kire is right, but a better solution for your use case would be the following:
// get the headers from the source without downloading anything
// there will be a location header wich redirects to the actual url
// you may want to put some error handling here in case the connection cant be established etc...
// the second parameter gives us an assoziative array and not jut a sequential list so we can right away extract the location header
$headers = get_headers('https://graph.facebook.com/1489686594/picture',1);
// just a precaution, check whether the header isset...
if(isset($headers['Location'])) {
$url = $headers['Location']; // string
} else {
$url = false; // nothing there? .. weird, but okay!
}
// $url contains now the url of the profile picture, but be careful it might very well be only temporary! there's a reason why facebok does it this way ;)
// the code is untested!

You can get it with FQL:
select pic_square from user where uid=1489686594
returns:
[
{
"pic_square": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs356.snc4/41721_1489686594_527_q.jpg"
}
]
Also you can just improve your function that gets picture by url. If you use curl it can automatically follow redirect headers.

Please note that the The Surrican's answer (and possibly others) can drastically increase your script's response time (around +500ms for me on my server). This is because the server issues a request to facebook (because of get_headers()) and the execution time (computation excluded) extends from this:
browser -> server
server -> browser
to this:
browser -> server
server -> facebook (request: get_headers)
facebook -> server (response: get_headers)
server -> browser
This adds the mentioned 500ms delay. You probably should consider to cache the real url on your server or to load the profile picture via JavaScript. At least take a look at your response time before and after ;)

#The Surrican,
Nice code! Here is a clean cut code function for such process!
function get_raw_facebook_avatar_url($uid)
{
$array = get_headers('https://graph.facebook.com/'.$uid.'/picture?type=large', 1);
return (isset($array['Location']) ? $array['Location'] : FALSE);
}
This will return the RAW facebook avatar image URL. Feel free to do whatever you want with it then!

You can also add ?redirect=false to the end of your URL and then parse the JSON response directly.
In your example: https://graph.facebook.com/1489686594/picture?redirect=false
More information here https://developers.facebook.com/docs/graph-api/reference/user/picture/

Related

Deep linking an app in PHP is not working

I have a webpage that needs to check to see if an app exists using a deep link, but it doesn't seem to work like it should. I have tried the following things.
Using a redirect in PHP (Doesn't work)
header('Location: exampleapp://param=test');
Using a redirect using JavaScript (Doesn't work)
var appurl = 'exampleapp://param=test';
var appstore = 'https://itunes.apple.com/us/app/...';
var timeout;
function preventPopup() {
clearTimeout(timeout);
timeout = null;
window.removeEventListener('pagehide', preventPopup);
}
function startApp() {
window.location = appurl;
timeout = setTimeout(function(){
if(confirm('You do not seem to have the App installed, do you want to go download it now?')){
document.location = appstore;
}
}, 100);
window.addEventListener('pagehide', preventPopup);
}
// app start is then called in the onload
Same as above but replace the the line window.location = appurl; with document.getElementById('deeplink').click(); and adding a link in the html's webpage. (Works) <a id="deeplink" href="exampleapp://param=test">Deep Link</a>
Is there a reason why you can't redirect using a header in PHP?
The PHP version doesn't work, because of the way HTTP works. The HTTP protocol doesn't specify that it should work to redirect to a different protocol from within the "Location:" header. There is nothing specific to PHP here, it's a HTTP issue.
The Javascript version doesn't work because you wanted to set the windows location. And the window cannot show the contents of "exampleapp://..." . You want the link to open like when the user clicks on it. Instead of using window.location you may use document.location.href. That should work.
Another problem:
in your code you write exampleapp:// in 1) and 2). And in 3) you write testapp:// - make sure you use the same URL in all three cases, so that you can be sure that the URL can work eventually..
The answer is to use Apples implementation called 'Smart Banners'
<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">
You can include three comma-separated parameters in the content
attribute:
app-id: (Required.) Your app's unique identifier. To find your app ID
from the iTunes Link Maker, type the name of your app in the Search
field, and select the appropriate country and media type. In the
results, find your app and select iPhone App Link in the column on the
right. Your app ID is the nine-digit number in between id and ?mt.
affiliate-data: (Optional.) Your iTunes affiliate string, if you are
an iTunes affiliate. If you are not, find out more about becoming an
iTunes affiliate at http://www.apple.com/itunes/affiliates/.
app-argument: (Optional.) A URL that provides context to your native
app. If you include this, and the user has your app installed, she can
jump from your website to the corresponding position in your iOS app.
Typically, it is beneficial to retain navigational context because: If
the user is deep within the navigational hierarchy of your website,
you can pass the document’s entire URL, and then parse it in your app
to reroute her to the correct location in your app. If the user
performs a search on your website, you can pass the query string so
that she can seamlessly continue the search in your app without having
to retype her query. If the user is in the midst of creating content,
you can pass the session ID to download the web session state in your
app so she can nondestructively resume her work. You can generate the
app-argument of each page dynamically with a server-side script. You
can format it however you'd like, as long as it is a valid URL.
https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html

Get Request to an API url

I have signed up to a synonym API.. see the details on this page
I am having trouble implementing this in my php code.
If I copy and paste the link into the web browser, I can see the results no problem.
Instead of typing the word in manually, I wish to have a variable in the link with the relevant word i.e. $variable_with_word_stored as shown below.
http://words.bighugelabs.com/api/2/xxxxxxxx/$variable_with_word_stored/php
//format could be php (I would unserialize)..or json..I could decode it?
Any ideas guys? Thanks.
It sounds like you mean you want the result from calling that webpage and store it in a variable. What you should be looking to do is sending a http get request to that page within the code.
Check out using curl with php, you can send a http request to your requested url, capture the result back and parse it through json_decode
http://php.net/manual/en/curl.examples-basic.php
try it like this, maybe that you dont need curl:
$key = "xxxxxxxx";
$word = "love";
echo file_get_contents("http://words.bighugelabs.com/api/2/$key/$word/php");

Hide MP3 full url

I have a music player that links to a song using the following syntax:
<li>title</li>
Is there any way that I could have that executed server side and then be displayed like (see below) for the user?
While searching, I ran across this...I like the idea behind having an external file that has the data...like:
<?php
// get-file.php
// call with: http://yoururl.com/path/get-file.php?id=1
$id = (isset($_GET["id"])) ? strval($_GET["id"]) : "1";
// lookup
$url[1] = 'link.mp3';
$url[2] = 'link2.mp3';
header("Location: $url[$id]");
exit;
?>
then using: http://yoururl.com/path/get-file.php?id=1 as the link...the only problem is that when you type http://yoururl.com/path/get-file.php?id=1 the user goes straight to the file...is there any way to disable that ability...maybe some code on get-file.php itself?
Ok, so I did a combination of things that I am satisfied with...although not completely secure, it definitely helped me obscure it quite a bit.
First of all, I am using the AudioJS player to play music - which can be found: http://kolber.github.com/audiojs/
Basically what I did was:
Instead of using "data-src" as the path to my songs I called it "key", that way people wouldn't necessarily think it was a path.
Instead of using "my-song-title" as the name of the songs, I changed it to a number like 7364920, that way people couldn't look for that in the source and find the url that way.
I added + "mp3" to the javascript code after all of the "key" variables, that way I would not have to declare it in obfusticated link.
I used a relative path like "./8273019283/" instead of "your-domain.com/8273019283/", that way it would be harder to tell that I was displaying a url.
Added an iTunes link to the href, that way people might get confused as to how I was pulling the file.
So, now my inline javascript looks like:
<script type="text/javascript">
$(function() {
// Play entire album
var a = audiojs.createAll({
trackEnded: function() {
var next = $("ul li.playing").next();
if (!next.length) next = $("ul li").first();
next.addClass("playing").siblings().removeClass("playing");
audio.load($("a", next).attr("key") + "mp3");
audio.play();
}
});
// Load the first song
var audio = a[0];
first = $("ul a").attr("key") + "mp3";
$("ul li").first().addClass("playing");
audio.load(first);
// Load when clicked
$("ul li").click(function(e) {
e.preventDefault();
$(this).addClass("playing").siblings().removeClass("playing");
audio.load($('a', this).attr('key') + "mp3");
audio.play();
});
});
</script>
My link looks like:
Falling
When you load it up in the browser and you view the source you'll see:
Falling
Then when you use Web Inspector or Firebug you'll see:
Falling - *which doesn't completely give the url away
Basically what I did was make the link look like it's an api-key of some-kind. The cool thing is that you can't just copy the link straight from view source or straight from Web Inspector/Firebug. It's not fool-proof, and can definitely be broken, but the user would have to know what they're doing. It keeps most people away, yet still allows the player to get the url it needs to play the song :)
*also, I got the php obfusticate script from somewhere on Stack Exchange, just not sure where.
Instead of doing a header redirect, add proper headers and include the audio file in your PHP code. Then, in your .htaccess file, you can disallow access to the directory where your audio files live.
If you are using amazon s3 service you can use signed url for your files. It will be more safe as you have to be signed user and also url can be expired. Read this.
No. This is not possible since it is the browser that interprets the HTML to make the page work properly. So if the client (browser) does not know where the mp3 is coming from then it will not be there to use.
On the other hand if you want to have the music switch songs by clicking a link then i suggest you look into some tools like http://jplayer.org/
EDIT: The only way to probably prevent direct access to the file itself would be to read the file in instead of linking to it from the script. For instance on my image hosting site http://www.tinyuploads.com/images/CVN5Qm.jpg and if you were to look at the actual file path on my server, the file CVN5Qm.jpg is out of view from the public_html folder. There is no way to directly access the file. I use databases to take the image id, look up where it is stored, and then readfile() it into the script and display the proper headers to output the image.
Hope this helps
I use http_referer and I can controll the procedence of the link
<?php
// key.php
// call with: http://yoururl.com/path/key.php?id=1
$page_refer=$_SERVER['HTTP_REFERER'];
if ($page_refer=="http://www.yourdomine.com/path/page.html")
{
$id = (isset($_GET["id"])) ? strval($_GET["id"]) : "1";
// lookup
$url[1] = 'link1.mp3';
$url[2] = 'link2.mp3';
header("Location: $url[$id]");
exit;
}
else
{
exit;
}
?>

Why is image request generating a 302?

I'm using PHP to generate the following image element:
<img id="uploaded-image" src="http://localhost/gonzo/plans/image/123/tablemap.png" />
This image URL is routed through my PHP MVC framework to the following function, which grabs the image from my db and prints it:
public function image($hexCode='',$fileName) {
if (!$this->validRequest('get')) return false;
Framework::loadModel('plan_model.php');
$plan = new PlanModel();
// Return image data from Blob field in db.
$image = $plan->getImage('123');
if ($image) {
header("Content-Type: image/png");
print $image;
die;
} else {
echo 'error';
}
}
The request generates a 302, with the wrong location and content-type headers:
The browser does not display the image where this image tag is on the page. But, when the image URL is typed directly into the address bar, the image is displayed.
Why would my server be generating a 302 when loading the image into an tag, but generating a 200 when the image URL is typed directly into the address bar? I'm running Apache on Windows.
The described behavior isn't possible at all - since the server doesn't know a bit about how an URL is embedded in a web-page.
Provide more details of the actual call of the PHP-script: Print environmental details - $_GET, $_POST and $_SERVER - to a log file.
It might be helpful to register a tick-function and trace each executed statement to a log-file.
Check your PHP sources.
It turns out that this was caused by a strange concurrency problem. My framework was still processing the first request (which generated the page containing the img element) while the browser requested the image.
In other words, when the browser requested the image, it was still receiving output from the first request to the script. This made things go wacky.
Output buffering didn't solve the problem, but possible solutions are:
Pause execution of the second (image request) script for a sufficient amount of time to let the first one complete.
Host the image serving script on a separate subdomain.

php curl for facebook post tweet

I want post tweets into facebook using php curl , this is my snippet I used for posting tweet into FB - FB CURL SNIPPET
But i am not find any updated tweet in my facebook,
am not sure but i thing somthing goes wrong,
Can you tell me, snippet is correct one or not?
Thanks
This calls for debugging.
First port of call: It could be that the cookies are not saved: Check whether the script actually generates a my_cookies.txt file. If it doesn't, create an empty one and do a chmod 777 on it.
Second port of call: curl_error().
Replace every curl_exec() call in the snippet by this:
$success = curl_exec(....... your options .....);
if (!$success) echo "CURL Error: ".curl_error();
this might give you some pointers as to what goes wrong.
However, seeing as the script tries to imitate a browser instead of using an API, it could be that the structure of the submission form has changed on Facebooks's side, in which case you'll have to parse the output cURL gives you and see what goes wrong.
All in all, if there is any way to do this cleanly through an API - I don't know whether there is - it would be much preferable to this.

Categories