开发者

how do I redirect back to a form from a php validation script, within a front controller

开发者 https://www.devze.com 2023-03-24 02:04 出处:网络
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 t

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 开发者_JAVA百科!== $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.php to 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.

    // index.php
    switch($_REQUEST['url']) {
        case('register'):
            $page['controller'] = 'register';
            break
        /* other stuff */
    }
    include_once('controllers/'.$page['controller'].'.php');


    // controllers/register.php
    if($_POST['register_form']) {
        // logic to deal with the form, error messages etc
    }
    $page['title'] = 'Register Now!';
    $page['template'] = 'register';
    include_once('../views/layout.php');



    // views/layout.php
    <!DOCTYPE html>
    <html>
    <head>
    <title><?=$page['title'];?></title>
    </head>
    <body>
    <?php
      // headers and such
      include_once($page['template'].'.php');
      // footers and such
    ?>
    </body>
    </html>


    // views/register.php
    /* your form html */

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.


Try to replace

header("Location: http://www.example.com/register.php");

with

return require '/path/to/register.php';


Setting the location header tells the browser to direct itself to register.php. Think of it as opening a new window and going to register.php. None of your post variables will carry through because they were posted to validate_registration.php, and then validate_registration.php simply redirects the browser back to register.php. This is where that data is lost. Nothing is transferred in a location redirect (remember, HTTP is stateless. It won't remember unless told (thus a POST, or cookie).

You need to either require('/path/to/register.php'); (as Francesco suggested) so that register.php may access those variables, or throw them into a SESSION variable and access them from register.php that way (remembering that you will need to use the session set of functions).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号