Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

$_SERVER['PHP_SELF'] adds extra / causing 'Server not found' err

Status
Not open for further replies.

VicM

Programmer
Sep 24, 2001
444
US
I'm using Apache 1.3.27 and PHP 4.3.11 and MySQL 4.1.12

I'm following along with a text book, PHP and MySQL by Larry Ullman, and its examples. The examples were downloaded from the book's web site, so there was basically to typing on my part.

The section I'm working on is about cookies. The example home page php contains links to other pages such as login, register, and change password.

I first noticed the problem when I was studying the login.php page. Basically it's a form for entering a username and password, which it then checks against the db. When the submit is clicked, the action uses $_SERVER['PHP_SELF'] to return to the login.php page, which contains code checking the username and pw against the db. If it matches, the code sets a cookie with the user's first name, then redirects to a loggedin.php page.

That page just outputs a personalized statement of login completion using the users first name from the db.

When the login page link is again clicked, the info filled in and submit is clicked, the browser hangs for a time and then returns a 'server not found' error. If I close the browser and reopen it, it again functions as described above.

It took me a few days to determine that after the first click on submit, the $_SERVER['PHP_SELF'] returns /login.php. But the next time it returns //login.php! (I decided to echo the $_SERVER['PHP_SELF'].)

For purposes of continuing on with the book's examples, I changed the form's action= parameter to: substr($_SERVER['PHP_SELF'], 1).

This works just fine. But I'm concerned that this is a bug, and if corrected would cause the substr() to lop off the first letter of the file name in future implementations.

Has anyone run accross this before and is this in fact a bug?
 
Never seen that in over 5 years of PHP coding. Can you post some example code?

Ken
 
The code for the login.php script before I added the substr() function is:
Code:
<?php # Script 7.1 - login.php

