Tu primera llamada a Claude u OpenAI desde PHP en 30 líneas
Es el momento. En esta lección haces la primera llamada real a una IA desde PHP. Te enseño tanto la versión Claude (Anthropic) como la OpenAI — eliges la que prefieras o pruebas ambas. Las dos tienen tier gratuito de inicio.
Lo que vas a hacer
- Obtener tu API key de Anthropic o OpenAI.
- Hacer tu primera llamada con
symfony/http-client. - Parsear la respuesta JSON y manejar errores básicos.
- Probar el mismo código integrado en un controller Symfony.
1. Obtener la API key
Opción A — Anthropic (Claude) ⭐ recomendado
- Crea cuenta en console.anthropic.com
- Settings → API Keys → Create Key
- Copia la clave (empieza por
sk-ant-...) y guárdala en tu.envcomoANTHROPIC_API_KEY - Anthropic da créditos gratis al registrarse, suficientes para todo el curso
Opción B — OpenAI
- Crea cuenta en platform.openai.com
- API Keys → Create new secret key
- Copia la clave (empieza por
sk-...) y guárdala en tu.envcomoOPENAI_API_KEY - Necesitas añadir un método de pago, pero los costes son céntimos para este curso
2. Llamada a Claude desde PHP plano
Crea claude.php:
<?php
require __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
use Symfony\Component\HttpClient\HttpClient;
$client = HttpClient::create();
$response = $client->request('POST', 'https://api.anthropic.com/v1/messages', [
'headers' => [
'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
'anthropic-version' => '2023-06-01',
'content-type' => 'application/json',
],
'json' => [
'model' => 'claude-haiku-4-5-20251001',
'max_tokens' => 300,
'messages' => [
['role' => 'user', 'content' => 'Resume en 3 puntos qué es PHP para alguien que solo conoce JavaScript.'],
],
],
]);
$data = $response->toArray();
echo $data['content'][0]['text'] . "\n";
Ejecuta:
php claude.php
En 1-2 segundos verás la respuesta generada por Claude. Has hecho tu primera llamada a IA generativa desde PHP.
3. Misma llamada con OpenAI
Crea openai.php:
<?php
require __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
use Symfony\Component\HttpClient\HttpClient;
$client = HttpClient::create();
$response = $client->request('POST', 'https://api.openai.com/v1/chat/completions', [
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['OPENAI_API_KEY'],
'Content-Type' => 'application/json',
],
'json' => [
'model' => 'gpt-4o-mini',
'max_tokens' => 300,
'messages' => [
['role' => 'user', 'content' => 'Resume en 3 puntos qué es PHP para alguien que solo conoce JavaScript.'],
],
],
]);
$data = $response->toArray();
echo $data['choices'][0]['message']['content'] . "\n";
Como ves, la estructura es prácticamente idéntica. Solo cambian: la URL, el header de autenticación y la ruta de la respuesta para extraer el texto.
4. Manejo básico de errores
En código real necesitas envolver la llamada en try/catch para manejar:
- Errores de red (timeout, sin conexión)
- Errores de autenticación (API key inválida → 401)
- Rate limit excedido (429)
- Respuesta inesperada del modelo
<?php
use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
try {
$response = $client->request('POST', $url, [...]);
$data = $response->toArray(); // lanza si status >= 400
return $data['content'][0]['text'];
} catch (HttpExceptionInterface $e) {
// Error HTTP (401, 429, 500...)
$status = $e->getResponse()->getStatusCode();
error_log("Error IA [$status]: " . $e->getMessage());
return "Error temporal, inténtalo de nuevo en un minuto.";
} catch (TransportException $e) {
// Error de red (timeout, DNS, etc.)
error_log("Error red IA: " . $e->getMessage());
return "No hay conexión, prueba más tarde.";
}
5. El mismo código dentro de un controller Symfony
Si tu proyecto es Symfony, esto se simplifica aún más porque ya tienes HttpClientInterface inyectable:
<?php
// src/Controller/IaController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class IaController extends AbstractController
{
public function __construct(
private HttpClientInterface $http,
) {}
#[Route('/api/preguntar', methods: ['POST'])]
public function preguntar(): JsonResponse
{
$response = $this->http->request('POST', 'https://api.anthropic.com/v1/messages', [
'headers' => [
'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
'anthropic-version' => '2023-06-01',
],
'json' => [
'model' => 'claude-haiku-4-5-20251001',
'max_tokens' => 500,
'messages' => [
['role' => 'user', 'content' => 'Hola, ¿qué hora es en formato humano?'],
],
],
]);
$data = $response->toArray();
return $this->json([
'respuesta' => $data['content'][0]['text'],
]);
}
}
Eso es una endpoint REST de tu Symfony que genera texto con IA. 15 líneas de código real para producción.
Costes y control
- Una llamada con respuesta corta (Claude Haiku o GPT-4o mini): unos 0.001 €.
- 50 llamadas para probar todo el curso: céntimos.
- Revisa siempre el dashboard de tu proveedor para ver consumo en tiempo real.
- Usa
max_tokensbajo (200-500) en pruebas para limitar coste.
Checklist antes de marcar completada
- Tienes tu API key de Anthropic u OpenAI guardada en
.env. - Has ejecutado
php claude.php(oopenai.php) y ves la respuesta del modelo. - Entiendes la estructura de la petición: URL + headers + body JSON.
- Entiendes que
try/catches obligatorio en código real (red puede fallar). - (Bonus) Has probado el código del controller Symfony si tienes un proyecto Symfony.
En la próxima lección dejamos atrás los "hola mundo" y construimos algo útil: generar 50 descripciones de producto en menos de 30 segundos. Es el patrón más común de IA en ecommerce PHP.
📝 Comprueba lo aprendido
Responde estas 4 preguntas y acierta al menos el 60% para desbloquear el botón "Marcar como completada".