$ _POST против $ _SERVER ['REQUEST_METHOD'] == 'POST'

130

Какой-то парень назвал одно из моих представлений Snipplr "дерьмом", потому что я использовал if ($_SERVER['REQUEST_METHOD'] == 'POST')вместоif ($_POST)

Мне кажется более правильным проверка метода запроса, потому что я действительно хочу этим заниматься. Есть ли между ними операционная разница или это просто проблема ясности кода?

Скотт
источник
214
Скажи этому парню, что он отстой.
Винко Врсалович 03
12
Вы должны использовать ===вместо ==здесь as 0 == 'POST'.
dave1010
5
$ _SERVER ["REQUEST_METHOD"] может содержать "POST" для запросов HTTP GET на некоторых установках PHP + Apache2. Как у меня. И вот как я сюда попал.
Tiberiu-Ionuț Stan
3
@ Tiberiu-IonuțStan Если это правда (во что я не верю), это очень серьезная ошибка. Можете ли вы предоставить ссылку на отчет об ошибке PHP или Apache? Действия по воспроизведению? Я просто не верю тебе.
Марк Эмери
1
@ dave1010 Зачем вообще нужен $_SERVER['REQUEST_METHOD']номер 0? Насколько я знаю, это невозможно.
Марк Эймери

Ответы:

169

Ну, на самом деле они не делают то же самое.

$_SERVER['REQUEST_METHOD'] содержит метод запроса (сюрприз).

$_POST содержит любые данные поста.

Запрос POST может не содержать данных POST.

Проверяю метод запроса - вообще-то никогда не думал о тестировании $_POSTмассива. Тем не менее, я проверяю обязательные поля для публикации. Таким образом, пустой почтовый запрос дал бы пользователю много сообщений об ошибках, что для меня имеет смысл.

gnud
источник
Теоретически может быть возможно, что метод запроса будет «post» (нижний или даже смешанный регистр). Автоматически ли PHP дезинфицирует это при GET и POST?
Boldewyn
После короткого теста мой PHP 5.2 на WinXP, очевидно, этого не делает, поэтому, вероятно, request_method следует очистить только до верхнего регистра.
Boldewyn
3
@Boldewyn Нет, это не так, но если клиент отправляет вам метод запроса 'post' или 'Post', когда они намереваются выполнить запрос POST, то они нарушают спецификацию, поскольку методы HTTP чувствительны к регистру в соответствии со спецификацией и спецификацией определяется только метод POST, а не, например, метод post, Post или pOsT. Я подробно расскажу об этом в своем ответе здесь: stackoverflow.com/a/21511879/1709587 . Независимо от того, хотите ли вы перевести метод в верхний регистр для обработки клиентского кода, нарушающего спецификации, - ваш выбор.
Марк Эймери
И поскольку это не одно и то же, имеет смысл использовать их для разных целей - типа и запроса полезной нагрузки. Интересно, заставляет ли это кого-то биться: я использую $ _SERVER ['REQUEST_METHOD'], чтобы выяснить, что мы делаем, и я использую $ _REQUEST для доступа к полезной нагрузке, которая поддерживает небольшую независимость между концепциями (другими словами, я редко используют специально $ _POST или $ _GET).
grantwparks 08
@grantwparks Звучит как плохая сделка. $ _GET и $ _POST больше связаны с тем, куда были переданы данные. Рассмотрим: "curl -k -L -X POST -H 'Content-Type: text / csv' --data-binary \ @ sample.csv 'test-script.php? Test = 12345'" Значение "test" заполняется $ _GET, даже если это метод POST.
txyoji 01
37

if ($_SERVER['REQUEST_METHOD'] == 'POST') - правильный способ, вы можете отправить почтовый запрос без каких-либо данных.

stuartloxton
источник
17

Раньше я проверял, $_POSTпока у меня не возникали проблемы с большими данными POST и загруженными файлами. Есть директивы конфигурации post_max_sizeи upload_max_filesize- если какая-либо из них превышена, $_POSTмассив не заполняется.

