Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.04.2014, 17:17   #1
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию PHP - как граммотно избавиться от Confirm Form Resubmission

Дорогие формучане, после отправки данных из формы в базу данных методом POST появляется информационное окно "Сonfirm Form Resubmission" при обновлении браузера. И если я подтверждаю, мне опять форма отсылает только что сохраненные данные в базу. У меня уже столько одинаковых данных накопилось!

Вот образец формы(addItem.php):
Код:
<form method="POST" action="" name="newItemForm"> 
 <input  type="text" name="itemName"  placeholder="Название товара" >
<button type="button"  name="addNewItem" onclick="form.submit(); form.reset();">Добавить новый товар</button>
</form>
В обработчике формы (контроллер data.php) написано:
Код:
 if(isset($_POST['addNewItem'])){

 $item = new Model_Item(); //создаем новый объект-модель Товар

               
                   $item->values(array(
                    'itemName' => $_POST[itemName], //отправляем данные в базу (модуль соединения с базой реализован отдельно и он работает прекрасно, данные заносятся в базу)

 ));
 $item->save(); //сохраняем данные о новом товаре

}
А мне не надо, чтобы такое окно (Confirm) появлялось и в случае подтверждения в базу поступали повторно те же самые данные. Мне надо, чтобы данные отправились один раз при нажатии на кнопку, форма закрылась и при обновлении браузера нигде никакой ресубмит не появлялся, пользователь оставался на той же странице и повторно никакие данные в базу не отправлялись.

В Интернете рекомендуют пользоваться header(перенаправление), но у меня во-первых пользователь должен оставаться на том же окне, а во-вторых у меня MVC-приложение и по страницам (View) я хожу при помощи метода в контроллере. И я не знаю, как правильно в таком случае этот header прописать.

Пока у меня работает без окна Confirm только единственный вариант
Код:
if ......{
.............
$item->save(); //сохраняем данные о новом товаре
exit;
}
Но он выбрасывает пользователя вообще в никуда, и приходится заново нажимать Enter в адресной строке, чтобы заново отобразилась страница.

Как избавиться от дублирования данных и этого жуткого Resubmit Confirmation?
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan
Blondy вне форума Ответить с цитированием
Старый 11.04.2014, 18:01   #2
Andkorol
Старожил
 
Регистрация: 31.05.2010
Сообщений: 3,301
По умолчанию

