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

130

Un tipo llamó a uno de mis presentaciones Snipplr "basura" porque he usado if ($_SERVER['REQUEST_METHOD'] == 'POST')en lugar deif ($_POST)

Verificar el método de solicitud me parece más correcto porque eso es lo que realmente quiero hacer. ¿Hay alguna diferencia operativa entre los dos o es solo un problema de claridad de código?

Scott
fuente
214
Dile a ese tipo que apesta.
Vinko Vrsalovic 03 de
12
Debería usar en ===lugar de ==aquí como 0 == 'POST'.
dave1010
55
$ _SERVER ["REQUEST_METHOD"] puede contener "POST" para solicitudes HTTP GET en algunas instalaciones PHP + Apache2. Como el mío. Y así es como llegué aquí.
Tiberiu-Ionuț Stan
3
@ Tiberiu-IonuțStan Si eso es cierto (lo cual no creo que sea), es un error muy grave. ¿Puede proporcionar un enlace a un informe de error de PHP o Apache? ¿Pasos para reproducir? Tal como están las cosas, simplemente no te creo.
Mark Amery
1
@ dave1010 ¿Por qué $_SERVER['REQUEST_METHOD']alguna vez sería el número 0? Que yo sepa, eso es imposible.
Mark Amery

Respuestas:

169

Bueno, en realidad no hacen lo mismo.

$_SERVER['REQUEST_METHOD'] contiene el método de solicitud (sorpresa).

$_POST contiene cualquier dato publicado.

Es posible que una solicitud POST no contenga datos POST.

Compruebo el método de solicitud: en realidad nunca pensé en probar la $_POSTmatriz. Sin embargo, verifico los campos de publicación requeridos. Por lo tanto, una solicitud de publicación vacía le daría al usuario muchos mensajes de error, lo que tiene sentido para mí.

GNUD
fuente
Teóricamente, podría ser posible que el método de solicitud sea 'post' (minúsculas o incluso mayúsculas y minúsculas). ¿PHP desinfecta automáticamente esto en GET y POST?
Boldewyn
Después de una breve prueba, mi PHP 5.2 en WinXP obviamente no lo hace, por lo que probablemente el método request_ debería desinfectarse solo en mayúsculas.
Boldewyn
3
@Boldewyn No, no lo hace, pero si el cliente le envía un método de solicitud de 'publicar' o 'Publicar' cuando tienen la intención de realizar una solicitud POST, están violando las especificaciones, ya que los métodos HTTP distinguen entre mayúsculas y minúsculas de acuerdo con la especificación y la especificación solo define el método POST, no, por ejemplo, el método post o Post o pOsT. Entro en más detalles sobre esto en mi respuesta aquí: stackoverflow.com/a/21511879/1709587 . Usted elige si desea o no forzar el método a mayúsculas para manejar el código de cliente que infringe las especificaciones.
Mark Amery
Y dado que no son lo mismo, tiene sentido que podamos usarlos para diferentes cosas: tipo y solicitud de carga útil. Me pregunto si esto hace que alguien vomite: uso $ _SERVER ['REQUEST_METHOD'] para averiguar qué estamos haciendo, y uso $ _REQUEST para acceder a la carga útil, que mantiene un poco de independencia entre los conceptos (en otras palabras, yo rara vez usa $ _POST o $ _GET específicamente).
grantwparks
@grantwparks Eso suena como un mal negocio. $ _GET y $ _POST tienen más que ver con el lugar donde se transportaron los datos. Considere: "curl -k -L -X POST -H 'Content-Type: text / csv' --data-binary \ @ sample.csv 'test-script.php? Test = 12345'" El valor "test" se completa $ _GET aunque el método sea POST.
txyoji
37

if ($_SERVER['REQUEST_METHOD'] == 'POST') es la forma correcta, puede enviar una solicitud de publicación sin ningún dato de publicación.

Stuartloxton
fuente
17

Solía ​​verificar $_POSThasta que me metí en problemas con datos POST más grandes y archivos cargados. Hay directivas de configuración post_max_sizey upload_max_filesize, si se supera alguna de ellas, la $_POSTmatriz no se rellena.

Entonces, la "forma segura" es verificar $_SERVER['REQUEST_METHOD']. Sin embargo, todavía tiene que usar isset()en todas las $_POSTvariables, y no importa si verifica o no $_SERVER['REQUEST_METHOD'].

binaryLV
fuente
9

Si su aplicación necesita reaccionar a solicitud de tipo post, use esto:

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
}

Si su aplicación necesita reaccionar ante cualquier dato recibido a través de una solicitud posterior, use esto:

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

Es específico de la implementación, pero vas a usar ambos, + $ _FILES superglobal.

DUzun
fuente
3

Ambos son correctos. Personalmente, prefiero su enfoque mejor por su verbosidad, pero realmente depende de sus preferencias personales.

Por otro lado, se ejecuta si ($ _ POST) no arrojaría un error: la matriz $ _POST existe independientemente de si la solicitud se envió con encabezados POST. Una matriz vacía se convierte en falso en un cheque booleano.

Eran Galperin
fuente
tal vez en 2009, pero una matriz vacía! = falso
clockw0rk
1
Es posible que te hayas perdido la palabra "elenco". La declaración dentro de una estructura "if" se convierte en un valor booleano y, por lo tanto, una matriz vacía se convierte en un valor booleano falso. Incluso en 2020
Eran Galperin
jajaja, tienes razón. +1
clockw0rk hace
3

Puede enviar un formulario presionando la tecla Intro (es decir, sin hacer clic en el botón Enviar) en la mayoría de los navegadores, pero esto no necesariamente envía el envío como una variable, por lo que es posible enviar un formulario vacío, es decir $_POST, estará vacío, pero el formulario seguirá ha generado una solicitud de publicación http a la página php. En este caso if ($_SERVER['REQUEST_METHOD'] == 'POST')es mejor.

Eamon
fuente
1
En ese caso, $_POSTno estaría vacío: sería una matriz con valores vacíos.
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
fuente
44
Aunque su respuesta puede ser correcta, ¡no es útil sin explicación! Por favor, eche un vistazo a Cómo responder ! ¡Gracias!
jkalden
0

Siempre que necesite acceder a mis scripts PHP con más de un método, lo que hago es:

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

Comprueba si la página se ha llamado a través de POST (en lugar de GET, HEAD, etc.). Cuando escribe una URL en la barra de menú, la página se llama a través de GET. Sin embargo, cuando envía un formulario con method = "post", la página de acción se llama con POST.

shreekanth
fuente
-3

Es realmente un 6 de uno, media docena de la otra situación.

El único argumento posible en contra de su enfoque es $ _SERVER ['REQUEST_METHOD'] == 'POST' no se puede completar en ciertos servidores web / configuración, mientras que la matriz $ _POST siempre existirá en PHP4 / PHP5 (y si no ' t existe, tienes problemas más grandes (- :)

Alan Storm
fuente
-17

Ambos funcionan de la misma manera, pero $_POSTdeben usarse ya que son más limpios. Puede agregarlo isset()para verificar que existe.

Alex Reino Unido
fuente
66
$_POSTsiempre existirá, aunque puede estar vacío (que se convierte en booleano false). ¿Y qué quieres decir con "limpiador"?
TRiG
2
tal vez quiso decir que se necesitan menos caracteres para escribir en el teclado = P
Julian