Wer mit PHP Formulardaten an einen anderen Server senden will, hat heute mehrere zuverlässige Möglichkeiten. Dieses Tutorial zeigt Schritt für Schritt, wie HTTP POST-Requests mit cURL, file_get_contents() und JSON funktionieren. Außerdem gibt es eine Vergleichstabelle, die bei der Wahl der richtigen Methode hilft.
Wann brauche ich das?
Formulardaten per HTTP POST an einen anderen Server zu senden, gehört zu den häufigsten Aufgaben in der PHP-Entwicklung. Typische Anwendungsfälle:
- Payment-APIs aufrufen: Zahlungsdaten an Stripe, PayPal oder andere Anbieter übermitteln
- Webhooks senden: Benachrichtigungen an Slack, Discord oder eigene Systeme auslösen
- Kontaktformulare weiterleiten: Eingaben an ein CRM oder einen E-Mail-Dienst wie Mailchimp übergeben
- REST-APIs ansprechen: Daten an externe Dienste senden, zum Beispiel für Übersetzungen, Chatbots oder KI-Services
In all diesen Fällen baut PHP im Hintergrund einen HTTP-Request zusammen und schickt ihn an die Gegenstelle. Die folgenden Abschnitte zeigen, wie das in der Praxis funktioniert.
Moderne Lösung: HTTP POST mit cURL
So sendest du Formulardaten mit cURL. Diese Methode ist zuverlässiger, unterstützt HTTPS automatisch und wird in der Praxis am häufigsten eingesetzt:
<?php
function postFormular(string $url, array $daten): string
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($daten),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30,
]);
$antwort = curl_exec($ch);
if ($antwort === false) {
$fehler = curl_error($ch);
curl_close($ch);
throw new RuntimeException('cURL-Fehler: ' . $fehler);
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
throw new RuntimeException('HTTP-Fehler ' . $httpCode);
}
return $antwort;
}
$daten = ['variable_name' => 'Inhalt'];
$ergebnis = postFormular('https://example.com/formular.php', $daten);
echo $ergebnis;
?>
Wichtig: SSL-Zertifikate nicht deaktivieren! Ein häufiger Fehler ist, CURLOPT_SSL_VERIFYPEER auf false zu setzen, um SSL-Probleme zu umgehen. Das deaktiviert die Zertifikatsprüfung und macht die Verbindung anfällig für Man-in-the-Middle-Angriffe. Stattdessen sollte das CA-Bundle auf dem Server aktuell gehalten werden. Unter Linux wird es meist über das Paket ca-certificates bereitgestellt. Auf Windows-Systemen kann das Bundle manuell von curl.se heruntergeladen und in der php.ini per curl.cainfo eingetragen werden.
Alternative: file_get_contents() mit Stream-Context
Ohne cURL-Erweiterung kannst du file_get_contents() mit einem Stream-Context verwenden:
<?php
$daten = http_build_query(['variable_name' => 'Inhalt']);
$optionen = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $daten,
'timeout' => 30,
],
];
$context = stream_context_create($optionen);
$ergebnis = file_get_contents('https://example.com/formular.php', false, $context);
if ($ergebnis === false) {
echo 'Fehler beim Senden.';
} else {
echo $ergebnis;
}
?>
JSON-POST mit cURL
Moderne REST-APIs erwarten meistens JSON statt klassischer Formulardaten. Mit cURL lässt sich das einfach umsetzen:
<?php
$daten = [
'name' => 'Max Mustermann',
'email' => 'max@example.com',
];
$json = json_encode($daten);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.example.com/users',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($json),
],
]);
$antwort = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
echo 'Fehler: HTTP ' . $httpCode;
} else {
$ergebnis = json_decode($antwort, true);
print_r($ergebnis);
}
?>
Der entscheidende Unterschied: Statt http_build_query() wird json_encode() verwendet und der Header Content-Type: application/json gesetzt. Die Antwort kann mit json_decode() wieder in ein PHP-Array umgewandelt werden.
Welche Methode passt?
PHP bietet mehrere Wege, um HTTP-Requests zu senden. Die folgende Tabelle hilft bei der Entscheidung:
| cURL | file_get_contents() | Guzzle |
| Vorteile | Volle Kontrolle über Headers, Timeouts und SSL. Auf fast jedem Server verfügbar. | Kein Extension-Abhängigkeit. Kompakter Code für einfache Requests. | Komfortables Interface, automatisches Retry, Middleware-System, PSR-7-kompatibel. |
| Nachteile | Etwas mehr Boilerplate-Code nötig. | Eingeschränkte Fehlerbehandlung. Kein natives Redirect-Handling bei POST. | Externe Abhängigkeit (Composer). Für einfache Requests überdimensioniert. |
| Empfehlung | Standard-Wahl für die meisten Projekte. | Gut für schnelle Skripte ohne cURL-Extension. | Ideal für größere Projekte mit vielen API-Aufrufen. |
Historischer Ansatz: fsockopen() (veraltet)
Die ursprüngliche Version dieses Tutorials verwendete fsockopen(), um eine rohe TCP-Verbindung zum Server zu öffnen und den HTTP-Request manuell zusammenzubauen. Dabei mussten Header, Content-Length und der POST-Body Zeile für Zeile per fputs() gesendet werden.
Dieser Ansatz hat mehrere Nachteile:
- Kein natives HTTPS. Für SSL müsste
ssl:// als Präfix verwendet werden. - Keine automatische Redirect-Behandlung.
- Fehleranfällig durch manuelles Zusammenbauen der HTTP-Header.
- Keine eingebaute Timeout- oder Retry-Logik.
Mit cURL oder file_get_contents() lassen sich alle diese Probleme vermeiden. Beide Methoden übernehmen das HTTP-Protokoll vollständig und sind in modernem PHP die empfohlene Wahl.
Verwandte PHP-Funktionen
Die folgenden Funktionen werden in den obigen Beispielen verwendet:
curl_init(), curl_setopt_array(), curl_exec(), curl_close() – cURL-Funktionen curl_getinfo() – HTTP-Statuscode und weitere Request-Infos abfragen http_build_query() – Array in URL-kodierten Query-String umwandeln json_encode() / json_decode() – PHP-Arrays in JSON umwandeln und zurück stream_context_create() – Stream-Context für file_get_contents() erstellen