Problem with SITE_ROOT

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
philip56
Forum Newbie
Posts: 5
Joined: Mon Mar 11, 2013 4:48 pm

Problem with SITE_ROOT

Post by philip56 »

Hi.
I am teaching myself php (working through a textbook) and have hit a couple of problems. I've just spent about 4 hours trying to get the SITE_ROOT configured. I have selected public_html/exercises as the ROOT using

define("SITE_ROOT", "/public_html/exercises/");

Now, I on error I want to redirect to public_html/exercises/scripts/show_error.php. I'm using

function handle_error ($user_error_message, $system_error_message) {
header("Location: " . SITE_ROOT . "scripts/show_error.php?" . "error_message={$user_error_message}&" . "system_error_message={$system_error_message}");
exit();
to do that but each time I get

The requested URL /public_html/exercises/scripts/show_error.php was not found on this server.

What am I doing wrong?

Philip
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Problem with SITE_ROOT

Post by requinix »

The public_html shouldn't be in there.

Code: Select all

define("SITE_ROOT", "/exercises/");
Or at least not in the redirected URL - depends what else may use SITE_ROOT and what for.
philip56
Forum Newbie
Posts: 5
Joined: Mon Mar 11, 2013 4:48 pm

Re: Problem with SITE_ROOT

Post by philip56 »

Right, thanks very much. That gives me a blank page, so I'm guessing that the redirection to show_error.php has been successful and that that page has a problem

Here it is

Code: Select all

<?php
require_once 'app_config.php';

	if (isset($_REQUEST['error_message']))
	{
		$error_message =
	preg_replace_all("/\\\\/", '',
	
	$_REQUEST['error_message']);
	} else {
		$error_message = "something went wrong, and that's " . 
		"how you ended up here.";
	}
	
	if
	(isset($_REQUEST['system_error_message']
	)) {
		$system_error_message =
	preg_replace("/\\\\/", '',
	
	$_REQUEST['system_error_message']); }
	else {
		$system_error_message = "No system-level error message was reported.";
	}
?>
<html>
 <head>
  <link href="../css/phpMM.css" rel="stylesheet" type="text/css" />
 </head>

 <body>
  <div id="header"><h1>PHP & MySQL: The Missing Manual</h1></div>
  <div id="example">Example 4-1</div>
<div id="example">Uh oh....sorry!</div>

<div id="content">
<h1>We're really sorry...</h1>
<p><img src="../images/error.jpg"
class="error" />....but something's gone wrong. Apparently, <?php echo $error_message; ?></span></p><p> Don't worry, though, we've been notified that there's a problem , and we take these things seriously. In fact, if you want to contact us to find out more about what's happened or if you have any concerns, just <a href="mailto:info@ptah.me.uk">email us</a> and we'll be happy to get back to you</p>
<p>In the meantime, if you want to go back to the page that caused the problem, jou can do that <a href="javascript:history.go(-1);">by clicking here.</a> If the same problem occurs, though, you may want to come back a bit later. We bet we'll have things sorted out by then. Thanks again ... we'll see you soon. And again, we're really sorry for the inconvenience.</p>
</div>
</body>
<?php 
	debug_print("<hr />");
	debug_print("<p>The following system-level message was received:
	<b>($system_error_message)</b></p>");	
?>
Does anything hit you?
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Problem with SITE_ROOT

Post by requinix »

Code: Select all

        preg_replace_all("/\\\\/", '',
        
        $_REQUEST['error_message']);
There is no built-in function named "preg_replace_all". Perhaps you meant just "preg_replace"?

Critique:
1. Since you're getting the messages to display from the URL you should make sure you HTML-encode them before displaying. Also in the page that's redirecting make sure you're urlencode()ing the messages before putting them in the URL... or use http_build_query which does everything for you.
2. I see you're removing backslashes. They're probably showing up because you have the magic_quotes php.ini setting enabled. You should disable it, but if you do so you have to make sure the rest of your site is safe without it (which is not to say it is safe now!) If that is why then stripslashes is better at removing them. You can make code that only removes those slashes if the setting is enabled by using get_magic_quotes_gpc.

Code: Select all

function handle_error ($user_error_message, $system_error_message) {
        $query = array(
                "error_message" => $user_error_message,
                "system_error_message" => $system_error_message
        );
        header("Location: " . SITE_ROOT . "scripts/show_error.php?" . http_build_query($query));
        exit();
}

Code: Select all

<?php
require_once 'app_config.php';

        if (isset($_REQUEST['error_message']))
        {
                $error_message = $_REQUEST['error_message'];
                if (get_magic_quotes_gpc()) {
                        $error_message = stripslashes($error_message);
                }
        } else {
                $error_message = "something went wrong, and that's " . 
                "how you ended up here.";
        }
        
        if (isset($_REQUEST['system_error_message'])) {
                $system_error_message = $_REQUEST['system_error_message'];
                if (get_magic_quotes_gpc()) {
                        $system_error_message = stripslashes($system_error_message);
                }
        }
        else {
                $system_error_message = "No system-level error message was reported.";
        }
?>
<html>
 <head>
  <link href="../css/phpMM.css" rel="stylesheet" type="text/css" />
 </head>

 <body>
  <div id="header"><h1>PHP & MySQL: The Missing Manual</h1></div>
  <div id="example">Example 4-1</div>
<div id="example">Uh oh....sorry!</div>

<div id="content">
<h1>We're really sorry...</h1>
<p><img src="../images/error.jpg"
class="error" />....but something's gone wrong. Apparently, <?php echo htmlentities($error_message); ?></span></p><p> Don't worry, though, we've been notified that there's a problem , and we take these things seriously. In fact, if you want to contact us to find out more about what's happened or if you have any concerns, just <a href="mailto:info@ptah.me.uk">email us</a> and we'll be happy to get back to you</p>
<p>In the meantime, if you want to go back to the page that caused the problem, jou can do that <a href="javascript&#058;history.go(-1);">by clicking here.</a> If the same problem occurs, though, you may want to come back a bit later. We bet we'll have things sorted out by then. Thanks again ... we'll see you soon. And again, we're really sorry for the inconvenience.</p>
</div>
</body>
<?php 
        debug_print("<hr />");
        debug_print("<p>The following system-level message was received:
        <b>(" . htmlentities($system_error_message) . ")</b></p>");   
?>
philip56
Forum Newbie
Posts: 5
Joined: Mon Mar 11, 2013 4:48 pm

Re: Problem with SITE_ROOT

Post by philip56 »

Thanks very much for that. Amending preg_replace_all to preg_replace solved the problem when DEBUG_MODE is set to false in app_config.php. (preg_replace_all does have a sort of function it appears but in this case the author has admitted it was a typo). When DEBUG_MODE is set to true, I get my old friend
Cannot modify header information
! Now, I'm familiar with some of the causes of this but I can't see how to solve it here.

I'm happy to repost a separate query but as I suspect could be solved by your most useful information on htmlentities etc, I've taken the liberty of posting here first.

The full error is

Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'ptahmeuk_phil'@'localhost' (using password: YES) in /home/ptahmeuk/public_html/exercises/connect.php on line 6 (I would expect this - I've seeded an error in connect.php).

Warning: Cannot modify header information - headers already sent by (output started at /home/ptahmeuk/public_html/exercises/connect.php:6) in /home/ptahmeuk/public_html/exercises/scripts/app_config.php on line 36

The relavent files are.

1)connect.php

Code: Select all

<?php                                                                                               

  require_once 'scripts/app_config.php';

//  DATABASE_PASSWORD "foo"
 mysql_connect(DATABASE_HOST, DATABASE_USERNAME, "foo") 
	or handle_error("there was a problem connecting to the database that holds the information we need to get you conected. ",
	 mysql_error());
	 

// DATABASE_PASSWORD
  echo "<p>Connected to MySQL!</p>";

  mysql_select_db(DATABASE_NAME)
    or die("<p>Error selecting the database " . DATABASE_NAME . mysql_error() . "</p>");

  echo "<p>Connected to MySQL, using database " . DATABASE_NAME . ".</p>";

  $result = mysql_query("SHOW TABLES;");

  if (!$result) {
    die("<p>Error in listing tables: " . mysql_error() . "</p>");
  }

  echo "<p>Tables in database:</p>";
  echo "<ul>";
  while ($row = mysql_fetch_row($result)) {
    echo "<li>Table: {$row[0]}</li>";
  }
  echo "</ul>";
 
?> 
2. app_config.php

Code: Select all

<?php
//Setup debug mode

define("DEBUG_MODE", true);

// Site root
define("SITE_ROOT", "/exercises/");

// Database connection constants

define("DATABASE_HOST", "");
define("DATABASE_USERNAME", "");
define("DATABASE_PASSWORD", "");
define("DATABASE_NAME", "");

// Error reporting

if (DEBUG_MODE) {
	error_reporting(E_ALL);
} else {
  // Turn off all error reporting
  error_reporting(0);
}

function debug_print($message) {
	if (DEBUG_MODE) {
		echo $message;
	}
}

function handle_error ($user_error_message, $system_error_message) {
	$query = array(
		"error_message" => $user_error_message,
		"system_error_message" => $system_error_message
);	
	header("Location: " . SITE_ROOT . "scripts/show_error.php?" . http_build_query($query));
	exit();
}

?>
3. show_error.php

Code: Select all

<?php
require_once 'app_config.php';

	if (isset($_REQUEST['error_message']))
	{
		$error_message =
	preg_replace("/\\\\/", '',
	
	$_REQUEST['error_message']);
	} else {
		$error_message = "something went wrong, and that's " . 
		"how you ended up here.";
	}
	
	if
	(isset($_REQUEST['system_error_message']
	)) {
		$system_error_message =
	preg_replace("/\\\\/", '',
	
	$_REQUEST['system_error_message']); }
	else {
		$system_error_message = "No system-level error message was reported.";
	}
?>
<html>
 <head>
  <link href="../css/phpMM.css" rel="stylesheet" type="text/css" />
 </head>

 <body>
  <div id="header"><h1>PHP & MySQL: The Missing Manual</h1></div>
  <div id="example">Example 4-1</div>
<div id="example">Uh oh....sorry!</div>

<div id="content">
<h1>We're really sorry...</h1>
<p><img src="../images/error.jpg"
class="error" />....but something's gone wrong. Apparently, <?php echo htmlentities ($error_message); ?></span></p><p> Don't worry, though, we've been notified that there's a problem , and we take these things seriously. In fact, if you want to contact us to find out more about what's happened or if you have any concerns, just <a href="mailto:info@ptah.me.uk">email us</a> and we'll be happy to get back to you</p>
<p>In the meantime, if you want to go back to the page that caused the problem, jou can do that <a href="javascript:history.go(-1);">by clicking here.</a> If the same problem occurs, though, you may want to come back a bit later. We bet we'll have things sorted out by then. Thanks again ... we'll see you soon. And again, we're really sorry for the inconvenience.</p>
</div>
</body>
<?php 
	debug_print("<hr />");
	debug_print("<p>The following system-level message was received:
	<b>(" . htmlentities($system_error_message) . "</b></p>");	
?>
You will see I've used some of the changes you suggested. stripslashes I've heard of but would like to research further.

Regards

Philip
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Problem with SITE_ROOT

Post by requinix »

You can't do a header() redirect if there has been any output so far. That includes error messages - like the warning from mysql_connect().

In your development environment I suggest you keep things as they are: you'll get that error message, see it on the page, and not get redirected. For me it's simpler that way.
Otherwise you can do like you should do in the production/live environment: turn off the "display_errors" php.ini setting. PHP will not output the mysql_connect() warning and the header() will work.


You should make a small adjustment to your error handling code though. On your live site, if another MySQL error comes up then I'll be redirected to a page telling me there was an error. That's okay. But the URL will include the $system_error_message. In your case that's what mysql_error() tells you. That kind of information should never, ever be revealed to the user; the page may not output it but it's still there in the URL for me to read.

I have a couple suggestions to that end:
a) Only pass along the $system_error_message if you're in DEBUG_MODE.

Code: Select all

$query = array(
        "error_message" => $user_error_message
);      
if (DEBUG_MODE) {
        $query["system_error_message"] = $system_error_message;
}
b) Modify handle_error() so that it logs the $system_error_message someplace, then if you ever need to see the message you can look there for it. (Then you can remove that stuff from the error page since it won't be used anymore.) This is the Best Practice for how to do error handling so I recommend you switch to it.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Problem with SITE_ROOT

Post by Christopher »

I would recommend that you have two config values -- one for the filesystem and one for the URL:

Code: Select all

define("SITE_ROOT", "/public_html/exercises/");
define("SITE_BASE", "http://www.mysite.com/exercises/");

function handle_error ($user_error_message, $system_error_message) {
header("Location: " . SITE_BASE . "scripts/show_error.php?" . "error_message={$user_error_message}&" . "system_error_message={$system_error_message}");
exit();
(#10850)
philip56
Forum Newbie
Posts: 5
Joined: Mon Mar 11, 2013 4:48 pm

Re: Problem with SITE_ROOT

Post by philip56 »

Many thanks to you both for your help. Christopher, SITE_BASE is in the next chapter of my textbook, but I implement it now! Requinix, thanks again. I note especially, your comments on the system error message appearing in the URL. Where would you advise I insert your code?

Code: Select all

$query = array(
        "error_message" => $user_error_message
);      
if (DEBUG_MODE) {
        $query["system_error_message"] = $system_error_message;
}
Many thanks
Philip
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Problem with SITE_ROOT

Post by requinix »

philip56 wrote:Where would you advise I insert your code?
In handle_error().
philip56
Forum Newbie
Posts: 5
Joined: Mon Mar 11, 2013 4:48 pm

Re: Problem with SITE_ROOT

Post by philip56 »

Many thanks. I thought that was the answer. I'll have a play and work out where exactly it goes.
Many thanks for all your help
Post Reply