The following code tries to run file_get_contents for a facebook url based on access token:
$access_token=$ret["oauth_token"];
$fbid=$ret["oauth_uid"];
$url ="https://api.facebook.com/method/friends.getAppUsers?format=json&access_token=$access_token";
try {
$content = file_get_contents($url);
if ($content === false) {
$common_friends = array("error_code" => "something");
} else {
$common_friends = json_decode($content,true);
}
} catch (Exception $ex) {
//Who cares
}
All the Facebook settings are correct, the only potential problem is that the access token is no longer valid. In that case I receive the warning of
file_get_contents(): php_network_getaddresses: getaddrinfo failed:
Name or service not known
How can I upgrade my code, so if the facebook user access token is expired/invalid, file_get_contents will not give a warning, but fail gracefully?
EDIT:
$content = #file_get_contents($url);
still shows the same warning, however, I want to get rid of it. NetBeans also warns me that error control operator is misused. I have modified my code as follows:
try {
User::checkFacebookToken();
//file_get_contents sends warning message when token does not exist
//the problem is already handled, therefore these warnings are not needed
//this is why we set scream_enabled to false temporarily
ini_set('scream.enabled', false);
$content = file_get_contents($url);
ini_set('scream.enabled', true);
if ($content === false) {
$common_friends = array("error_code" => "something");
} else {
$common_friends = json_decode($content,true);
}
} catch (Exception $ex) {
//Who cares
}
I hope that scream.enabled is only temporarily changed to false.
You could alternatively use cURL which has better server response handling and you can display the error gracefully.
$access_token = 'your_access_token';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://api.facebook.com/method/friends.getAppUsers?format=json&access_token=$access_token");
curl_setopt($curl, CURLOPT_VERBOSE, 0);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($curl);
$response = curl_getinfo($curl);
echo '<pre>';
print_r($response);
if(!curl_errno($curl)){
// Server request success, but check the API returned error code
$content = json_decode($content, true);
print_r($content);
echo $content['error_code'];
echo $content['error_msg'];
}else {
// Server request failure
echo 'Curl error: ' . curl_error($curl);
}
curl_close($curl);
PhpFiddle
SOLUTION 1 : ensure that warnings will not be printed on main output
just add '#' to 'file_get_contents()' to suppress warning since you catched the error correctly by :
error_reporting(E_ERROR | E_PARSE);
if(#file_get_contents() === FALSE) {
// handle this error/warning
}
SOLUTION 2 : verify that you have a valid Facebook token before doing your request, Using Facebook API
$ch = curl_init();
// you should provide your token
curl_setopt($ch, CURLOPT_URL, "http://graph.facebook.com/me?access_token=52524587821444123");
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
$output = json_decode("[" . curl_exec($c) . "]");
if(is_array($output) && isset($output[0]->error)) {
print "Error Message : " . $output[0]->error->message . "<br />";
print "Error Type : " . $output[0]->error->type . "<br />";
print "Error Code : " . $output[0]->error->code . "<br />";
}else {
// do your job with file_get_contents();
}
curl_close($c);
Related
I use code like that shown on the first part below to download a file from an external site that isn't mine. The token is required and if it isn't valid the download fails. I want to duplicate that action with my own site. I have control over both the sending and receiving servers but can't get this to work. Would someone explain what I am doing wrong, please?
Here is the code on the sending server:
$url = "https://example.com/download/index.php?token=$someid";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '1');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, '1');
curl_exec($ch);
try {
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
}
catch (Exception $e){ echo $e->getMessage(); }
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode == 200) {
handle the downloaded file
} else {
echo 'Result = '. $statusCode;
}
And this is on my site (the receiving server). The true is just for testing so when I execute the above code I should get a 404 but it just shows "Result =".
if (true || ! empty($_GET['token'])) {
header("HTTP/1.1 404 Not Found");
exit;
}
header("Location: http://example.com/myfile.zip");
exit;
I'm trying to implement reCAPTCHA in my website, everything seems working fine, except the return from file_get_contents().
Here is my code:
if ($_REQUEST["send"] == 1){
// access
$secretKey = 'my_key';
$captcha = $_POST['g-recaptcha-response'];
$ip = $_SERVER['REMOTE_ADDR'];
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip);
$responseKeys = json_decode($response,true);
echo ($responseKeys);exit;
if(intval($responseKeys["success"]) !== 1) {
$message = 'Invalid reCAPTCHA';
} else {
$msg = 'content';
send_mail('send_to',"Subject",$msg);
header("location:index.php?send=1");exit;
}
}
My variable response is returning empty.
I tried to open https://www.google.com/recaptcha/api/siteverify? inserting manually the variables and it seems to work fine.
Am I forgeting something?
Thanks
Their API waiting for a POST request. Your code send GET request.
See answer here How to post data in PHP using file_get_contents?
My wrappers were disabled, reason why I couldn't reach the URL and get the return.
As I don't have access to php.ini the workaround was send the request with curl, here is the code:
$url = "https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip;
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo curl_error($ch);
echo "\n<br />";
$response = '';
} else {
curl_close($ch);
}
if (!is_string($response) || !strlen($response)) {
echo "Failed to get contents.";
$contents = '';
}
$responseKeys = json_decode($response,true);
Hope anyone can help me out with this. I have tried to call external site using cURL but I get no error or response. Yet it works fine on local server but does not work on production server. I had started the call using file_get_contents() but fail online too. I talked to the hosting and they mentioned the problem is within codes. here is my codes can anyone help!?`
function send_with_curl($url, $data) {
$data_string;
//url-ify the data for the POST
foreach ($data as $key => $value) { $data_string .= $key . '=' . $value . '&';
}
rtrim($data_string, '&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, count($data));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
if (!is_string($result) || !strlen($result)) {
$result = "Failed to connect.";
}
//close connection
curl_close($ch);
return $result;
}
I also have another function that uses file_get_contents() and whichever I may use they work locally but fail online without an error I spent more than 4 hours trying to fix it with hosting guys until they finally said the error is within codes and they weren't familiar with those codes :(
function send_with_file($url, $context, $sender) {
global $database;
if (!$result = file_get_contents($url, false, $context)) {
echo "Message sending failed, please check your internet.";
exit ;
} else {
//--UPDATING THE DATABASE------
$sql_update = "SELECT * FROM users WHERE users_type='2'";
$query_update = $database -> query($sql_update);
while ($update = $database -> fetch_array($query_update)) {
$update_user = $update['users_id'];
if ($update_user == $sender) {
if ($result === FALSE) {/* Handle error */
}
} else {
}
}
}
return $result;
}
Compare $result against false and then check curl_error()
Something like...
$result = curl_exec($ch);
if($result === false) {
echo "Error in cURL : " . curl_error($ch);
}
There was no problem with the codes, I just traced the url I was trying to connect to and realized it takes too long to communicate with the hosting server.
I'm using the code below to query an api however I'm not seeing any output. The header is returned however I also get an error - "An error has occurred:" with nothing else - not very helpful to say the least. Does anyone know what I'm doing wrong here? (NB I've had to remove the user details for obvious reasons)
//Required Call Information;
$username = "xxxxxxxxxxxxx";
$password = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
$remote_url = 'https://xxxxxxxxxxxxx.com/xx.json';
// init the resource
$ch = curl_init();
//Header Information;
$headr = array();
$headr[] = "Authorization: Basic " . base64_encode("$username:$password");
$headr[] = "X-Page:" . $pages;
// set curl options
curl_setopt($ch, CURLOPT_URL,$remote_url);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headr);
curl_setopt($ch, CURLOPT_HEADER, true);
// execute
$output = curl_exec($ch);
// echo
echo $output;
// echo
print $output;
// free
curl_close($ch);
// check status of server being called vis crul
var_dump(curl_getinfo($ch));
//if error
if (!curl_exec($ch)) {
// if curl_exec() returned false and thus failed
echo 'An error has occurred: ' . curl_error($ch);
}
else {
echo 'everything was successful';
}
Adding the RETURN_TRANSFER curl opt will return data rather than a boolean when $output = curl_exec($ch); is called.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
Add in the following curl opt and see what you get back:
curl_setopt($ch, CURLOPT_VERBOSE, true);
I have a slight issue whereby the API I'm using for part of my service uses a rsp stat to handle the success / error messages in XML.
So we use a form to post it data and it returns the data like the following example:
<rsp stat="ok">
<success msg="accepted" transactionid="505eeb9c43969d4919c0a6b3f7a4dfbb" messageid="a92eff8d65cf48e9c6e96702a7b07400"/>
</rsp>
The following is most of the script used :
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
// ToDo: Replace the placeholders in brackets with your data.
// For example - curl_setopt($ch, CURLOPT_UsERPWD, 'SMSUser:PassW0rD#');
curl_setopt($ch, CURLOPT_USERPWD, '');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
$xml = curl_exec($ch);
if (curl_error($ch)) {
print "ERROR ". curl_error($ch) ."\n";
}
curl_close($ch);
print_r($xml);
The only problem is that when it is parsed and displayed via the print_r command , it only displays via source code for some strange reason and we have no idea how to display it via the page
Basically we would like a system whereby if rsp stat="ok" then "Sent" else "unsent".
Well, a simple way could be:
if (strpos($xml, 'stat="ok"') !== false) {
echo "sent";
} else {
echo "unsent";
}
http://codepad.org/pkzsfsMk
This would replace print($xml);.
Put that code in a function, and have the function return your $xml.
Assuming you had a function called getRspStat() you could just do like:
echo getRspStat();
If you do something like that:
(see also on CodePad.org)
function xmlRequestWasSuccessful($xml) {
$result = simplexml_load_string($xml);
$result = (string)$result['stat'];
if ($result == 'ok') {
return true;
} else {
return false;
}
}
$xml = '<rsp stat="ok">
<success msg="accepted" transactionid="505eeb9c43969d4919c0a6b3f7a4dfbb" messageid="a92eff8d65cf48e9c6e96702a7b07400"/>
</rsp>';
$stat = xmlRequestWasSuccessful($xml);
you will receive 'true' boolean in the result ($stat variable). Adapt it to support the case when there is an error. Since no details on how it looks when error occurs, this is how you can do it now:
if ($stat) {
// do something on success ('sent' something)
} else {
// do something on success (display 'unsent' message for example)
}