Save facebook profile image using cURL - php

I'm trying to save a users profile image on facebook using CURL. When I use the code below, I save a jpeg image but it has zero bytes in it. But if I exchange the url value to https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/211398_812269356_2295463_n.jpg, which is where http://graph.facebook.com/' . $user_id . '/picture?type=large redirects the browser, the image is saved without a problem. What am I doing wrong here?
<?php
$url = 'http://graph.facebook.com/' . $user_id . '/picture?type=large';
$file_handler = fopen('pic_facebook.jpg', 'w');
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_FILE, $file_handler);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($file_handler);
?>

There is a redirect, so you have to add this option for curl
// safemode if off:
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
but if you have safemode if on, then:
// safemode if on:
<?php
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
#list($header, $data) = #explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = #parse_url(trim(array_pop($matches)));
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (#$url['query']?'?'.$url['query']:'');
return $new_url;
} else {
$curl_loops=0;
return $data;
}
}
function get_right_url($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
return curl_redir_exec($curl);
}
$url = 'http://graph.facebook.com/' . $user_id . '/picture?type=large';
$file_handler = fopen('pic_facebook.jpg', 'w');
$curl = curl_init(get_right_url($url));
curl_setopt($curl, CURLOPT_FILE, $file_handler);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($file_handler);

If you can't process the redirect, try this instead:
Make the request to https://graph.facebook.com/<USER ID>?fields=picture and parse the response, which will be in JSON format and look like this - e.g. for Zuck you get this response:
{
"picture": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/157340_4_3955636_q.jpg"
}
Then make your curl request directly to retrieve the image from that cloud storage URL

set
CURLOPT_FOLLOWLOCATION to true
so that it follows the 301/302 redirect the reads the image file from final location.
i.e.
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

I managed to do it this way, works perfectly fine:
$data = file_get_contents('https://graph.facebook.com/[App-Scoped-ID]/picture?width=378&height=378&access_token=[Access-Token]');
$file = fopen('fbphoto.jpg', 'w+');
fputs($file, $data);
fclose($file);
You just need an App Access Token (APPID . '|' . APPSECRET), and you can specify width and height.
You can also add "redirect=false" to the URL, to get a JSON object with the URL (For example: https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xpa1...)
CURLOPT_FOLLOWLOCATION has been removed in PHP5.4, so it´s not really an option anymore.

Related

Translation On Telegram Bot

if (strpos($message, "/translate") === 0) {
$word = substr ($message, 10);
$mymemori = json_decode(file_get_contents("https://api.mymemory.translated.net/get?q=".$word."&langpair=en|id"), TRUE)["matches"]["translation"];
file_get_contents($apiURL."/sendmessage?chat_id=".$chatID."&text=Hasil translate: ".$word." : $mymemori ");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_string);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if(($html = curl_exec($ch)) === false) {
echo 'Curl error: ' . curl_error($ch);
die('111');
}
}
Hello guys i was trying to make translation bot on telegram using php but the output is still error or no output at all. Am using this API https://api.mymemory.translated.net/get?q=Hello%20World!&langpair=en|id
Please help how to get the translation
Error output IMAGES
First, I suggest using cURL, Not file_get_contents.
Second, No need to echo anything, Because the URL will be visited by webhook, Not a human.
Third, You need a method to send requests to Telegram Bot API.
Use this new code:
define('Token', '<your_bot_token>');
# Reading the update from Telegram
$update = json_decode(file_get_contents('php://input'));
$message = $update->message;
$text = $message->text;
if (strpos($text, '/translate') === 0) {
$word = substr ($message, 10);
$mymemori = json_decode(file_get_contents("https://api.mymemory.translated.net/get?q=".$word."&langpair=en|id"), TRUE)["matches"]["translation"];
//
Bot('sendMessage', [
'chat_id' => $update->message->chat->id,
'text' => "Hasil translate: $word : $mymemori "
]);
}
function Bot(string $method, array $params = [])
{
$ch = curl_init();
$api_url = 'https://api.telegram.org/bot' . Token . "/$method";
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
if ($result->ok == false)
{
throw new Exception($result->description, $result->error_code);
}
return $result->result;
}

How to get json for soundcloud without type

