как перенаправить обратно в форму из сценария проверки php, внутри фронт-контроллера - PullRequest
1 голос
/ 29 июля 2011

Я прочитал множество вопросов о перенаправлении обратно в форму после выполнения проверки на стороне сервера (при условии, что в форме есть ошибки) и отображении ошибок, но я не нашел ничего, связанного с моей конкретной проблемой. У меня есть простой фронт-контроллер, который использует .htaccess для перенаправления http-запросов в index.php. Это настройка; вот моя ситуация:

register.php - это форма регистрации, которая публикуется на validate_registration.php. У меня есть код в форме, которая отображает переменные php (который не будет установлен, если скрипт проверки не запущен). Я использую это в конце validate_registration.php:

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

К сожалению, код для отображения ошибок в register.php просто ничего не делает. Это теряется в моем фронт-контроллере? Мой код .htaccess такой:

<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>

и мой фронт-контроллер такой (в основном, это чрезвычайно просто с оператором switch, потому что мне абсолютно не нужно ничего более сложного, масштабируемого и т. Д.):

$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>';

Извините за длинный вопрос; Я не могу исправить это! validate_registration.php перенаправляет в register.php просто отлично, но переменные, похоже, не проходят через фронт-контроллер. Кроме того, эта форма должна работать без включенного Javascript, поэтому, к сожалению, AJAX не вариант.

EDIT: Вот код формы с сообщениями об ошибках; сейчас все просто, потому что я только проверяю это.

<?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");
?>

Код для формы просто содержит и похожие блоки кода для отображения ошибок. Здесь задействовано множество форматов и стилей, поэтому я не буду тратить пространство на всю форму.

РЕДАКТИРОВАТЬ: Кроме того, как мне отформатировать что-то как код, не помещая вручную 4 пробела перед каждой строкой? Я скопировал код непосредственно из NetBeans, моей IDE, в окно редактирования, выделил его и нажал «Код», и он все равно не позволил мне отправить свое сообщение.

Ответы [ 3 ]

3 голосов
/ 30 июля 2011

Попробуйте заменить

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

на

return require '/path/to/register.php';
2 голосов
/ 29 июля 2011

Если вы перенаправите, вы потеряете все данные формы, потому что это новый запрос. Вместо этого визуализируйте форму в текущем запросе, если должны отображаться ошибки, и перенаправьте в случае успеха.

Перенаправление обычно используется для предотвращения повторной отправки формы после успешного завершения действия формы.

РЕДАКТИРОВАТЬ (после значительной эволюции в комментариях):

Возможно, вы захотите изменить дизайн ваших скриптов. На самом деле index.php не требуется отображать какой-либо контент вообще, или ваши URL-адреса всегда должны заканчиваться .php.

Я собираюсь предложить один из способов написать ваше приложение; это, вероятно, не самый лучший способ, поэтому подумайте о других, но это может помочь вам подумать.

    // 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 */

Здесь ваш маршрутизатор, логика контроллера и шаблоны макетов и представлений разделены на управляемые разделы с четкими обязанностями. Таким образом, вам не придется писать, повторять код везде в приложении.

0 голосов
/ 30 июля 2011

Установка заголовка местоположения говорит браузеру направить себя в register.php. Думайте об этом как об открытии нового окна и переходе к register.php. Ни одна из ваших переменных не пройдет, потому что они были опубликованы в validate_registration.php, а затем validate_registration.php просто перенаправляет браузер обратно в register.php. Это где эти данные теряются. При перенаправлении местоположения ничего не передается (помните, что HTTP не имеет состояния. Он не помнит, пока не будет сказано (таким образом, POST или cookie).

Вам нужно либо require('/path/to/register.php'); (как предложил Франческо), чтобы register.php мог получить доступ к этим переменным, либо выбросить их в переменную SESSION и получить к ним доступ из register.php таким образом (помня, что вам нужно будет используйте набор функций сеанса ).

...