weird problem with file_get_contents and twitter - php

I made this function to verify a user's twitter credentials. Its running on two different webservers.
<?
function twitauth($username, $password){
if(#file_get_contents("http://".$username.":".$password."#twitter.com//account/verify_credentials.xml")){
return "1";}
else {
return "0";}
}
?>
On my webserver, it works fine. On the other one, it ALWAYS returns 1! Even when password is intentionally wrong.
What in the world would cause one server to do one thing, and the other to do something else?

When I visit that url with any combination of username/password it always returns something, whether it's auth successful or failure. file_get_contents() only returns FALSE when it fails to open the requested url.
It seems to me for your function to be successful you would have to parse the return value to determine whether or not the auth was successful.

Remove the '#' sign from the function to see the error message (if there is one).
Some PHP configurations don't allow opening files over the HTTP protocol, so look into cURL, or try looking up the official Twitter API to see if they have authentication functions for you to use.

I came up with an alternative solution.
<?
function twitauth($username, $password){
$xml = #simplexml_load_file("http://".$username.":".$password."#twitter.com/statuses/friends_timeline.xml");
$noway = $xml->error;
$errorcheck = "Could not authenticate you.";
if($noway == $errorcheck){
return "0";
} else {
return "1";
}
}
?>

The # symbol (error suppression) in front of file_get_contents might be suppressing an error. Try removing it and see what error you get. Also, you might be seeing different behavior on different servers due to php configuration. Specifically, the allow_url_fopen setting changes file_get_contents ability to work with URLs. Check this setting on both servers (maybe with ini_get() or find the setting in the output of phpinfo().

Here is an updated response that isn't returning booleans as strings, and it's weird to check if its the error message before checking if its not the error message.
<?php
function twitauth($username, $password){
$xml = #simplexml_load_file("http://". urlencode($username) .":". urlencode($password) ."#twitter.com/statuses/friends_timeline.xml");
return ($xml->error != "Could not authenticate you.") ? true : false;
}
?>
file_get_contents() will only return the response of the page, which can be an authenticated user or a bad response, you need to use SimpleXML or what not to parse the response to determine whether or not they were authenticated. Which looks like:
<?xml version="1.0" encoding="UTF-8"?>
<user>
<id>800316</id>
<name>Garrett</name>
<screen_name>garrettb</screen_name>
<location>WHER>!, CA, USA</location>
<description>Build websites, wants to be rich, and loves my Mac. You?</description>
<profile_image_url>http://a1.twimg.com/profile_images/185221952/pic_normal.png</profile_image_url>
<url></url>
<protected>false</protected>
<followers_count>158</followers_count>
<profile_background_color>352726</profile_background_color>
<profile_text_color>3E4415</profile_text_color>
<profile_link_color>D02B55</profile_link_color>
<profile_sidebar_fill_color>99CC33</profile_sidebar_fill_color>
<profile_sidebar_border_color>829D5E</profile_sidebar_border_color>
<friends_count>139</friends_count>
<created_at>Wed Feb 28 06:03:17 +0000 2007</created_at>
<favourites_count>18</favourites_count>
<utc_offset>-28800</utc_offset>
<time_zone>Pacific Time (US & Canada)</time_zone>
<profile_background_image_url>http://s.twimg.com/a/1251845223/images/themes/theme5/bg.gif</profile_background_image_url>
<profile_background_tile>false</profile_background_tile>
<statuses_count>1781</statuses_count>
<notifications></notifications>
<verified>false</verified>
<following></following>
<status>
<created_at>Wed Sep 02 19:07:59 +0000 2009</created_at>
<id>3716655439</id>
<text>#lucaspatton09 take a picture, I want to see.</text>
<source><a href="http://www.atebits.com/" rel="nofollow">Tweetie</a></source>
<truncated>false</truncated>
<in_reply_to_status_id>3716512637</in_reply_to_status_id>
<in_reply_to_user_id>59230940</in_reply_to_user_id>
<favorited>false</favorited>
<in_reply_to_screen_name>lucaspatton09</in_reply_to_screen_name>
</status>
</user>
If the request is denied (bad access), it will have a authentication dialog drop down, which is probably causing you problems.

