Я запутался в PHP Post / Redirect / Get - PullRequest
7 голосов
/ 07 октября 2011

В статье о предотвращении повторной отправки форм PHP я прочитал следующее:

(без кавычек) Это может быть страница, которая получает данные формы, например, называется "форма".php ":

<form action="submit.php">
  <input type="text" name="user" required />
  <input type="password" name="pass" required />
  <input type="submit" value="Log in" />
</form>

Страница, которая будет обрабатывать данные POST, будет поэтому называться" submit.php ".Если вход в систему выполнен правильно, этот код будет работать:

header('Location: /login/form.php?success=true');

Однако не может ли пользователь просто перейти по указанному выше URL-адресу?Кроме того, какова цель переменной GET?Могу ли я просто иметь скрипт в form.php, который проверяет, вошел ли пользователь в систему?

В submit.php мне следует сохранить зарегистрированное имя пользователя как $ _ SESSION ['username'], а затем проверьте, если isset () в form.php?Кроме того, поскольку URL-адрес с «успехом» не очень приятный, стоит ли перенаправлять пользователя еще раз?Должен ли я использовать PHP header () или Javascript window.location.href? Как вы видите, я немного растерялся.

Спасибо за любую помощь.

Ответы [ 4 ]

5 голосов
/ 07 октября 2011

Однако не может ли пользователь просто перейти по указанному выше URL-адресу?

Да, он может.Это не вызовет ничего плохого.

Кроме того, какова цель переменной GET?

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

Не могу просто написать скрипт на форме.php, который проверяет, вошел ли пользователь в систему?

Хм, вы можете сохранить свой код так, как вам нравится 1018 *.Нет строгих требований

В submit.php я должен сохранить зарегистрированное имя пользователя как $ _SESSION ['username'], а затем проверить, установлен ли isset () в form.php?

Если вам нужно сохранить его в текущем сеансе - да, сделайте это.

Кроме того, поскольку URL с «успехом» в нем не очень красив,это экономично перенаправить пользователя еще раз?

Перенаправить куда.Перенаправление - довольно дешевая вещь.

Должен ли я использовать PHP header () или Javascript window.location.href?

Вы определенно должны сделать это в php, иначе вы 'Я получу проблемы, которые вы пытаетесь избежать, следуя PRG-пути.

2 голосов
/ 07 октября 2011

PRG или Post / Redirect / Get - это просто шаблон, который вы можете использовать для предотвращения появления окон сообщений. То, как вы используете его подробно (а статья содержит только общие рекомендации), зависит от ваших потребностей.

Если вы хотите пометить флэш-сообщение об успехе в файле cookie, в сеансе или в переменной get, это полностью ваше дело. Кстати, второе перенаправление не поможет, вы узнаете об этом, если поиграете с ним.

Единственная важная часть заключается в том, что после получения запроса POST вы выполняете перенаправление. Затем пользователь все еще может перемещаться назад и вперед в истории без запроса повторной отправки данных POST.

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

О вашем перенаправлении

Этот код неверен:

header('Location:/login/form.php?success=true');

Прежде всего, вам нужно иметь пробел после двоеточия:

header('Location: /login/form.php?success=true');

Тогда адрес должен быть абсолютным URI, он должен содержать полный URL:

header('Location: http://example.com/login/form.php?success=true');

Рядом с header() вы должны предоставить тело сообщения в соответствии с RFC, многие так называемые «веб-разработчики» даже не знают:

$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('<a href="%s">Moved</a>.', $url);
exit;

Не забывайте выход. Конечно, это в значительной степени заново изобретает колесо, вместо этого установите расширение http PHP и просто выполните следующую строку:

http_redirect('/login/form.php?success=true');

Вы обнаружите, что отличный помощник здесь .

Напомним: важно то, что вы делаете перенаправление после публикации. Все остальное, например, передача переменной, зависит только от вас, как бы вы хотели это сделать.

1 голос
/ 07 октября 2011

Основная идея POST / REDIRECT / GET, на которую указывает ссылка, на которую вы ссылаетесь, состоит в том, чтобы избежать повторной отправки данных пользователями (в большинстве случаев).Как правило, вы не хотите, чтобы один и тот же POST (с одинаковыми данными) происходил дважды - действительно, в некоторых ситуациях он может закончиться выполнением какого-либо действия (например, кредитной карты) во второй раз, что было бы плохо.

Большая часть того, о чем вы спрашиваете в своем вопросе, - это детали реализации (например, отправка параметра запроса? Success в перенаправлении).

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

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

login.php

<?php
/**
 * ensure user supplied both username & password
 * @return mixed true or an array of error messages
 */ 
function validate_login_values($vars){
    $errors = array();
    if (empty($vars['username'])) $errors[] = 'You must supply a username, genius.';
    if (empty($vars['password'])) $errors[] = 'You must supply a password, dummy.';
    if (empty($errors)) return true;
    return $errors; // $errors must be an array.
}

if (! empty($_POST)){
    $validationResults = validate_login_values($_POST);
    if ($validationResults === true){
        // assume here that authenticate properly escapes it's arguments before sending them
        // to the database.
        if (authenticate($_POST['username'],$_POST['password'])){
            //GREAT SUCCESS!  The user is now logged in.  Redirect to home page
            header("Location: /");
            die();
        }
        $errors[] = 'Invalid username/password.  Try again, slim";

    }else{
        $errors = $validationResults; // validate_login_values created errors.
    }  
}
?>

<h1>Log In, Friend!</h1>]

<?php 
//display errors, if there were any
if (! empty($errors)): ?>
<div class="errors">Something went horribly wrong:
<ul><?php foreach($errors as $e) echo "<li>$e</li>"; ?></ul>
<div>
<?php endif; ?>

<form method="POST">
<!--   //username, password, and submit   -->
</form>
1 голос
/ 07 октября 2011

Да, вы никогда не должны полагаться на переменную GET (или даже на скрытую переменную POST), чтобы сказать: «Конечно, впустите меня, я действительный пользователь!».

Лично я быубрать информацию GET из ссылки и полагаться исключительно на переменные сеанса.Не забудьте разместить 'session_start ();'в качестве первой строки кода, если вы используете PHP для активации сеанса.

Для submit.php:

<?php
session_start();
if ($_POST['user'] && $_POST['pass']) { // Make sure both variable are set
 if (your_method) {
 // Code to check if the user and pass are valid however you plan
  $_SESSION['user'] = $_POST['user'];
  $_SESSION['loggedin'] = time();
 }
}
header('Location: form.php'); // Either way, pass or fail, return to form.php
exit();
?>

Затем в form.php:

<?php
session_start();
$activeuser = false;
if ($_SESSION['user'] && $_SESSION['loggedin'] < (time()+600)) {
// Check if the user exists and the last access was with in 10 minutes.
 $_SESSION['loggedin'] = time(); // If so, keep them up to date!
 $activeuser = true;
}
if ($activeuser) {
 // whatever should show to someone logged in
} else {
 // Show log in form
}
?>

Кроме того, вы, возможно, уже знаете это, но метод передачи по умолчанию - GET, поэтому обязательно укажите method = "post" в теге формы.

Обычно лучше использовать header () для перенаправления, еслинеобходим, поскольку Javascript на стороне клиента и его можно избежать, что может нарушить ваши намерения по функционированию вашего сайта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...