$ _POST vs. $ _SERVER ['REQUEST_METHOD'] == 'POST'

130

Um cara chamou uma das minhas submissões do Snipplr de "porcaria" porque eu usei em if ($_SERVER['REQUEST_METHOD'] == 'POST')vez deif ($_POST)

Verificar o método de solicitação parece mais correto para mim, porque é isso que eu realmente quero fazer. Existe alguma diferença operacional entre os dois ou isso é apenas uma questão de clareza de código?

Scott
fonte
214
Diga ao cara que ele é péssimo.
Vinko Vrsalovic
12
Você deve usar em ===vez de ==aqui como 0 == 'POST'.
Dave1010
5
$ _SERVER ["REQUEST_METHOD"] pode conter "POST" para solicitações HTTP GET em algumas instalações do PHP + Apache2. Como o meu. E foi assim que cheguei aqui.
Tiberiu-Ionuț Stan
3
@ Tiberiu-IonuțStan Se isso é verdade (o que eu não acredito que seja), é um bug muito grave. Você pode fornecer um link para um relatório de bug do PHP ou Apache? Passos para reproduzir? Como é, eu simplesmente não acredito em você.
Mark Amery
1
@ dave1010 Por que $_SERVER['REQUEST_METHOD']algum dia esse número seria 0? Tanto quanto eu sei, isso é impossível.
Mark Amery

Respostas:

169

Bem, eles não fazem a mesma coisa, realmente.

$_SERVER['REQUEST_METHOD'] contém o método de solicitação (surpresa).

$_POST contém quaisquer dados de postagem.

É possível que uma solicitação POST não contenha dados POST.

Verifico o método de solicitação - na verdade, nunca pensei em testar a $_POSTmatriz. Verifico os campos de postagem obrigatórios. Portanto, uma solicitação de postagem vazia daria ao usuário muitas mensagens de erro - o que faz sentido para mim.

gnud
fonte
Teoricamente, é possível que o método de solicitação seja 'post' (minúsculas ou até mistas). O PHP limpa automaticamente isso no GET e POST?
Boldewyn
Após um breve teste, meu PHP 5.2 no WinXP obviamente não o faz, então provavelmente o request_method deve ser higienizado apenas para maiúsculas.
Boldewyn
3
@Boldewyn Não, não é, mas se o cliente enviar a você um método de solicitação 'post' ou 'Post' quando pretender executar uma solicitação POST, eles violarão as especificações, pois os métodos HTTP diferenciam maiúsculas de minúsculas de acordo com a especificação e a especificação define apenas o método POST, não por exemplo, o método post ou Post ou pOsT. Entro em mais detalhes sobre isso na minha resposta aqui: stackoverflow.com/a/21511879/1709587 . Você deseja ou não coagir o método para maiúsculas para manipular o código do cliente que viola as especificações.
Mark Amery
E como não são a mesma coisa, faz sentido que possamos usá-los para coisas diferentes - digite e solicite carga útil. Gostaria de saber se isso faz alguém vomitar: eu uso $ _SERVER ['REQUEST_METHOD'] para descobrir o que estamos fazendo, e eu uso $ _REQUEST para acessar a carga útil, o que mantém um pouco de independência entre os conceitos (em outras palavras, eu raramente use $ _POST ou $ _GET especificamente).
Concessão #
@grantwparks Isso parece um mau negócio. $ _GET e $ _POST têm mais a ver com o local onde os dados foram transportados. Considere: "curl -k -L -X POST -H 'Tipo de conteúdo: text / csv' --dados-binários \ @ sample.csv 'test-script.php? Test = 12345'" O valor "test" é preenchido $ _GET, mesmo que o método seja POST.
Txyoji
37

if ($_SERVER['REQUEST_METHOD'] == 'POST') é a maneira correta, você pode enviar uma solicitação de postagem sem nenhum dado de postagem.

Stuartloxton
fonte
17

Eu costumava verificar $_POSTaté ter problemas com dados POST maiores e arquivos enviados. Existem diretivas de configuração post_max_sizee upload_max_filesize- se alguma delas for excedida, a $_POSTmatriz não será preenchida.

Portanto, o "caminho seguro" é verificar $_SERVER['REQUEST_METHOD']. Você ainda precisa usar isset()todas as $_POSTvariáveis, e isso não importa, se você verifica ou não $_SERVER['REQUEST_METHOD'].

binaryLV
fonte
9

Se seu aplicativo precisar reagir a pedido do tipo post, use este:

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
}

Se o seu aplicativo precisar reagir a qualquer dado recebido por meio da solicitação posterior, use o seguinte:

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
   // ...
}

É específico da implementação, mas você vai usar os dois, + $ _FILES superglobal.

DUzun
fonte
3

Ambos estão corretos. Pessoalmente, prefiro sua abordagem melhor pela sua verbosidade, mas é realmente uma preferência pessoal.

Disponível, executando se ($ _ POST) não gerasse um erro - a matriz $ _POST existe independentemente se a solicitação foi enviada com os cabeçalhos POST. Uma matriz vazia é convertida em false em uma verificação booleana.

Eran Galperin
fonte
talvez em 2009, mas uma matriz vazia! = false
clockw0rk 28/07
1
Você pode ter perdido a palavra "elenco". A instrução dentro de uma estrutura "se" é convertida em um booleano e uma matriz vazia é convertida em um falso booleano. Mesmo em 2020
Eran Galperin
lol, você está certo. +1
clockw0rk
3

Você pode enviar um formulário pressionando a tecla Enter (ou seja, sem clicar no botão Enviar) na maioria dos navegadores, mas isso não envia necessariamente o envio como uma variável - portanto, é possível enviar um formulário vazio, ou seja $_POST, ficará vazio, mas o formulário ainda será geraram uma solicitação de postagem http para a página php. Neste caso if ($_SERVER['REQUEST_METHOD'] == 'POST')é melhor.

Eamon
fonte
1
Nesse caso, $_POSTnão estaria vazio: seria uma matriz com valores vazios.
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");
    }
}
Amama Alaeddine
fonte
4
Embora sua resposta possa estar correta, ela não é útil sem explicações! Por favor, dê uma olhada em Como responder ! Obrigado!
jkalden
0

Desde que eu precise acessar meus scripts PHP com mais de um método, o que eu faço é:

if (in_array($_SERVER['REQUEST_METHOD'],array("GET","POST","DELETE"))) {
// do wathever I do 
}
Alfredo Rahn
fonte
-1

Ele verifica se a página foi chamada através do POST (ao contrário de GET, HEAD, etc). Quando você digita um URL na barra de menus, a página é chamada por meio de GET. No entanto, quando você envia um formulário com o método = "post", a página de ação é chamada com POST.

shreekanth
fonte
-3

É realmente um 6 de um, meia dúzia da outra situação.

O único argumento possível contra sua abordagem é $ _SERVER ['REQUEST_METHOD'] == 'POST' pode não ser preenchido em determinados servidores da Web / configuração, enquanto o array $ _POST sempre existirá no PHP4 / PHP5 (e se isso não acontecer ' t existe, você tem problemas maiores (- :)

Alan Storm
fonte
-17

Ambos funcionam da mesma maneira, mas $_POSTdevem ser usados, pois são mais limpos. Você pode adicionar isset()a ele para verificar se ele existe.

Alex UK
fonte
6
$_POSTsempre existirá, embora possa estar vazio (que é convertido em booleano false). E o que você quer dizer com "limpador"?
TRiG
2
talvez ele significou que menos caracteres são necessários para digitar no teclado = P
Julian