file_get_contents usually gives warning and returns nothing upon encountering http error code, but in case of your other server it probably returns body of error page (maybe it can be set up by some configuration).
Code below should work for both cases:
if(strpos(
#file_get_contents("http://".$username.":".$password."#twitter.com//account/verify_credentials.xml"),
"Could not authenticate you.") === false) {
echo "credentials ok";
} else {
echo "credentials not ok";
}

Related

PHP script to check on remote server, a file exists

I am having roblems with locating a PHP script to allow me to obtain the contents of a txt file on a remote server, then output to a variable. Outputting something to a variable is not the hard part. It's the picking up and reading the contents of the file that's the hard part. Anyone have any ideas?
I have trawled the forum and can only locate a method that works locally. Not ideal as the target is remote.
The objective really is, how do I find out if a file exists on the remote server and output a status in html.
Ideas?
Assuming your remote server is accessible by http or ftp you can use file_exists():
if (file_exists("http://www.example.com/somefile.txt")) {
echo "Found it!;
}
or
if (file_exists("ftp:user:password#www.example.com/somefile.txt")) {
echo "Found it!;
}
Use this:
$url = 'http://php.net';
$file_headers = #get_headers($url);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
echo "URL does not exist";
}
else {
echo "URL exists";
}
Source: http://www.php.net/manual/en/function.file-exists.php#75064
You can try to use this code:
if (file_exists($path)) {
echo "it exists";
} else {
echo "it does not exist";
}
As you can see $path is the path of your file. Of course you can write anything else instead of those echo.
Accessing files on other servers can be quite tricky! If you have access to the file via ftp, you can use ftp to fetch the file, for example with ftp_fget().
If you do not have access to the file-system via ssh, you only can check the response the server gives when requesting the file. If the server responds with an error 404, the file is either not existent or it is not accessible via http due to the server configuration.
You can check this through curl, see this tutorial for a detailled explanation of obtaining the response code through curl.
I know this is an old thread, but as Lars Ebert points out, checking for the existence of a file on a remote server can be tricky, so checking the server response, using cURL, is how I have been able to do it on our big travel site. Using file_exists() threw an error every time, but checking for a "200 OK" has proved quite successful. Here is the code we are using to check for images for our hotel listings page:
$media_url = curl_init("http://pathto/remote_file.png");
curl_setopt($media_url, CURLOPT_RETURNTRANSFER, true);
$media_img = curl_exec($media_url);
$server_response = curl_getinfo($media_url, CURLINFO_HTTP_CODE);
if($server_response != 200){
echo "pathto/graphics/backup_image.png";
}else{
echo "http://pathto/remote_file.png";
}
Where "http://pathto/remote_file.png" is the remote image we seek, but we need to know whether it is really there. And "pathto/graphics/backup_image.png" is what we display if the remote image does not exist.
I know it's awfully verbose, compared to file_exists(), but it's also more accurate, at least so far.

I am getting an Error (-32300): transport error - HTTP status code was not 200

I am getting an Error when I try to upload data using xmlrpc in wordpress. The code used to work fine but all of a sudden this error started appearing. I have not changed anything in the code.
Error (-32300): transport error - HTTP status code was not 200
Also, I know my script works because google chrome returns an 'ok' status on the GET request.
php.ini has 128mb of memory allocated.
Here is the code that is used to make post
/**
* Make Posts using the XMLRPC classes
*/
function makePosts() {
$data_set = $this->getMovieLinks();
$xml_client = new XMLRPClientWordPress();
foreach ($data_set as $key) {
echo '<pre>';
echo 'This is title movie about to be added ======== : ' . $key['title'];
echo '</pre>';
//new_post($title,$summary,$category,$image_url,$internal_links)
if ($xml_client->new_post($key['title'], $key['summary'], $key['category'], $key['image'], $key['internal_links']) ) {
$status=1;
} else {
$status=0;
}
if (isset($status)) {
echo ' ====== ADDED';
} else {
echo ' ====== ERROR ADDING';
}
}
} // Function makePosts endes here
You can do few things to debug the error.
Take a look in the server logs, maybe they include the real reason for the problem.
Look for "memory_limit" in your php.ini. Try higher number and see whether that's the problem.
Try deactivating one plugin at a time, May be one plugin may causing the error.
I received the same error, finally I found out the reason was I that I enabled such code in .htaccess (XML-PRC server side); I was blocked myself.
order deny,allow
deny from all
allow from 211.111.0.0/16
The server hosted "http://example.com/xmlrpc.php" was blocked post script IP source.
You should:
Add the XML-RPC client script IP to XML-PRC server side; even the client and server in same site.
Or simply remove "deny from all" from .htaccess
I have the same error but i solved it :
I typed http://www.example.com/xmlrpc.php but the good is http://example.com/xmlrpc.php because if it have "www" prefix it redirected with staus cod
If none of the above solutions work:
Make sure you are not being white-listed on the hosting provider. Our client uses wp-engine and we had this exact issue when posting media items.
After making the same request on an outside network, different IP, we got a 200 (OK) status code.