I get JSON from the Soundcloud API by using code in section【A】.
But I want to get it without using $type, like in code【B】.
In other words, I want to get that information by only giving $target.
What should I do?
$r = soundcloud_responce();
var_dump( $r );
function soundcloud_responce(){
$client_id = 'xxx';
$type = 'tracks';
$q = 'words';
// code【A】
// If I have $type, So this process ok.
$url = "https://api.soundcloud.com/";
$url .= $type;
$url .= "?client_id=$client_id";
$url .= "&q=$q";
// code【B】
// I want to do same process with $target but without $type
$target = "https://soundcloud.com/accountname/trackname";
$target = str_replace('https://soundcloud.com/', '', $target);
$url = "https://api.soundcloud.com/";
$url .= $target;
$url .= "?client_id=$client_id";
// curl
$ch = curl_init();
$headers = [
'Accept: application/json',
'Content-Type: application/json',
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$res = curl_exec($ch);
$json = json_decode($res);
curl_close($ch);
return $json;
}
(Add 2020-02-21-09:38 #Tokyo)
I tried this code【C】but this also failed.
// code【C】
// I tried with oembed but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = 'http://soundcloud.com/oembed?format=json&url='.$target;
(Add 2020-02-21-10:12 #Tokyo)
I tried this code【D】but this also failed.
// code【D】
// I tried with resolve but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = "https://api.soundcloud.com/resolve?url=$target&client_id=$client_id";
I tried this code【E】this is successful!
Thank you for giving me good advice, #showdev.
// code【E】
// this is successful!
$target = "https://soundcloud.com/accountname/trackname";
$target = urlencode($target);
$url = "https://api.soundcloud.com/resolve.json?url=$target&client_id=$client_id";

Redirect php script using CURL

I am trying to make a redirect php script, I want that script to check if the link exist and then redirect the user to the link, if it doesn't exist then it will get the next link and so on, but for some reason is not working, maybe you could give me some help on this.
<?php
$URL = 'http://www.site1.com';
$URL = 'http://www.site2.com';
$URL = 'http://www.site3.com';
$handlerr = curl_init($URL);
curl_setopt($handlerr, CURLOPT_RETURNTRANSFER, TRUE);
$resp = curl_exec($handlerr);
$ht = curl_getinfo($handlerr, CURLINFO_HTTP_CODE);
if ($ht == '404')
{ echo "Sorry the website is down atm, please come back later!";}
else { header('Location: '. $URL);}
?>
You are overwriting your $URL variable..
$URL = 'http://www.site1.com';
$URL = 'http://www.site2.com';
$URL = 'http://www.site3.com';
Put these urls in an array and go through it with a for each loop.
You have a few issues in your code. For 1, your $URL will overwrite itself, resulting in only 1 url in there. It needs to be an array:
array( 'http://www.site1.com', 'http://www.site2.com', 'http://www.site3.com' );
You can get many responses, not just a 404, so you should tell cURL to follow redirects. If the URL was a redirect itself, could get a 301 that redirects to a 200. So we want to follow that.
Try This:
<?php
function curlGet($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ( $httpcode == 200 ) {
return true;
}
return false;
}
$urlArray = array( 'http://www.site1.com', 'http://www.site2.com', 'http://www.site3.com' );
foreach ( $urlArray as $url ) {
if ( $result = curlGet($url) ) {
header('Location: ' . $url);
exit;
}
}
// if we made it here, we looped through every url
// and none of them worked
echo "No valid URLs found...";
http://php.net/manual/en/function.file-exists.php#74469
<?php
function url_exists($url) {
if (!$fp = curl_init($url)) return false;
return true;
}
?>
This will give you the url exists check.
to check multiple urls though, you need an array:
<?
$url_array = [];
$url_array[] = 'http://www.site1.com';
$url_array[] = 'http://www.site2.com';
$url_array[] = 'http://www.site3.com';
foreach ($url_array as $url) {
if url_exists($url){
// do what you need;
break;
}
}
?>
PS - this is completely untested, but should theoretically do what you need.

Detect if the url is redirecting before iframing it

i am building an app and i am stuck at some point, i am having an iframe that it's source is dynamically determined according to :
<?php
ini_set('display_errors','off');
$file = $_GET['file'];
$url = ('remotedomain. com/' .$file);
?>
now here is the iframe:
<iframe id="embed" src="<? echo $url; ?>"></iframe>
the point i am stuck at is sometime the url(that's the iframe source) is redirecting back to home page, i want to detect this redirect and if it will happen then the source of the iframe should be certain url for example mysite .com/page1.html
Use curl and the option CURLOPT_HEADER. It's something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/"); //your url
curl_setopt($CURL, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if (preg_match('#HTTP.{4} 30[34]#m', $result)) {
if (preg_match('#\vLocation: (.*)\v#m', $result, $matches)) {
echo "Found redirect: ", $matches[1], "\n";
}
}
You can instead use Guzzle, it will follow redirects.
$response = $client->get('http://github.com');
echo $response->getStatusCode();
// 200
echo $response->getEffectiveUrl();
// 'https://github.com/'
getEffectiveUrl(); will here print where it redirected to.
Something like this:
function getFinalUrl($url) //in your library
{
$client = new GuzzleHttp\Client();
$response = $client->get($url);
if (in_array($response->getStatusCode(), [303, 304], true)) {
$url = $response->getEffectiveUrl();
}
return $url;
}
And iframe:
<iframe id="embed" src="<?=getFinalUrl($url);?>"></iframe>
thanks every one who discussed this with me i have managed to do and here is the answer so if anyone need it:
$url = (remote site .com/' .$file);
$start_time = microtime(TRUE);
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($handle, CURLOPT_NOBODY, 1);
$response = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 302) {
$final_url = 'mysite .com/page1.php';
}
else {
$final_url = $url;
}
You can lookup the current URL of an iframe with the following javascript:
document.getElementById("iframe_id").contentWindow.location.href
You can compare this url to that of the homepage you want to avoid. If they match redirect them to your alternate URL

Check if links are broken in php

I wonder if there is any good PHP script (libraries) to check if link are broken? I have links to documents in a mysql table and could possibly just check if the link leads to a the document, or if I am redirected to anther url. Any idea? I would prefer to do it in PHP.
Might be related to:
Check link works and if not visually identify it as broken
You can check for broken link using this function:
function check_url($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$headers = curl_getinfo($ch);
curl_close($ch);
return $headers['http_code'];
}
You need to have CURL installed for this to work. Now you can check for broken links using:
$check_url_status = check_url($url);
if ($check_url_status == '200')
echo "Link Works";
else
echo "Broken Link";
Also check this link for HTTP status codes : HTTP Status Codes
I think you can also check for 301 and 302 status codes.
Also another method would be to use get_headers function . But this works only if your PHP version is greater than 5 :
function check_url($url) {
$headers = #get_headers( $url);
$headers = (is_array($headers)) ? implode( "\n ", $headers) : $headers;
return (bool)preg_match('#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers);
}
In this case just check the output :
if (check_url($url))
echo "Link Works";
else
echo "Broken Link";
Hope this helps you :).
You can do this in few ways:
First way - curl
function url_exists($url) {
$ch = #curl_init($url);
#curl_setopt($ch, CURLOPT_HEADER, TRUE);
#curl_setopt($ch, CURLOPT_NOBODY, TRUE);
#curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$status = array();
preg_match('/HTTP\/.* ([0-9]+) .*/', #curl_exec($ch) , $status);
return ($status[1] == 200);
}
Second way - if you dont have curl installed - get headers
function url_exists($url) {
$h = get_headers($url);
$status = array();
preg_match('/HTTP\/.* ([0-9]+) .*/', $h[0] , $status);
return ($status[1] == 200);
}
Third way - fopen
function url_exists($url){
$open = #fopen($url,'r');
if($handle !== false){
return true;
}else{
return false;
}
}
First & second solutions
As quick workaround check, you can use the global variable $http_response_header with file_get_contents() function.
For example (extracted from PHP documentation):
<?php
function get_contents() {
file_get_contents("http://example.com");
var_dump($http_response_header);
}
get_contents();
var_dump($http_response_header);
Then check the status code in first line for a "HTTP/1.1 200 OK" or other HTTP status codes.
Try this:
$url = '[your_url]';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
if ($result === false) {
echo 'broken url';
} else {
$newUrl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
if ($newUrl !== $url) {
echo 'redirect to: ' . $newUrl;
}
}
curl_close($curl);
if you looking for a solution in PHP Laravel. check this link
use Illuminate\Support\Facades\Http;
$response = Http::get('http://example.com');
$response->body() : string;
$response->json($key = null) : array|mixed;
$response->object() : object;
$response->collect($key = null) : Illuminate\Support\Collection;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->redirect(): bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;

Categories