La extensión cURL de PHP permite realizar peticiones HTTP desde el lado del servidor: consumir APIs REST, descargar ficheros, enviar datos a terceros o autenticarse contra servicios externos. Aunque existen librerÃas como Guzzle que envuelven cURL con una API más cómoda, entender las opciones de CURLOPT es fundamental para cualquier desarrollador PHP.
GET básico con cabeceras
<?php
// Petición GET básica
$ch = curl_init('https://jsonplaceholder.typicode.com/posts/1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, // devolver la respuesta como string
CURLOPT_FOLLOWLOCATION => true, // seguir redirecciones
CURLOPT_MAXREDIRS => 5, // máximo de redirecciones
CURLOPT_TIMEOUT => 10, // timeout total en segundos
CURLOPT_CONNECTTIMEOUT => 5, // timeout de conexión
CURLOPT_USERAGENT => 'MiApp/1.0 (PHP)',
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Authorization: Bearer ' . $token,
],
]);
$respuesta = curl_exec($ch);
$codigoHTTP = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new RuntimeException("cURL error: $error");
}
if ($codigoHTTP !== 200) {
throw new RuntimeException("HTTP $codigoHTTP al llamar a la API.");
}
$datos = json_decode($respuesta, true);
echo $datos['title'];
?>
POST con formulario y con JSON
<?php
// POST con datos de formulario (application/x-www-form-urlencoded)
$ch = curl_init('https://api.ejemplo.com/login');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'email' => '[email protected]',
'password' => 'secreto123',
]),
]);
$respuesta = curl_exec($ch);
curl_close($ch);
// POST con cuerpo JSON (application/json)
$datos = ['nombre' => 'Ana', 'email' => '[email protected]', 'rol' => 'editor'];
$json = json_encode($datos);
$ch = curl_init('https://api.ejemplo.com/usuarios');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($json),
'Authorization: Bearer ' . $apiToken,
],
]);
$respuesta = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
?>
Timeouts y gestión de errores
<?php
function peticionSegura(string $url, array $opciones = []): array
{
$ch = curl_init($url);
curl_setopt_array($ch, array_merge([
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => true, // verificar certificado SSL
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_ENCODING => '', // aceptar cualquier encoding (gzip, etc.)
], $opciones));
$cuerpo = curl_exec($ch);
$codigo = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$tiempoTotal = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
$errorMsg = curl_error($ch);
curl_close($ch);
if ($cuerpo === false || $errorMsg) {
throw new RuntimeException("Error cURL: $errorMsg");
}
return [
'codigo' => $codigo,
'cuerpo' => $cuerpo,
'tiempo' => $tiempoTotal,
];
}
$resultado = peticionSegura('https://api.github.com/repos/php/php-src');
$repo = json_decode($resultado['cuerpo'], true);
echo "Estrellas: " . $repo['stargazers_count'];
?>
Peticiones en paralelo con curl_multi
curl_multi_* permite ejecutar varias peticiones HTTP a la vez sin esperar a que termine cada una antes de iniciar la siguiente, lo que reduce el tiempo total cuando hay que llamar a varios endpoints.
<?php
function peticionesParalelas(array $urls): array
{
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $id => $url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
curl_multi_add_handle($mh, $ch);
$handles[$id] = $ch;
}
// Ejecutar hasta que todas terminen
$activas = null;
do {
$estado = curl_multi_exec($mh, $activas);
if ($activas) {
curl_multi_select($mh); // esperar actividad en algún handle
}
} while ($activas > 0 && $estado === CURLM_OK);
$resultados = [];
foreach ($handles as $id => $ch) {
$resultados[$id] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
return $resultados;
}
$urls = [
'usuarios' => 'https://jsonplaceholder.typicode.com/users',
'posts' => 'https://jsonplaceholder.typicode.com/posts',
'albums' => 'https://jsonplaceholder.typicode.com/albums',
];
$resultados = peticionesParalelas($urls);
$usuarios = json_decode($resultados['usuarios'], true);
$posts = json_decode($resultados['posts'], true);
?>
La documentación oficial de la extensión cURL de PHP lista todas las constantes CURLOPT_* disponibles, las opciones de autenticación (básica, digest, OAuth), la gestión de cookies en sesiones cURL y el uso de ficheros de certificados personalizados.