function.file-get-contents - failed to open stream [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
file_get_contents with query string
I'm using the file_get_contents function but although returning the correct output, it is still showing this error:
Warning: file_get_contents(secure/validate.php?cardnumber=1234567) [function.file-get-contents]: failed to open stream: No error in ...
The scenario is card number validation and in validatecard.php there is a simple if statement:
if (isset($_GET['cardnumber']) && ($_GET['cardnumber'] == "12345")) {
echo "OK";
} else {
echo "INVALID CARD";
}
My code is:
$cardnumber = $_POST["cardnumber"];
$url = "secure/validate.php?cardnumber=" . $cardnumber;
if (file_get_contents($url) != "OK"){
$order_error_msg = "Invalid card number";
} else { ....
What may be the problem?
Well, it seems like you don't have allow_url_fopen set in your php.ini #Gordon is correct, this is not a url_fopen issue. It's actually failing because using file_get_contents on the local file will actually get you the code for the file, not the PHP-processed result of running that file. To get it to work as you wanted, you'd need to hit apache/PHP by prepending "https://localhost/" to the url, and enabling allow_url_fopen.
But also this looks like a very worrying piece of code; you should do as little as possible with CC numbers in the code. By using file_get_contents and a card number on the get string, it opens up the possibility of the number being logged somewhere.
A much more secure implementation would look something like this:
validatecard.php
function checkCard($card) {
if ($card == "12345")) {
return "OK";
} else {
return "INVALID CARD";
}
}
Then in your main code:
include('secure/validatecard.php');
$cardnumber = $_POST["cardnumber"];
if (checkCard($cardnumber) != "OK"){
$order_error_msg = "Invalid card number";
} else { ....
That way your checkCard function is more re-usable, and you don't have to ferry the card number around so much.
If you decide to go with the file_get_contents approach and hit https://localhost/secure/validatecard.php?card=12345 then the credit card numbers will get logged in your apache access logs in plain text. This is verging on criminally negligent, don't do it.
also, as per Gordon's advice, make sure that you're using https all the way through.
You might consider hiring in a contractor with experience writing shopping carts/checkouts. These things are important to get right, and can be insecure in subtle ways if you're not experienced.
are you sure your php.ini configuration allows for opening urls?
you can check using phpinfo() and searching for allow_url_fopen
also, as another poster noted , using GET for this kind of stuff isn't really ideal (read: really really bad). if you're keen on making a request to another page, rather than using a file (if that other page is not on your server, for example), try using cURL and do a POST request

PHP proxy - return response in case of error

I use PHP as proxy (for JS XMLHttpRequest).
In the following code:
handle = #fopen(...);
if (!$handle)
{
,,,
}
I want to return the response (header + body) from the server in case i enter the IF.
How can i do that?
You could return the HTTP status you think is appropriate when fopen fails, e.g.:
if (!$handle) {
header('HTTP/1.1 500 Internal Server Error');
// header('HTTP/1.1 404 Not Found');
die();
}
You're better off using cURL than fopen. Not only is it faster, but IIRC you have finer-grained control over the options.
Edit: It's been suggested that I give an example of how to use this. The best examples are within PHP's documentation - http://www.php.net/manual/en/curl.examples-basic.php This example is pretty close to what I think you're wanting to do. You'd need to change the CURLOPT_HEADER option to 1 or TRUE.
There are a ton of options you can use to customize how cURL behaves. This page will tell you everything: http://www.php.net/manual/en/function.curl-setopt.php
If you've got the time, I'd recommend skimming through the cURL documentation - http://www.php.net/manual/en/book.curl.php It's a powerful extension and very useful.
Your if statement says if(!$handle), meaning "if fopen() fails". If fopen() fails, you're not going to be able to read a response body or header. The return value from fopen() is the only handle to the data coming back from the server.
UPDATE:
Here's an example of how to get the information using error_get_last() instead of $handle:
<?php
$handle = fopen("http://www.google.com/doesntwork.html","r");
if (!$handle){
$error = error_get_last();
$m=array();
$i = preg_match('/(HTTP\/1.[01]) ([0-9]+) (.*)/',$error['message'],$m);
if($i){
echo "HTTP version: ".$m[1]."<br>\n";
echo "HTTP status: ".$m[2]."<br>\n";
echo "HTTP message: ".$m[3]."<br>\n";
}
} else {
$output="";
while(!feof($handle)){
$output .= htmlspecialchars(fgets($handle, 1024));
}
fclose($handle);
echo "fopen returned with result: $output<br>\n";
}
?>
As another user posted, you're better off using fopen() wrappers and/or cURL. Also, you shouldn't suppress warnings/errors...remove the # symbol and fix any errors that come up.

How to check if a webpage exists. jQuery and/or PHP

I want to be able to validate a form to check if a website/webpage exists. If it returns a 404 error then that definitely shouldn't validate. If there is a redirect...I'm open to suggestions, sometimes redirects go to an error page or homepage, sometimes they go to the page you were looking for, so I don't know. Perhaps for a redirect there could be a special notice that suggests the destination address to the user.
The best thing I found so far was like this:
$.ajax({url: webpage ,type:'HEAD',error:function(){
alert('No go.');
}});
That has no problem with 404's and 200's but if you do something like 'http://xyz' for the url it just hangs. Also 302 and the like trigger the error handler too.
This is a generic enough question I would like a complete working code example if somebody can make one. This could be handy for lots of people to use.
It sounds like you don't care about the web page's contents, you just want to see if it exists. Here's how I'd do it in PHP - I can stop PHP from taking up memory with the page's contents.
/*
* Returns false if the page could not be retrieved (ie., no 2xx or 3xx HTTP
* status code). On success, if $includeContents = false (default), then we
* return true - if it's true, then we return file_get_contents()'s result (a
* string of page content).
*/
function getURL($url, $includeContents = false)
{
if($includeContents)
return #file_get_contents($url);
return (#file_get_contents($url, null, null, 0, 0) !== false);
}
For less verbosity, replace the above function's contents with this.
return ($includeContents) ?
#file_get_contents($url) :
(#file_get_contents($url, null, null, 0, 0) !== false)
;
See http://www.php.net/file_get_contents for details on how to specify HTTP headers using a stream context.
Cheers.
First you need to check that the page exists via DNS. That's why you say it "just hangs" - it's waiting for the DNS query to time out. It's not actually hung.
After checking DNS, check that you can connect to the server. This is another long timeout if you're not careful.
Finally, perform the HTTP HEAD and check the status code. There are many, many, many special cases you have to consider here: what does a "temporary internal server error" mean for the page existing? What about "permanently moved"? Look into HTTP status codes.
I've just written a simpler version using PHP:
function url_check($url) {
$x = #fopen($url,"r");
if ($x) {
$reply = 1;
fclose($x);
} else {
$reply = 0;
}
return $reply;
}
Obviously $url is the test URL, returns true (1) or false (0) depending on URL existence.
Maybe you could combine domain checker, and jQuery, domain checker (PHP) can respond 1 or 0 for non-existent domains.
eg. http://webarto.com/snajper.php?domena=stackoverflow.com , will return 1, you can use input blur function to check for it instantly.

Categories