if (isset($_POST['submit'])) { // Handle the form.

	require_once ('../mysql_connect.php'); // Connect to the db.
		
	// Create a function for escaping the data.
	function escape_data ($data) {
		global $dbc; // Need the connection.
		if (ini_get('magic_quotes_gpc')) {
			$data = stripslashes($data);
		}
		return mysql_real_escape_string($data, $dbc);
	} // End of function.

	$message = NULL; // Create an empty new variable.
	
	// Check for a username.
	if (empty($_POST['username'])) {
		$u = FALSE;
		$message .= '<p>You forgot to enter your username!</p>';
	} else {
		$u = escape_data($_POST['username']);
	}
	
	// Check for a password.
	if (empty($_POST['password'])) {
		$p = FALSE;
		$message .= '<p>You forgot to enter your password!</p>';
	} else {
		$p = escape_data($_POST['password']);
	}
	
	if ($u && $p) { // If everything's OK.

		// Retrieve the user_id and first_name for that username/password combination.
		$query = "SELECT user_id, first_name FROM users WHERE username='$u' AND password=PASSWORD('$p')";		
		$result = @mysql_query ($query); // Run the query.
		$row = mysql_fetch_array ($result, MYSQL_NUM); // Return a record, if applicable.

		if ($row) { // A record was pulled from the database.
				
				// Set the cookies & redirect.
				setcookie ('first_name', $row[1]);
				setcookie ('user_id', $row[0]);
				header ("Location:  [URL unfurl="true"]http://"[/URL] . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/loggedin.php");
				exit(); // Quit the script.
				
		} else { // No record matched the query.
			$message = '<p>The username and password entered do not match those on file.</p>'; 
		}
		
		mysql_close(); // Close the database connection.

	} else {
		$message .= '<p>Please try again.</p>';		
	}

} // End of the main Submit conditional.

// Set the page title and include the HTML header.
$page_title = 'Login';
include ('templates/header.inc');

// Print the error message if there is one.
if (isset($message)) {
	echo '<font color="red">', $message, '</font>';
}
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

[COLOR=blue]// I replaced the action parameter above with:[/color][COLOR=red]<?php echo substr($_SERVER['PHP_SELF'], 1); ?>[/color] [COLOR=blue]to get it to work.[/color]

<fieldset><legend>Enter your information in the form below:</legend>
<p><b>User Name:</b> <input type="text" name="username" size="10" maxlength="20" value="<?php if (isset($_POST['username'])) echo $_POST['username']; ?>" /></p>

<p><b>Password:</b> <input type="password" name="password" size="20" maxlength="20" /></p>

<div align="center"><input type="submit" name="submit" value="Login" /></div>

</fieldset></form><!-- End of Form -->

<?php
include ('templates/footer.inc'); // Include the HTML footer.
?>

The code for the loggedin.php script is:

Code:
<?php # Script 7.2 - loggedin.php

// If no cookie is present, redirect the user.
if (!isset($_COOKIE['first_name'])) {
	header ("Location:  [URL unfurl="true"]http://"[/URL] . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/index.php");
	exit(); // Quit the script.
}

// Set the page title and include the HTML header.
$page_title = 'Logged In!';
include ('templates/header.inc');

// Print a customized message.
echo "<p>You are now logged in, {$_COOKIE['first_name']}!</p>";

include ('templates/footer.inc'); // Include the HTML footer.
?>

The require_once file contains the connection info to the db. The include files are HTML for the page links to the various functions, such as login, registration, change password, etc.

As I said, I put an echo statement on the form and got the results I mentioned in my first post.

Vic
 
substr() is not needed, a better option would be to use stripslashes(). That command will only take out the slashes so that you need not worry about it taking off letters. Be careful though as if you point it to a subfolder (/login/index.php) it will come out (loginindex.php) which, of course, is not right.
 
Forgot to add why this is happening to my last post (whups!?). This is happeneing because you are sending /login.php and it (just like in CPP) will sometimes convert / to //. Another easy way of handling this situation if you NEED the slashes to be there is with a simple replace statement.
Code:
str_replace("//","/",$var);
[code]
 
I also have never seen something like this happening.
The code works fine on 4.3.10 - I'll have to compile 4.3.11 to see what happens there.
I don't believe that MattNeelys explanation works. Once I have 4.3.11 I'll report back.
 
Ran your code on PHP 4.3.11 without any such behavior.
 
I have 4.3.11 and have tried the script. It doesn't exhibit that behaviour.

I did remove the mysql code of course and hardcoded the $row result, but it does work as expected with Firefox 1.0.3.

I went to the login page, logged in, got the successful message, then went back to the login page a second time and repeated.

I put the scripts in a /test folder and both times when I echo PHP_SELF I get: '/test/login.php'
 
I had tried stripslashes(), MattNeeley, and it didn't work. I believe that function only works on backslashes (\).

However, I do like the option of using the str_replace() function. That should work without jeopardizing the code.

Not sure what you mean when you say
This is happening because you are sending /login.php ...
I'm using the super-global $_SERVER['PHP_SELF']. I don't understand why the function would return \login.php the first time and \\login.php the second. I thought that the info it contains should be constistent.

As to why this is happening in my configuration and not in anyone else's is a puzzlement indeed.

Thanks for your input folks.

Vic
 
It is mistakenly presented as if the action attribute is submitted - which it is not. Submitted form field values have escape slashes and there would be a need to strip those (dependent on php.ini settings) before reusing the values. However, not true for the action attribute which is never transmitted.
 
For clarity, I erred in my 12:38 post above.

The $_SERVER['PHP_SELF'] super-global returns /login.php the first time and //login.php the second. That is, it returns forward slashes (/), not backslashes which would have been corrected with the stripslashes() function.

Anyhow, until I figure out why this is happening, I'll use the str_replace() function.

Thanks again,

Vic
 
I'd say this is a pretty significant problem with your server setup which you should really correct... that's my first assumption anyway.

Have you tried dumbing down the script to see if youc an repliate the behavior?

i.e.
Code:
<?php
echo $_SERVER['PHP_SELF'];
echo "<br />";
echo $_SERVER['PHP_SELF'];
echo "<br />";
for ($i=0;$i<5;++$i)
{
  echo $_SERVER['PHP_SELF'];
  echo "<br />";
}
?>

Also what do you see as the value for _SERVER["PHP_SELF"] if you change the script to

<?php phpinfo(); ?>

 
Hate to keep beating on this old horse, but:

DRJ478 and danomac

You said the code worked for you. But my question is how did you get back to the login.php page? Did you use the 'Back' button on your browser?

I tried that, and that will work. However, when I retyped the url into the browser's address bar I was able to reproduce the error.

The header.php and footer.php, which I didn't include in these posts, have links back to the different pages, such as Login, etc. When the link is clicked, I believe the server reloads the file. But if the 'Back' button is used, I believe the code comes from the browser's cache. This could explain why, if you used the 'Back' button, the code worked for you.

Also, if you could put the following line of code into the login.php script and try it without using the browser's 'Back' button, it will print out the contents of $_SERVER['PHP_SELF'].

Code:
.
.
.
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<fieldset><legend>Enter your information in the form below:</legend>

[COLOR=red][b]<?php echo $_SERVER['PHP_SELF']; ?>[/b][/color]

<p><b>User Name:</b> <input type="text" name="username" size="10" 
.
.
.

That's how I discovered the double slash. I'd be interested to know if you're able to reproduce the error that way.

Thanks,

Vic
 
When I did the test, I retyped the page in the address bar. I did not use the back button.
 
Well, I guess that theory is shot to pieces [blush]

Anyway, thanks for all your input.

Vic
 
Here's what I did:
1. took the form code without the database stuff.
2. submitted the form (to $_SERVER['PHP_SELF']) several times.
3. inspected the $_SERVER array after the post, all is fine.

Best bets:
a) There is a link in header/footer that prepends the extra slash.
b) Your web server has a faulty setup, rewrite rule or something along those lines.

I assume that the double slash is also showing in the address bar of the browser. I would go through the process and check when it happens. As soon as it appears we'd know the previous page must be responsible.
 
So any more information on your debugging steps?

You need to start doing var_dump()'s, and print_r()'s, and removing potentially troubling code and so on.

I gave some examples above of the simplest script which should show your problem, did you try those, did you look at the phpinfo() output?

At this point you need to determine if it's your server or your code. If it's your code, you need to determine at which line the problem manifests itself... go ahead, put
Code:
echo '<pre>';
print_r($_SERVER);
echo '</pre><hr />';

At several points throughout your code... including the very beginning, see if you're coming in with a malformed $_SERVER array, or if somewhere it's getting warped.

I'm making the assumption you're not using an IDE like ZendStudio, so footprinting is your most effective form of debugging, I suggest it's time to try those steps.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top