I’ve read numerous questions about redirecting back to a form after performing server side validation (assuming the form has errors) and displaying the errors, but I haven’t found anything related to my specific problem. I have a simple front controller that uses .htaccess to redirect http requests to index.php. That’s the setup; here’s my situation:
register.php is a registration form that posts to validate_registration.php. I have code in the form that displays php variables (which won’t be set unless the validation script has run). I use this at the end of validate_registration.php:
header("Location: http://www.example.com/register.php");
Unfortunately, the code to display the errors in register.php simply doesn’t do anything. Is this getting lost in my front controller? My .htaccess code is this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond $1 !^(index\.php|ajax|css|error|form|img|js|robots\.txt|securimage|submit)
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
and my front controller is this (mostly, it’s extremely simple with a switch statement because I absolutely no need for anything more complex, scalable, etc.):
$url = $_GET['url'];
require_once("header.php");
echo '<body>';
require_once("banner.php");
require_once("navigation.php");
require_once("login_bar.php");
echo '<div id="main">';
switch ($url) {
case('register.php'):
require_once('register.php');
break;
default:
require_once('error404.php');
break;
}
echo '</div>'; //Closing div tag for the id="main" section
require_once("$template_directory/general/footer.php");
echo '</body>';
Sorry about the long question; I can’t seem to get this fixed! validate_registration.php redirects to register.php just fine, but the variables don’t seem to carry through the front controller. Also, this form needs to work without Javascript enabled, so AJAX isn’t an option, unfortunately.
EDIT:
Here’s the code to the form with error messages; it’s quite simple right now because I’m only testing it.
<?php
$allowed_fields = array("reg_username",
"reg_password",
"reg_confirm_password",
"reg_email",
"reg_confirm_email",
"captcha_code",
"reg_disclaimer",
);
$db_select_connection = DB::get_admin_connection();
$errors = array();
foreach ($_POST as $key => $value) {
if (in_array($key, $allowed_fields)) {
$$key = mysql_real_escape_string($value);
if ($value == "") {
$errors["$key" . "_blank"] = "The $key field is required.";
}
}
}
// Validation section
// Username
if (ctype_alnum($reg_username)) {
$errors["reg_username_invalid"] = "Username can only contain letters and numbers.";
}
// Password
if (strlen($reg_password) < 6) {
$errors["reg_password_short"] = "Password must be at least 6 characters long.";
}
if ($reg_password !== $reg_confirm_password) {
$errors["reg_password_match"] = "Passwords do not match.";
}
$legal_characters = preg_quote("~!@#$%^&*()");
$trimmed_password = preg_replace("/[^a-zA-Z$legal_characters]/", "", $reg_password);
if ($trimmed_password !== $reg_password) {
$errors["reg_pass_chars"] = "Password can only contain letters, numbers, and " . htmlentities($legal_characters, ENT_QUOTES, 'UTF-8');
}
// Email
if ($reg_email !== $reg_confirm_email) {
$errors["reg_email_match"] = "Email addresses do not match.";
}
if (!Email::validate_email($reg_email)) {
$errors["reg_email_invalid"] = "Email address is invalid.";
}
//Disclaimer check box
if ($reg_disclaimer !== "on") {
$errors["reg_disclaimer_accept"] = "You must read and accept the disclaimer to create an account.";
}
require("http://www.example.com/register.php");
?>
The code for the form simply contains and similar code blocks to display the errors. There’s a lot of formatting and styling divs involved so I won’t waste space with the entire form.
EDIT: Also, how do I format something as code without manually putting 4 spaces in front of every line? I copied code directly from Netbeans, my IDE, into the editing window, highlighted it, and pressed Code, and it still wouldn’t let me submit my post.
If you redirect, you’ll lose all the form data because it’s a new request. Instead render the form in the current request if errors are to be displayed, and redirect on success.
A redirect is normally used to prevent form re-send when the form action has been completed successfully.
EDIT (after considerable evolution in the comments):
You might want to redesign the way your scripts run. There’s actually no requirement for
index.phpto render any content at all, or for your urls to always end in.php.I’m going to suggest one way to write your app; it probably isn’t the best way, so do consider others, but it might help you think.
Here, your router, controller logic and your layout and view templates are separated into manageable sections with clear responsibilities. This way you won’t have to write repeat your code everywhere in your app.