Цитата:
Сообщение от Blondy Посмотреть сообщение
В Интернете рекомендуют пользоваться header(перенаправление), но у меня во-первых пользователь должен оставаться на том же окне, а во-вторых у меня MVC-приложение и по страницам (View) я хожу при помощи метода в контроллере. И я не знаю, как правильно в таком случае этот header прописать.
Правильно рекомендуют – после отправки формы нужно обязательно выполнять редирект.
Можно сделать функцию редиректа в хелпере, или же специальный метод для редиректа в базовом контроллере – и использовать их для выполнения перенаправления.
В простейшем виде это выглядит примерно так:
PHP код:
function redirect($uri ''$method 'location'$http_response_code 302)
{
    if ( ! 
preg_match('#^https?://#i'$uri))
    {
        
$uri site_url($uri);// site_url() формирует корректный URL, разбирается со слэшами и т.д.
    
}

    switch(
$method)
    {
        case 
'refresh'    header("Refresh:0;url=".$uri);
            break;
        default           : 
header("Location: ".$uriTRUE$http_response_code);
            break;
    }
    exit;

Соответственно, в нужном нам месте мы используем это:
PHP код:
redirect('controller/method/bla'); // если это функция хелпера
// or
$this->redirect('controller/method/bla'); // если это метод базового контроллера 
Для вашего примера:
PHP код:
if(isset($_POST['addNewItem']))
{
   
$item = new Model_Item(); //создаем новый объект-модель Товар
   
$item->values(array(
      
'itemName' => $_POST[itemName], //отправляем данные в базу (модуль соединения с базой реализован отдельно и он работает прекрасно, данные заносятся в базу)
   
));
   
$item->save(); //сохраняем данные о новом товаре
   
redirect('controller/method/bla'); // можно прямо на этот же контроллер/метод – $_POST в этом случае будет пуст, и повторная запись не произойдет

Andkorol вне форума Ответить с цитированием
Старый 11.04.2014, 19:43   #3
TranceSmile
Смайлик :)
Форумчанин
 
Аватар для TranceSmile
 
Регистрация: 12.12.2010
Сообщений: 445
По умолчанию

А что за фраемворк используете?
Самый перспективный framework Yii (c)
TranceSmile вне форума Ответить с цитированием
Старый 11.04.2014, 22:49   #4
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию

Цитата:
А что за фраемворк используете?
Kohana 3.2 только я в нем пока не очень сильна. Все какие-то проблемы возникают технические: вроде и примеров полно, пока не начнешь решать конкретные задачи. Вот как с этим вопросом - хоть бы в одном примере было указано толком, как избавляться от Confirm и перенаправлять редиректом с использованием контроллера или использовать перенаправление с контроллера в header().

Я вообще на PHP писала два года назад, все больше на Шарп и Джава, а тут пришлось делать модуль с возможно последующей интерграцией в готовый веб-сайт, вот я Кохана и постигаю.

Уважаемый Andkorol, спасибо Вам за совет, сейчас буду пробовать. И у меня еще к Вам вот какой вопрос по тому же коду - а вот почему так может быть: кнопка срабатывает, то есть в адресной строке видно, что данные на событие (isset($_POST['addNewItem'])) формируются (и где-то в сессии сидят), но в базе данных тишина. А если заместо кнопки 'addNewItem', я в if подставлю название поля itemName (то есть получется строчка
Код:
if(isset($_POST['itemName']))
данные поступают в базу?

И вот тоже не совсем понятно: Вы пишите
Цитата:
Можно сделать функцию редиректа в хелпере, или же специальный метод для редиректа в базовом контроллере
А разве можно внутри метода action ( public function action_index()) вызывать какую-то функцию, кроме встроенных - вот Вы предлагаете вызывать function redirect. И может быть такое чтобы в контроллере было несколько функций и мы потом ими уже рулили (при необходимости вызывая тот или иной метод)? Как тогда их прописывать в файле маршрутизации - только создавая отдельные Route с путями под каждый метод и навешивая их потом на необходимые элементы (кнопки и т.д.)? Я к чему интересуюсь - у меня уже метод action index длинный как простыня, а реализовать вызовы готовых функций из какого-нибудь стороннего файла DataManager не получается.
Вот написала в контроллере в action index
Код:
$items = DataManager::getAllItems($goods);
у меня в этом DataManager запросик (factory ORM) прописан, коотрый выбирает массив всех товаров из базы. А среда уперлась - не видит DataManager и возвращаемой методом getAllItems переменной $goods, хотя у меня и use DataManager до контроллера прописан и в самом контроллере код этого метода работает.....

Ваш способ с редиректом в контроллере сработал. Списибо огромное - я Вам плюсую!
Как все-таки приятно, когда профессионалы дают точный синопсис и действенное "лекарство". А то сидишь днями, разбираешь примеры, чтобы две строски кода запустить, и в результате они к тому же и запускаются криво.
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan

Последний раз редактировалось Blondy; 11.04.2014 в 23:27.
Blondy вне форума Ответить с цитированием
Старый 11.04.2014, 23:09   #5
Andkorol
Старожил
 
Регистрация: 31.05.2010
Сообщений: 3,301
По умолчанию

Цитата:
Сообщение от Blondy Посмотреть сообщение
а вот почему так может быть: кнопка срабатывает, то есть в адресной строке видно, что данные на событие (isset($_POST['addNewItem'])) формируются (и где-то в сессии сидят), но в базе данных тишина. А если заместо кнопки 'addNewItem', я в if подставлю название поля itemName (то есть получется строчка
Код:
if(isset($_POST['itemName']))
данные поступают в базу?
Для передачи значения через <button> нужно указать type="submit", ну и значение какое-то желательно установить:
Код HTML:
<button type="submit" value="1" name="addNewItem" >Добавить новый товар</button>
Однако – добавление данных в БД имеет смысл только тогда, когда заполнено поле itemName.
Поэтому нужно проверять именно наличие данных в itemName:
PHP код:
if(!empty($_POST['itemName'])) 
Andkorol вне форума Ответить с цитированием
Старый 11.04.2014, 23:35   #6
Andkorol
Старожил
 
Регистрация: 31.05.2010
Сообщений: 3,301
По умолчанию

Цитата:
Сообщение от Blondy Посмотреть сообщение
А то сидишь днями, разбираешь примеры, чтобы две строски кода запустить, и в результате они к тому же и запускаются криво.
У Kohana, к сожалению, с внятными мануалами просто беда.
Andkorol вне форума Ответить с цитированием
Старый 12.04.2014, 00:59   #7
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию

Спасибо Вам огромное!
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan
Blondy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Form 1 родительская а Form 2 дочерняя как их поменять местами ? reihtmonbern Общие вопросы Delphi 7 27.12.2013 00:00
Как избавиться от глупости victorshkoda Win Api 7 22.03.2013 14:19
confirm в javaScript kuba1981 JavaScript, Ajax 5 15.02.2013 17:58
Как избавиться от #Н/Д? kachorro Microsoft Office Excel 10 26.04.2012 06:38
IE7. Как получить параметры окна confirm()? Doda Windows 1 24.04.2009 10:22