/
HTTP

Procesamiento de peticiones ajax POST en PHP

01. 11. 2019

Mientras desarrollaba aplicaciones ajax Vue.js, después de años finalmente descubrí cómo usar ajax en PHP y cómo recibir datos por el método POST.

La variable superglobal $_POST sólo está disponible para los formularios

En PHP, la variable superglobal $_POST está comúnmente disponible para mantener los datos enviados desde un formulario.

Es relativamente fácil de usar.

En el lado de HTML, necesita crear un formulario:

<form action="process.php" method="post">
Jméno: <input type="text" name="username">
<input type="submit" value="Odeslat">
</form>

Y luego en el archivo process.php se puede acceder a los valores como elementos del array:

echo htmlspecialchars($_POST['nombre de usuario'] ?? '');

Atención:

Con este sencillo enfoque, todo el mundo podría pensar que los datos POSTed se definen automáticamente como índices de matriz en la variable $_POST. Pero esto no es cierto.

De hecho, la razón por la que los datos enviados desde un formulario utilizando el método POST se escriben en la variable $_POST es porque el navegador envía automáticamente la cabecera HTTP 'Content-Type': 'application/x-www-form-urlencoded' cuando se envía el formulario HTML.

Sin una cabecera correctamente configurada, simplemente no se puede acceder a los valores y tenemos que utilizar una solución engañosa.

Envío de datos por ajax

Al intentar enviar datos mediante ajax, tenemos que cambiar un poco el enfoque en el lado de PHP. Puedes leer el debate en Facebook para conocer los detalles.

En javascript, por ejemplo, puedes utilizar la librería axios para enviar datos mediante ajax. Para utilizarlo fácilmente, basta con enlazar el javascript del servidor CDN y utilizarlo directamente:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.post('/api/form-process', {
username: 'Jméno uživatele'
})
.then(response => {
// Zpracování odpovědi z API
alert(response.data.message); // Vyhodí hlášku se zprávou
});
</script>

En este caso sencillo, se llama a la URL '/api/form-process' mediante ajax y el método POST pasa el objeto { username: 'User name' }. La propia biblioteca ya se encarga de la logística de pasar los datos automáticamente, por lo que se envían serializados como Json. En la jerga de los desarrolladores de frontend, esto se llama json payload.

Por el lado de PHP, esperaría usarlo como un formulario (después de todo, era un método POST):

echo htmlspecialchars($_POST['nombre de usuario'] ?? '');

Sin embargo, en este caso el campo $_POST estará vacío y no se pasará ningún dato. La variable $_POST sólo se utiliza para los datos recuperados de los formularios (se puede saber por la cabecera HTTP que no tiramos).

Así que en este caso necesitamos obtener los datos directamente de la petición HTTP, para lo cual se utiliza la solución inteligente. Así, es fácil de usar:

$data = json_decode(file_get_contents('php://entrada'), true);
echo htmlspecialchars($data['nombre de usuario'] ?? '');
header('Content-Type: application/json');
echo json_encode([
'mensaje' => 'La enredadera del servidor',
]);
die;

Como ejemplo, también proporciono una respuesta sencilla en javascript. Lo importante es lanzar correctamente la cabecera HTTP 'Content-Type: application/json' y salir del script una vez enviados todos los datos.

Imposición del uso de $_POST.

Si todavía quiere tratar los datos enviados directamente como un formulario, hay una manera de transferirlos. En este caso, hay que modificar la creación de la propia consulta ajax y pasar las cabeceras HTTP correctamente:

axios.post(
'/api/form-process',
{
username: 'Jméno uživatele'
},
{
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}
).then(response => {
// Nějaké zpracování
});

En este caso, sin embargo, el procesamiento en el lado de PHP no será agradable, porque todavía tenemos que corregir los datos y convertirlos en un array.

Me las arreglé para llegar a este horror:

if (\count($_POST) === 1
&& preg_match('/^\{.*\}$/', $post = array_keys($_POST)[0])
&& ($json = json_decode($post)) instanceof \stdClass
) {
foreach ($json as $key => $value) {
$_POST[$key] = $value;
unset($_POST[$post]);
}
}
echo htmlspecialchars($_POST['nombre de usuario'] ?? '');

Sin embargo, es mucho mejor quedarse con el primer enfoque y utilizar el método 'php://input' para recuperar los datos.

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
4.