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

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

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.

PHP exit() vs if - else statement

Is it a good or bad practice to authenticate and then just exit() the function or to wrap the whole result of the authentication in an if statement? Example
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false) exit();
//continue with senstive code here
}
}
OR
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == true)
{
// do sensitive stuff
}
}
I would like to take this opportunity to talk about exit; (as others have stated both work, the second is more explicit then the first, and give you the opportunity to send a nice error message to the user). My main beef (I have several with exit;) is that people should stop using it in libraries, i.e. code that can/will be used in other projects... You know how irritating it is to debug those? Throw exceptions, trigger fatal errors, but give me something with a description.
/rant
Your examples are equivalent.
However, it's not usually useful to the end user to just exit the script abruptly. Instead, send your user a useful error message printed in HTML rather than the plain text you would get from a die() call, for example.
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false)
{
$errormsg = "You are not allowed to view this page";
}
else
{
//continue with senstive code here
}
}
Later, print the error in HTML, rather than just aborting the script:
<div class='error'><?php echo $errormsg; ?></error>
Either or. I don't think it'll make a difference. It relatively the exact same thing. In programming there are many ways to program things, never on right way in most instances.
They are absolutely the same. The indentation and coding style is the only difference. In both cases the sensitive code won't execute unless the authentication is done successfully.
It's usually better to be expressive in your code though, so I'd recommend the second method.

How to handle errors for debug purposes on PHP? (public strings?)