Так что «безопасный способ» - это проверить $_SERVER['REQUEST_METHOD']. Тем не менее, вам все равно придется использовать isset()для каждой $_POSTпеременной, и не имеет значения, проверяете вы или нет $_SERVER['REQUEST_METHOD'].

binaryLV
источник
9

Если ваше приложение должно реагировать на запрос типа post, используйте это:

if(strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') { // if form submitted with post method
    // validate request, 
    // manage post request differently, 
    // log or don't log request,
    // redirect to avoid resubmition on F5 etc
}

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

if(!empty($_POST)) {  // if received any post data
   // process $_POST values, 
   // save data to DB,
   // ... 
}

if(!empty($_FILES)) { // if received any "post" files
   // validate uploaded FILES
   // move to uploaded dir
   // ...
}

Это зависит от реализации, но вы собираетесь использовать оба, + $ _FILES superglobal.

DUzun
источник
3

Оба они правы. Лично я предпочитаю ваш подход из-за его многословности, но на самом деле это зависит от личных предпочтений.

В автономном режиме выполнение if ($ _ POST) не вызовет ошибки - массив $ _POST существует независимо от того, был ли запрос отправлен с заголовками POST. Пустой массив приводится к false при логической проверке.

Эран Гальперин
источник
возможно в 2009 году, но пустой массив! = false
clockw0rk
1
Вы могли пропустить слово «бросить». Оператор внутри структуры if преобразуется в логическое значение, а пустой массив, таким образом, преобразуется в логическое значение false. Даже в 2020 году
Эран Гальперин
лол, ты прав. +1
clockw0rk
3

Вы можете отправить форму, нажав клавишу ввода (то есть не нажимая кнопку отправки) в большинстве браузеров, но это не обязательно отправляет отправку как переменную - поэтому можно отправить пустую форму, т.е. $_POSTона будет пустой, но форма все равно будет создали HTTP-запрос на php-страницу. В этом случае if ($_SERVER['REQUEST_METHOD'] == 'POST')лучше.

Имон
источник
1
В этом случае $_POSTне будет пустым: это будет массив с пустыми значениями.
TRiG
0
$this->method = $_SERVER['REQUEST_METHOD'];
if ($this->method == 'POST' && array_key_exists('HTTP_X_HTTP_METHOD', $_SERVER)) {
    if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'DELETE') {
        $this->method = 'DELETE';
    } else if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'PUT') {
        $this->method = 'PUT';
    } else {
        throw new Exception("Unexpected Header");
    }
}
Амама Алаэддин
источник
4
Хотя ваш ответ может быть правильным, он бесполезен без объяснения причин! Пожалуйста, посмотрите, как ответить ! Спасибо!
jkalden
0

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

if (in_array($_SERVER['REQUEST_METHOD'],array("GET","POST","DELETE"))) {
// do wathever I do 
}
Альфредо Ран
источник
-1

Он проверяет, была ли страница вызвана через POST (в отличие от GET, HEAD и т. Д.). Когда вы вводите URL-адрес в строке меню, страница вызывается через GET. Однако, когда вы отправляете форму с помощью method = "post", страница действия вызывается с помощью POST.

shreekanth
источник
-3

Это действительно 6 из одной, полдюжины другой ситуации.

Единственный возможный аргумент против вашего подхода - $ _SERVER ['REQUEST_METHOD'] == 'POST' не может быть заполнен на определенных веб-серверах / конфигурации, тогда как массив $ _POST всегда будет существовать в PHP4 / PHP5 (и если это не так ' нет, у вас проблемы посерьезнее (- :)

Алан Сторм
источник
-17

Они оба работают одинаково, но $_POSTих следует использовать, так как они чище. Вы можете добавить isset()к нему, чтобы убедиться, что он существует.

Алекс Великобритания
источник
6
$_POSTвсегда будет существовать, хотя может быть пустым (преобразованным в логическое значение false). А что вы подразумеваете под «чище»?
TRiG
2
возможно, он имел в виду, что нужно меньше символов для ввода на клавиатуре = P
Джулиан