Die cURL-Extension gehört zu den wichtigsten Werkzeugen in PHP, wenn es um HTTP-Kommunikation geht. Während file_get_contents() für einfache GET-Anfragen ausreicht, bietet cURL volle Kontrolle über Request-Methoden, Header, Timeouts und Fehlerbehandlung. Den Einstiegspunkt bildet die Funktion curl_init(), die eine neue cURL-Session erstellt. In diesem Tutorial lernst du den kompletten cURL-Workflow kennen, von der Initialisierung mit curl_init() über die Konfiguration mit curl_setopt() bis zur Ausführung mit curl_exec(). Du siehst Beispiele für GET-Requests, POST-Requests und den Versand von JSON-Daten.

Zunächst wird erklärt, was cURL ist und warum es gegenüber file_get_contents() die bessere Wahl für HTTP-Anfragen darstellt.
Was ist cURL in PHP?
cURL steht für "Client URL" und ist eine Bibliothek zur Übertragung von Daten über verschiedene Netzwerkprotokolle. Die PHP-cURL-Extension stellt eine Schnittstelle zur libcurl-Bibliothek bereit, die unter anderem HTTP, HTTPS, FTP und FTPS unterstützt. Im Vergleich zu file_get_contents() bietet cURL deutlich mehr Konfigurationsmöglichkeiten. Du kannst benutzerdefinierte Header setzen, Zertifikate prüfen, Timeouts steuern und detaillierte Fehlerinformationen abrufen. Dadurch ist cURL die erste Wahl für die Kommunikation mit REST-APIs und alle Szenarien, in denen zuverlässige HTTP-Anfragen benötigt werden.
curl_init() im Detail
Die Funktion curl_init() erstellt eine neue cURL-Session und gibt ein Handle zurück. Ab PHP 8.0 handelt es sich dabei um ein CurlHandle-Objekt, während ältere PHP-Versionen eine Resource zurückgaben. Optional kann die Ziel-URL direkt als Parameter übergeben werden.
<?php
/* Variante 1: curl_init() ohne Parameter */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/daten');
/* Variante 2: URL direkt an curl_init() uebergeben */
$ch = curl_init('https://api.example.com/daten');
Beide Varianten sind funktional gleichwertig. Das zurückgegebene CurlHandle-Objekt wird anschließend an curl_setopt() und curl_exec() übergeben, um die Anfrage zu konfigurieren und auszuführen. Schlägt die Initialisierung fehl, gibt curl_init() den Wert false zurück.
Der typische cURL-Workflow
Jede cURL-Anfrage folgt einem festen Ablauf aus vier Schritten. Zuerst wird die Session initialisiert, dann werden Optionen gesetzt, die Anfrage wird ausgeführt und abschließend wird die Session geschlossen. Das folgende Diagramm veranschaulicht diesen Ablauf.
graph TD
A[curl_init] -->|Handle erstellen| B[curl_setopt]
B -->|Optionen setzen| C[curl_exec]
C -->|Request senden| D{Antwort ok?}
D -->|Erfolg| E[Antwort verarbeiten]
D -->|Fehler| F[curl_error]
E --> G[curl_close]
F --> G
Dieser Ablauf bildet das Grundgerüst für jede cURL-Anfrage in PHP. Die Funktion curl_close() ist ab PHP 8.0 nicht mehr zwingend erforderlich, da das CurlHandle-Objekt automatisch freigegeben wird. Dennoch gilt der explizite Aufruf als guter Stil, weil er die Absicht dokumentiert und die Abwärtskompatibilität sicherstellt.
CURLOPT_RETURNTRANSFER
Die Option CURLOPT_RETURNTRANSFER steuert, ob curl_exec() die Serverantwort als String zurückgibt. Ohne diese Option gibt curl_exec() bei Erfolg lediglich true zurück und schreibt die Antwort direkt in die Ausgabe. Setzt du CURLOPT_RETURNTRANSFER auf true, erhältst du die Antwort als String und kannst sie weiterverarbeiten.
<?php
$ch = curl_init('https://api.example.com/status');
/* Antwort als String zurueckgeben statt direkt ausgeben */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$antwort = curl_exec($ch);
curl_close($ch);
/* $antwort enthaelt jetzt den Response-Body als String */
echo $antwort;
CURLOPT_URL
Die Option CURLOPT_URL legt die Ziel-URL der Anfrage fest. Sie ist eine Alternative zur direkten Übergabe der URL an curl_init(). Diese Option ist besonders nützlich, wenn dasselbe cURL-Handle für mehrere aufeinanderfolgende Anfragen wiederverwendet werden soll, da die URL zwischen den Aufrufen geändert werden kann.
CURLOPT_CONNECTTIMEOUT und CURLOPT_TIMEOUT
Timeouts schützen deine Anwendung davor, bei langsamen oder nicht erreichbaren Servern endlos zu warten. CURLOPT_CONNECTTIMEOUT begrenzt die Zeit in Sekunden, die für den Verbindungsaufbau zum Server zur Verfügung steht. CURLOPT_TIMEOUT begrenzt die Gesamtdauer der gesamten Anfrage einschließlich Verbindungsaufbau und Datenübertragung. Beide Optionen sollten in produktiven Anwendungen immer gesetzt werden, um unkontrollierte Wartezeiten zu vermeiden.
GET-Request mit cURL ausführen
Ein GET-Request ist die Standardmethode von cURL und muss nicht explizit konfiguriert werden. Das folgende Beispiel zeigt einen vollständigen GET-Request mit Fehlerbehandlung und Auswertung des HTTP-Statuscodes.
<?php
$ch = curl_init('https://api.example.com/produkte');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$antwort = curl_exec($ch);
if ($antwort === false) {
echo 'cURL-Fehler: ' . curl_error($ch);
} else {
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo 'HTTP-Status: ' . $statusCode . "\n";
$daten = json_decode($antwort, true);
print_r($daten);
}
curl_close($ch);
Die Funktion curl_error() gibt eine lesbare Fehlermeldung zurück, wenn curl_exec() den Wert false liefert. Mit curl_getinfo() lassen sich zusätzliche Informationen zur Anfrage abrufen, darunter der HTTP-Statuscode und die benötigte Zeit. Die Prüfung mit === false ist wichtig, da ein leerer Antwort-String ebenfalls ein gültiges Ergebnis sein kann.
POST-Request mit cURL senden
Für einen POST-Request werden zwei zusätzliche Optionen benötigt. CURLOPT_POST aktiviert die POST-Methode und CURLOPT_POSTFIELDS enthält die zu sendenden Daten. Wird ein Array übergeben, sendet cURL die Daten im Format multipart/form-data. Ein String wird als application/x-www-form-urlencoded gesendet.
<?php
$ch = curl_init('https://api.example.com/kontakt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
/* Formulardaten als Array uebergeben */
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'name' => 'Max Mustermann',
'email' => 'max@example.com',
'nachricht' => 'Hallo, das ist ein Test.'
]);
$antwort = curl_exec($ch);
if ($antwort === false) {
echo 'Fehler: ' . curl_error($ch);
} else {
echo $antwort;
}
curl_close($ch);
Alternativ können die Daten auch als URL-kodierter String übergeben werden, zum Beispiel mit http_build_query(). In diesem Fall setzt cURL automatisch den Content-Type-Header auf application/x-www-form-urlencoded.
JSON-Daten per POST senden
Moderne REST-APIs erwarten häufig JSON im Request-Body. Dafür werden die Daten zunächst mit json_encode() in einen JSON-String umgewandelt und anschließend zusammen mit dem passenden Content-Type-Header an cURL übergeben.
<?php
$daten = [
'benutzername' => 'maxm',
'rolle' => 'administrator',
'aktiv' => true
];
$jsonString = json_encode($daten);
$ch = curl_init('https://api.example.com/benutzer');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonString);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json',
'Content-Length: ' . strlen($jsonString)
]);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$antwort = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($antwort === false) {
echo 'cURL-Fehler: ' . curl_error($ch);
} elseif ($statusCode >= 400) {
echo 'HTTP-Fehler: ' . $statusCode;
} else {
$ergebnis = json_decode($antwort, true);
print_r($ergebnis);
}
curl_close($ch);
Der entscheidende Unterschied zum vorherigen Beispiel liegt in CURLOPT_HTTPHEADER. Der Header Content-Type: application/json teilt dem Server mit, dass der Request-Body JSON-Daten enthält. Der Header Accept: application/json signalisiert, dass auch die Antwort im JSON-Format erwartet wird.
Den Fehler "Call to undefined function curl_init()" beheben
Dieser Fehler tritt auf, wenn die cURL-Extension nicht geladen ist. Die Extension ist nicht in jeder PHP-Installation aktiv und muss in der php.ini explizit aktiviert werden.
Unter Linux lässt sich die Extension über den Paketmanager installieren. Für Debian und Ubuntu wird das Paket php-curl verwendet. Nach der Installation muss der Webserver oder PHP-FPM neu gestartet werden, damit die Änderung wirksam wird.
Unter Windows muss die Zeile extension=curl in der php.ini einkommentiert werden, indem das Semikolon am Zeilenanfang entfernt wird. Der Pfad zur php.ini lässt sich mit php --ini auf der Kommandozeile oder mit phpinfo() im Browser ermitteln.
Bei XAMPP und MAMP ist die cURL-Extension in der Regel bereits vorinstalliert. Sollte sie dennoch fehlen, genügt es, die entsprechende Zeile in der php.ini zu aktivieren und den Apache-Server neu zu starten.
Ist cURL in meiner PHP-Installation verfügbar?
Bevor du cURL in einem Projekt einsetzt, solltest du prüfen, ob die Extension verfügbar ist. PHP bietet dafür mehrere Möglichkeiten, die sich sowohl im Code als auch auf der Kommandozeile nutzen lassen.
<?php
/* Pruefen ob die cURL-Extension geladen ist */
if (function_exists('curl_init')) {
echo 'cURL ist verfuegbar.' . "\n";
/* Installierte cURL-Version ausgeben */
$version = curl_version();
echo 'cURL-Version: ' . $version['version'] . "\n";
echo 'SSL-Version: ' . $version['ssl_version'] . "\n";
echo 'Unterstuetzte Protokolle: ' . implode(', ', $version['protocols']);
} else {
echo 'cURL ist NICHT verfuegbar. Bitte die Extension aktivieren.';
}
Die Funktion function_exists() prüft, ob curl_init als Funktion registriert ist. Die Funktion curl_version() gibt ein assoziatives Array mit Versionsinformationen zurück, darunter die cURL-Version, die SSL-Version und die unterstützten Protokolle. Auf der Kommandozeile kannst du alternativ php -m ausführen, um alle geladenen Extensions aufzulisten.
Fazit
Die Funktion curl_init() ist der Startpunkt für jede HTTP-Anfrage mit der PHP-cURL-Extension. Der Workflow aus curl_init(), curl_setopt(), curl_exec() und curl_close() bietet maximale Kontrolle über alle Aspekte einer HTTP-Anfrage. Mit CURLOPT_RETURNTRANSFER fängst du die Serverantwort als String ab, mit CURLOPT_POST und CURLOPT_POSTFIELDS sendest du Formulardaten oder JSON, und mit CURLOPT_TIMEOUT schützt du deine Anwendung vor langen Wartezeiten. Ab PHP 8.0 gibt curl_init() ein typsicheres CurlHandle-Objekt zurück. Stelle sicher, dass die cURL-Extension in deiner php.ini aktiviert ist, um den Fehler "Call to undefined function curl_init()" zu vermeiden. Für einfache GET-Anfragen bleibt file_get_contents() eine leichtgewichtige Alternative, doch sobald du Header, Timeouts oder POST-Daten benötigst, ist cURL die richtige Wahl.