What I want to do is when an if condition doesn't go as it should, instead of echo'ing the my custom error message in else { }, storing the error message somewhere else and retrieving it from another page.
For example, this is my page with the if condition:
if ($something < 4){
echo 'yes it is less than four';
else { echo 'no it isn\'t less than four';}
I want to for example store these error messages in strings and give them numbers:
if ($something < 4){
$debug11 = 'yes it is less than four';
echo '11';
else { $debug10 = 'no it isn\'t less than four'; echo '10'; }
then let's assume there's a debug.php file with php class that can echo these messages but in order to do so it needs to know what $debug11 is, can it do that without including that php page? is that what public strings are for? or should I just define all of them in debug.php
the point of all this is that jquery will call this file.php and get a message like 11 or 10 which in this case is success or failure then I will be able to know why it failed with debug.php. numbers are easier since I may play with text messages a lot and easier to confirm with numbers than text in if conditions.
You want to store error-messages and read this messages by another script.
It means you need a storage.
As a storage, you can use files, or memcache, or APC, or queues.
Create logger, which will write messages to the storage, and then in debug.php you will read list of messages from the storage.
I recommend to use Memcache, set_error_handler and trigger_error.
I'm not sure what you mean by 'public strings', but if you are looking at accessing a variable between 2 pages, you would need to persist them into a session variable at least.
Also you might be better off using PHP assertions to check for error conditions within your code (I think that's what your trying to achieve here):
Assertions should be used as a debugging feature only. You may use them for sanity-checks that test for conditions that should always be TRUE and that indicate some programming errors if not or to check for the presence of certain features like extension functions or certain system limits and features.
Try logging to file: http://nl3.php.net/manual/en/errorfunc.configuration.php#ini.error-log. You can supply a custom log file in which you can find all your errors.
If you put in a error handler you should be able to create debug messages and store them in another file.
Write own logging mechanism and put log messages in a file.
As above I am not 100% sure what you are trying to do, however instead of using variables for your custom error messages it may be better to use Constants. The benefits of them are that the values can't be rewritten unlike your variable where you can change the value within your script.
Your code would look something like this:
define("ERROR1", "It wont Work!");
define("ERROR2", "It still wont Work!");
define("ERROR3", "It must be broken!");
if ($something < 4){
echo '11';
} else {
echo ERROR1; // Prints "It wont Work!"
}
You can store these Constants in your debug.php file and use them on any page you include the file on.
Hope this helps.

PHP: Notice: Undefined index where the session variable is defined

I am making a registration system with an e-mail verifier. Your typical "use this code to verify" type of thing.
I want a session variable to be stored, so that when people complete their account registration on the registration page and somehow navigate back to the page on accident, it reminds them that they need to activate their account before use.
What makes this problem so hard to diagnose is that I have used many other session variables in similar ways, but this one is not working at all. Here's my approach:
/* This is placed after the mail script and account creation within the same if
statement. Things get executed after it, so I know it's placed correctly. */
$_SESSION['registrationComplete'] = TRUE;
// I've tried integer 1 and 'Yes' as alternatives.
Now to check for the variable, I placed this at the top of the page.
echo $_SESSION['registrationComplete']; // To see if it's setting. This gives the
// undefined index notice.
if (isset($_SESSION['registrationComplete'])) {
// Alternatively, I have nested another if that simply tests if it's TRUE.
echo $_SESSION['registrationComplete']; // When echo'd here, it displays nothing.
echo '<p>Congratulations, Foo! Go to *link to Bar*.</p>';
}
Now, I used to have the page redirect to a new page, but I took that out to test it. When the page reloads from submit, my message in the if statement above appears and then I get an Notice: Undefined index: registrationComplete blah blah from the echoing of the session var!
Then if I ever go back to the page, it ignores the if statement all together.
I have tested for typos and everything, clearing session variables in case old ones from testing were interfering, but I am having no luck. A lot of Googling just shows people suppressing these errors, but that sounds insane! Not only that, but I am not getting the same persistence of session variables elsewhere on my site. Can someone point out if I'm doing something blatantly wrong? Help! Thanks!
FYI, I read several related questions and I am also a beginner, so I may not know how to utilize certain advice without explanation.
As requested, more code, heavily annotated to keep it brief
var_dump($_SESSION);
// It's here to analyze that index message. I guess it's not important.
echo $_SESSION['registrationComplete'];
if (isset($_SESSION['registrationComplete'])) {
// The golden ticket! This is what I want to appear so badly.
echo 'Congratulations, Foo! Go to *link to Bar*.';
}
// Explanation: I don't want logged in users registering.
// The else statement basically executes the main chunk of code.
if (isset($_SESSION['user_id'])) {
echo 'You are logged in as someone already.';
}
else {
if (isset($_POST['submitRegister'])) {
// Code: Database connection and parsing variables from the form.
if (!empty($email) && !empty($email2) && $email == $email2 && !empty($displayName) && !empty($password) && !empty($password2) && $password == $password2) {
// Code: Query to retrieve data for comparison.
if (mysqli_num_rows($registrationData) == 0) {
// Code: Generates the salt and verification code.
// Code: Password hashing and sending data to verify database.
// E-mail the verification code.
$_SESSION['registrationComplete'] = 'yes';
}
else {
// Some error handling is here.
$registerError = 'The e-mail address you entered is already in use.';
}
}
// the elseif, elseif, and else are more error handling.
elseif ($email != $email2) { $registerError = 'Your e-mails did not match'; }
elseif ($password != $password2) { $registerError = 'Passwords didn\'t match.'; }
else { $registerError = 'Filled out completely?'; }
// If the registration was submitted, but had errors, this will print the form again.
if (!isset($_SESSION['registrationComplete'])) { require_once REF_DIR . REF_REGISTERFORM; }
// IMPORTANT! it turns out my code did not work, I forgot I had the same statement elsewhere.
else { echo 'Congratulations, Foo! Go to *link to Bar*.'; }
}
// Creates form.
else { require_once REF_DIR . REF_REGISTERFORM; }
}
This came down to the basics of debugging/troubleshooting.
Understand as much as you can about the technique/library/function/whatever that you're trying to use.
Inspect the salient bits and make sure that they are what you expect or what they should be. (There's a slight difference between those two, depending on the situation.)
If that doesn't bring you towards a solution, step back and make sure you're understanding the situation. This may mean simplifying things so that you're only dealing with the issue at hand, i.e. create a separate, simpler test case which exposes the same problem. Or, it may simply mean that you stop coding and work through the flow of your code to make sure it is really doing what you think it is doing.
A typical issue with sessions not working is forgetting to use session_start() (near or at the top) of any page which uses sessions.
One of my favorite snippets of PHP code, for debugging:
print '<pre>';
var_dump($some_variable);
print '</pre>';
I try to use print for debugging and echo for regular output. It makes it easier to spot debugging code, once it's goes beyond a few trivial bits of output.
Meanwhile, var_dump will print a bit more info about the variable, like it's type and size. It's important to wrap it in <pre></pre> so that it's easier to read the output.
Try
if (!empty($_SESSION['registrationComplete'])) {
If you get the warning after the message is printed, this cannot come from the variable echoing because according to your code it would be thrown before printing that message. Are you sure you don't use $_SESSION['registrationComplete'] beyond the if statement? Try to add exit or die() before the closing bracket of the if and see if the notice disappears.

weird problem with file_get_contents and twitter

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";
}

Categories