Пусть у нас есть контроллер Test и в нем действие form с формой и действие result, на которое эта форма отправляется.
Вот маршруты, соответствующие описанному:
<?php
Route::get('test/form', 'TestController@form');
Route::get('test/result', 'TestController@result');
?>
Вот форма, расположенная в представлении действия form:
<form action="/test/result/">
<input type="text" name="text">
<input type="submit">
</form>
Как вы видите, эта форма отправляется на адрес /test/result/, то есть на действие result.
Так как атрибут method у формы не указан, то эта форма отправляется HTTP методом GET. Можно указать метод и в явном виде, добавив в форму атрибут method:
<form action="/test/result/" method="GET">
<input type="text" name="text">
<input type="submit">
</form>
Давайте теперь будем отправлять форму методом POST. Для этого поменяем значение атрибута method с GET на POST:
<form action="/test/result/" method="POST">
<input type="text" name="text">
<input type="submit">
</form>
Однако, если ограничиться только этим изменением, то отправка формы приведет к ошибке. Суть ошибки будет сводиться к тому, что нашему маршруту разрешено принимать данные только методом GET, но не методом POST.
Дело в том, что в нашем маршруте используется метод get класса Route:
<?php
Route::get('test/result', 'TestController@result');
?>
Данный метод get разрешает отправлять только GET запросы. Чтобы разрешить отправку POST запросов, поменяем метод get на метод post:
<?php
Route::post('test/result', 'TestController@result');
?>
Теперь наш маршрут будет принимать POST запросы (но уже не будет принимать GET).
Попытка отправить форму, однако, все равно приведет к ошибке с текстом "The page has expired due to inactivity.". Данная ошибка уже имеет другую природу, не связанную с маршрутами: просто в форме, отправляемой методом POST необходимо передавать CSRF-токен для защиты от хакерских атак.
CSRF (англ. Сross Site Request Forgery - "межсайтовая подделка запроса") - вид атак на посетителей сайтов, использующий недостатки протокола HTTP.
Для исправления проблемы проблемы в тексте формы нужно написать следующую команду: {{ csrf_field() }}
Сделаем это:
<form action="/test/result/" method="POST">
{{ csrf_field() }}
<input type="text" name="text">
<input type="submit">
</form>
Вот теперь наша форма наконец станет отправляться методом POST. Для получения отправленных данных нужно использовать тот же объект Request - он содержит одновременно и данные, отправленные методом GET, и данные, отправленные методом POST.
Сделайте два действия. В представлении первого действия покажите форму, которая будет отправляться на второе действие методом POST. Выведите данные, отправленные через форму, в представлении второго действия.
Получение и проверка метода запроса
Для получения метода HTTP запроса можно использовать метод method:
<?php
$method = $request->method();
?>
Можно также использовать метод isMethod для проверки соответствия HTTP-метода заданной строке:
<?php
if ($request->isMethod('post')) {
}
?>
Напоминаю вам, что запрос к сайту методом GET - это не только отправка формы этим методом, но и просто запрос любого URL сайта.
Выведите на экран метод HTTP запроса.
Если метод HTTP запроса - GET, то выведите на экран сообщение '!', а если POST, то сообщение '!!'.
Отправка формы и получение в одном действии
Когда мы отправляли форму методом GET, то использовали одно и тоже действие и для показа формы и для получения данных.
При отправке методом POST так просто это не получится, так как при показе формы осуществляется GET запрос к сайту, а при отправке формы - POST.
То есть для решения проблемы нужно сделать на один и тот же адрес два маршрута - один с методом Route::get, а другой - с методом Route::post:
<?php
Route::get('test/form', 'TestController@form');
Route::post('test/form', 'TestController@form');
?>
Для избежания дублирования адресов можно использовать метод match:
<?php
Route::match(['get', 'post'], 'test/form', 'TestController@form');
?>
Используя метод isMethod можно отделить первое обращение к действию для получения формы от второго обращения к действию после отправки формы:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function form(Request $request)
{
// Выполнится при первом заходе:
if ($request->isMethod('get')) {
return view('test.form'); // представление с формой
}
// Выполнится после отправки формы:
if ($request->isMethod('post')) {
$text = $request->input('text');
return view('test.result', ['text', $text]); // представление с результатом
}
}
}
?>
Сделайте форму, которая будет спрашивать у пользователя два числа с помощью двух инпутов. После отправки формы методом POST выведите на экран сумму введенных чисел. Пусть и форма, и результат показываются одним действием.