Zurück zum Blog

Proxy-Einrichtung in PHP mit cURL und Guzzle HTTP Client: Vollständiger Leitfaden mit Codebeispielen

Vollständige Anleitung zur Konfiguration von Proxys in PHP über cURL und Guzzle HTTP Client - mit Codebeispielen, IP-Rotation und Tipps zur Auswahl des Proxytyps für das Scraping und die Automatisierung.

📅12. August 2026
```html

Wenn Sie einen Parser schreiben, Datenautomatisierung durchführen oder IP-Beschränkungen umgehen — kommen Sie nicht ohne Proxy in PHP aus. In diesem Leitfaden werden wir die beiden wichtigsten Werkzeuge untersuchen: die integrierte cURL und die beliebte Bibliothek Guzzle HTTP Client — mit fertigen Codebeispielen, die Sie sofort in Ihrem Projekt verwenden können.

Warum Proxy in PHP-Projekten

PHP bleibt eine der am weitesten verbreiteten Sprachen für serverseitige Automatisierung, und Aufgaben, die Proxy erfordern, treten ständig auf. Hier sind die Hauptszenarien, in denen Sie ohne Proxy nicht auskommen:

  • Scraping von Websites und Marktplätzen — Wildberries, Ozon, Avito, AliExpress blockieren IPs nach mehreren Dutzend Anfragen. Proxys ermöglichen es, die Last auf verschiedene Adressen zu verteilen und keine 403/429 zu erhalten.
  • Daten von geoabhängigen Ressourcen sammeln — Preise, Suchergebnisse, Inhalte können je nach Land unterschiedlich sein. Proxys mit der benötigten Geolokalisierung lösen dieses Problem.
  • Umgehung von Rate Limiting — viele APIs begrenzen die Anzahl der Anfragen von einer IP. Die Rotation von Proxys ermöglicht es, diese Limits zu umgehen.
  • Testen von geoabhängigen Inhalten — Überprüfen, wie die Website für Benutzer aus verschiedenen Ländern aussieht, ohne das Büro zu verlassen.
  • Anonymität bei der Automatisierung — Verbergen der echten IP des Servers bei massenhaften Anfragen an externe Ressourcen.
  • Überwachung von Wettbewerbern — Regelmäßiges Sammeln von Preisen, Sortimenten, Aktionen von Wettbewerber-Websites ohne Risiko, gesperrt zu werden.

In PHP werden für HTTP-Anfragen am häufigsten zwei Werkzeuge verwendet: die integrierte Erweiterung cURL und die Bibliothek Guzzle HTTP Client. Beide unterstützen HTTP, HTTPS, SOCKS4 und SOCKS5 Proxys — wir werden jeden im Detail untersuchen.

Welchen Proxytyp für PHP wählen

Bevor Sie mit dem Schreiben von Code beginnen, ist es wichtig zu verstehen, welcher Proxytyp für Ihre Aufgabe geeignet ist. Verschiedene Typen haben unterschiedliche Eigenschaften in Bezug auf Geschwindigkeit, Zuverlässigkeit und Anonymität.

Proxytyp Geschwindigkeit Anonymität Am besten geeignet für
Rechenzentrumsproxies Sehr hoch Mittel Scraping ohne strenge Anti-Bot-Systeme, API-Anfragen
Residential Proxies Mittel Hoch Scraping von geschützten Websites, Marktplätzen, Geodaten
Mobile Proxies Mittel Maximal Websites mit strenger Anti-Bot-Schutz, soziale Netzwerke

Für die meisten Scraping-Aufgaben von Marktplätzen wie Wildberries oder Ozon sind Residential Proxies die optimale Wahl — ihre IPs gehören echten Heimnutzern, was die Anfragen praktisch von normalem Browser-Traffic nicht unterscheidbar macht. Rechenzentrumsproxies eignen sich dort, wo Geschwindigkeit wichtiger ist als Unauffälligkeit und der Schutz schwach ist.

Alle drei Proxytypen unterstützen die Protokolle HTTP/HTTPS und SOCKS5, daher ist die Konfiguration aus Sicht des Codes identisch. Der Unterschied liegt nur in der Verbindungszeichenfolge.

Proxy in cURL: Grundkonfiguration

Die cURL-Erweiterung ist in PHP standardmäßig verfügbar und ist die gängige Methode zur Ausführung von HTTP-Anfragen auf dem Server. Für die Verbindung zu Proxys werden zwei Hauptoptionen verwendet: CURLOPT_PROXY und CURLOPT_PROXYTYPE.

HTTP-Proxy ohne Authentifizierung

<?php

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://httpbin.org/ip',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT        => 30,

    // Proxy-Adresse angeben
    CURLOPT_PROXY          => '185.199.100.1:8080',

    // Proxy-Typ: HTTP (Standard)
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP Code: $httpCode\n";
echo $response;

Hier akzeptiert CURLOPT_PROXY eine Zeichenfolge im Format host:port. Für HTTPS-Traffic verwendet cURL automatisch die CONNECT-Methode — Tunneling, sodass der Inhalt der Anfrage verschlüsselt bleibt.

Nützliche cURL-Optionen für die Arbeit mit Proxys

Option Beschreibung
CURLOPT_PROXY Adresse des Proxy-Servers (host:port)
CURLOPT_PROXYTYPE Typ: CURLPROXY_HTTP, CURLPROXY_SOCKS4, CURLPROXY_SOCKS5
CURLOPT_PROXYUSERPWD Benutzername und Passwort im Format user:password
CURLOPT_HTTPPROXYTUNNEL Tunneling über HTTP CONNECT aktivieren
CURLOPT_SSL_VERIFYPEER Überprüfung des SSL-Zertifikats (false — deaktivieren)
CURLOPT_TIMEOUT Timeout der Anfrage in Sekunden
CURLOPT_CONNECTTIMEOUT Timeout für die Verbindung zum Proxy

Authentifizierung und SOCKS5 in cURL

Die meisten kommerziellen Proxys erfordern eine Authentifizierung mit Benutzername und Passwort. SOCKS5 ist auch das bevorzugte Protokoll, wenn vollständige Anonymität erforderlich ist, da es keine Header wie X-Forwarded-For hinzufügt, die die Verwendung eines Proxys verraten könnten.

HTTP-Proxy mit Benutzername und Passwort

<?php

$proxyHost = '185.199.100.1';
$proxyPort = '8080';
$proxyUser = 'your_login';
$proxyPass = 'your_password';

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://httpbin.org/ip',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_CONNECTTIMEOUT => 10,

    // Proxy mit Authentifizierung
    CURLOPT_PROXY          => "$proxyHost:$proxyPort",
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
    CURLOPT_PROXYUSERPWD   => "$proxyUser:$proxyPass",

    // Tunneling für HTTPS
    CURLOPT_HTTPPROXYTUNNEL => true,

    // Browser-Header zur Maskierung
    CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    CURLOPT_HTTPHEADER     => [
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language: ru-RU,ru;q=0.9,en;q=0.8',
    ],
]);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'cURL-Fehler: ' . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

SOCKS5-Proxy in cURL

<?php

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://httpbin.org/ip',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 30,

    CURLOPT_PROXY          => '185.199.100.1:1080',

    // SOCKS5 mit DNS-Resolution über den Proxy (empfohlen!)
    CURLOPT_PROXYTYPE      => CURLPROXY_SOCKS5_HOSTNAME,

    // Authentifizierung (falls erforderlich)
    CURLOPT_PROXYUSERPWD   => 'login:password',
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

💡 Wichtig: SOCKS5 vs SOCKS5_HOSTNAME

Verwenden Sie CURLPROXY_SOCKS5_HOSTNAME anstelle von CURLPROXY_SOCKS5. Der Unterschied besteht darin, dass bei SOCKS5_HOSTNAME auch DNS-Anfragen über den Proxy laufen, was DNS-Lecks verhindert und die Anonymität erhöht. Bei normalem SOCKS5 wird DNS lokal aufgelöst — das kann Ihre echte IP offenbaren.

Proxy-Rotation in cURL

Ein Proxy wird schnell blockiert, wenn viele Anfragen gestellt werden. Die richtige Strategie besteht darin, einen Pool von Proxys zu haben und diese abwechselnd zu verwenden. Hier ist eine einfache, aber funktionale Implementierung:

<?php

class ProxyRotator
{
    private array $proxies;
    private int $currentIndex = 0;

    public function __construct(array $proxies)
    {
        $this->proxies = $proxies;
        shuffle($this->proxies); // Mischen für zufällige Reihenfolge
    }

    /**
     * Nächsten Proxy aus dem Pool erhalten
     */
    public function getNext(): string
    {
        $proxy = $this->proxies[$this->currentIndex];
        $this->currentIndex = ($this->currentIndex + 1) % count($this->proxies);
        return $proxy;
    }

    /**
     * Zufälligen Proxy erhalten
     */
    public function getRandom(): string
    {
        return $this->proxies[array_rand($this->proxies)];
    }
}

// Liste der Proxys im Format login:password@host:port
$proxyList = [
    'user1:[email protected]:8080',
    'user2:[email protected]:8080',
    'user3:[email protected]:8080',
    'user4:[email protected]:8080',
];

$rotator = new ProxyRotator($proxyList);

/**
 * Funktion für die Anfrage mit automatischer Auswahl des Proxys
 */
function fetchWithProxy(string $url, ProxyRotator $rotator): ?string
{
    $proxyStr = $rotator->getNext();

    // Proxy-Zeichenfolge parsen
    preg_match('/^(.+):(.+)@(.+):(\d+)$/', $proxyStr, $m);
    [, $user, $pass, $host, $port] = $m;

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_PROXY          => "$host:$port",
        CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
        CURLOPT_PROXYUSERPWD   => "$user:$pass",
        CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        CURLOPT_SSL_VERIFYPEER => false,
    ]);

    $response = curl_exec($ch);
    $error    = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Proxy $host:$port nicht erreichbar: $error");
        return null;
    }

    return $response;
}

// Beispiel: Scraping von 10 Seiten mit Proxy-Rotation
$urls = [
    'https://example.com/page/1',
    'https://example.com/page/2',
    'https://example.com/page/3',
    // ...
];

foreach ($urls as $url) {
    $html = fetchWithProxy($url, $rotator);
    if ($html) {
        echo "Erhalten: " . strlen($html) . " Bytes\n";
    }
    usleep(500000); // Pause von 0.5 Sekunden zwischen Anfragen
}

Beachten Sie usleep(500000) — die Pause zwischen Anfragen ist entscheidend. Selbst mit Proxy-Rotation können zu häufige Anfragen zu einer Blockierung aufgrund von Verhaltensmustern führen. Der empfohlene Intervall liegt zwischen 500 ms und 2 Sekunden, abhängig von der Website.

Proxy im Guzzle HTTP Client: Grundkonfiguration

Guzzle ist eine leistungsstarke PHP-Bibliothek für HTTP-Anfragen, die in den meisten modernen PHP-Frameworks (Laravel, Symfony) verwendet wird. Sie bietet eine benutzerfreundlichere und lesbarere API im Vergleich zu reinem cURL, unterstützt asynchrone Anfragen, Middleware und eine bequeme Fehlerbehandlung.

Installation über Composer

composer require guzzlehttp/guzzle

HTTP-Proxy ohne Authentifizierung

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client([
    // Basis-URL (optional)
    'base_uri' => 'https://httpbin.org',

    // Standardkonfiguration für alle Anfragen
    'timeout'  => 30,
    'connect_timeout' => 10,

    // Proxy für alle Anfragen des Clients
    'proxy' => 'http://185.199.100.1:8080',
]);

$response = $client->get('/ip');

echo $response->getStatusCode() . "\n";  // 200
echo $response->getBody() . "\n";        // {"origin": "185.199.100.1"}

In Guzzle wird der Proxy über die Option proxy im URL-Format angegeben. Dies ist intuitiver als in cURL. Proxys können sowohl auf Client-Ebene (für alle Anfragen) als auch für jede Anfrage einzeln festgelegt werden.

HTTP-Proxy mit Authentifizierung

<?php

use GuzzleHttp\Client;

$login    = 'your_login';
$password = 'your_password';
$host     = '185.199.100.1';
$port     = '8080';

$client = new Client([
    'timeout' => 30,
]);

// Proxy mit Authentifizierung wird im URL-Format übergeben
$response = $client->get('https://httpbin.org/ip', [
    'proxy' => "http://$login:$password@$host:$port",
    'headers' => [
        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept'     => 'text/html,application/xhtml+xml,application/xml;q=0.9',
    ],
]);

echo $response->getBody();

Das Format des Proxy-URLs in Guzzle lautet: scheme://user:password@host:port. Für HTTP-Proxys verwenden wir http://, für SOCKS5 — socks5://.

Fortgeschrittene Arbeit mit Guzzle: Timeouts, Header, SOCKS5

Lassen Sie uns komplexere Szenarien betrachten: verschiedene Proxys für HTTP und HTTPS, SOCKS5, Deaktivierung der SSL-Überprüfung und Header-Anpassungen zur Browser-Imitation.

Verschiedene Proxys für HTTP und HTTPS

<?php

use GuzzleHttp\Client;

$client = new Client([
    'timeout' => 30,
    'proxy'   => [
        // Proxy für HTTP-Anfragen
        'http'  => 'http://login:[email protected]:8080',
        // Proxy für HTTPS-Anfragen
        'https' => 'http://login:[email protected]:8080',
        // Ausnahmen — diese Hosts gehen ohne Proxy
        'no'    => ['localhost', '127.0.0.1', '.internal.corp'],
    ],
]);

SOCKS5 in Guzzle

<?php

use GuzzleHttp\Client;

// Für SOCKS5 in Guzzle ist ein zusätzliches Paket erforderlich
// composer require clue/socks-react (oder verwenden Sie den cURL-Handler)

$client = new Client([
    'timeout' => 30,
    'proxy'   => 'socks5://login:[email protected]:1080',
    'curl'    => [
        CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5_HOSTNAME,
    ],
]);

$response = $client->get('https://httpbin.org/ip');
echo $response->getBody();

Vollständige Konfiguration mit Browser-Headern

<?php

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;

$client = new Client([
    'timeout'         => 30,
    'connect_timeout' => 10,
    'verify'          => false, // SSL-Überprüfung deaktivieren (für Debugging)
    'allow_redirects' => [
        'max'       => 5,
        'strict'    => false,
        'referer'   => true,
        'protocols' => ['http', 'https'],
    ],
    'headers' => [
        'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language' => 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
        'Accept-Encoding' => 'gzip, deflate, br',
        'Cache-Control'   => 'no-cache',
        'Connection'      => 'keep-alive',
    ],
]);

$response = $client->get('https://example.com/catalog', [
    'proxy' => 'http://login:[email protected]:8080',
]);

$statusCode = $response->getStatusCode();
$body       = (string) $response->getBody();

echo "Status: $statusCode, Größe: " . strlen($body) . " Bytes\n";

⚠️ Zu verify => false

Die Deaktivierung der SSL-Überprüfung ('verify' => false) ist nur während des Debuggings oder bei der Arbeit mit internen Diensten zulässig. Im Produktionscode sollten Sie die SSL-Überprüfung immer aktiviert lassen, da Sie sonst anfällig für Man-in-the-Middle-Angriffe sind.

Proxy-Rotation in Guzzle

In Guzzle lässt sich die Rotation bequem über Middleware implementieren — eine Zwischenschicht, die jede Anfrage abfängt und ihr einen Proxy hinzufügt. Dies ist eleganter, als den Proxy manuell in jeden Aufruf zu übergeben.

<?php

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;

/**
 * Middleware zur automatischen Rotation von Proxys
 */
function proxyRotationMiddleware(array $proxies): callable
{
    $index = 0;
    $total = count($proxies);

    return Middleware::mapRequest(
        function (RequestInterface $request) use ($proxies, &$index, $total) {
            $proxy = $proxies[$index % $total];
            $index++;

            // Fügen Sie den Proxy zu den Anforderungsattributen hinzu
            // (über Optionen im Handler übergeben)
            return $request->withHeader('X-Selected-Proxy', $proxy);
        }
    );
}

// Liste der Proxys
$proxies = [
    'http://user1:[email protected]:8080',
    'http://user2:[email protected]:8080',
    'http://user3:[email protected]:8080',
];

// Einfache Variante: Wrapper-Klasse um Guzzle mit Rotation
class GuzzleWithRotation
{
    private Client $client;
    private array $proxies;
    private int $index = 0;

    public function __construct(array $proxies, array $clientConfig = [])
    {
        $this->proxies = $proxies;
        $this->client  = new Client($clientConfig);
    }

    public function get(string $url, array $options = []): \GuzzleHttp\Psr7\Response
    {
        $options['proxy'] = $this->proxies[$this->index % count($this->proxies)];
        $this->index++;

        return $this->client->get($url, $options);
    }

    public function post(string $url, array $options = []): \GuzzleHttp\Psr7\Response
    {
        $options['proxy'] = $this->proxies[$this->index % count($this->proxies)];
        $this->index++;

        return $this->client->post($url, $options);
    }
}

// Verwendung
$guzzle = new GuzzleWithRotation($proxies, [
    'timeout' => 30,
    'headers' => [
        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
    ],
]);

$urls = [
    'https://example.com/product/1',
    'https://example.com/product/2',
    'https://example.com/product/3',
];

foreach ($urls as $url) {
    try {
        $response = $guzzle->get($url);
        echo "OK [{$response->getStatusCode()}]: $url\n";
        sleep(1);
    } catch (\Exception $e) {
        echo "Fehler: " . $e->getMessage() . "\n";
    }
}

Fehlerbehandlung und Debugging

Bei der Arbeit mit Proxys sind Fehler unvermeidlich: Ein Proxy kann nicht erreichbar sein, langsam antworten oder die Zielwebsite kann einen Fehler zurückgeben. Es ist wichtig, all diese Situationen angemessen zu behandeln.

Fehlerbehandlung in cURL

<?php

function fetchWithErrorHandling(string $url, string $proxy): array
{
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_PROXY          => $proxy,
        CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
    ]);

    $body     = curl_exec($ch);
    $errno    = curl_errno($ch);
    $error    = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $totalTime = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
    curl_close($ch);

    // cURL-Fehlercodes für Proxys
    $proxyErrors = [
        CURLE_COULDNT_CONNECT    => 'Verbindung zum Proxy fehlgeschlagen',
        CURLE_OPERATION_TIMEDOUT => 'Timeout bei der Verbindung zum Proxy',
        CURLE_RECV_ERROR         => 'Fehler beim Empfang von Daten',
        CURLE_SSL_CONNECT_ERROR  => 'SSL-Fehler über den Proxy',
    ];

    if ($errno) {
        $message = $proxyErrors[$errno] ?? "cURL-Fehler #$errno: $error";
        return ['success' => false, 'error' => $message, 'code' => $errno];
    }

    if ($httpCode >= 400) {
        return ['success' => false, 'error' => "HTTP $httpCode", 'code' => $httpCode];
    }

    return [
        'success' => true,
        'body'    => $body,
        'code'    => $httpCode,
        'time'    => round($totalTime, 3),
    ];
}

// Verwendung mit Wiederholungsversuchen
function fetchWithRetry(string $url, array $proxies, int $maxRetries = 3): ?string
{
    foreach ($proxies as $proxy) {
        for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
            $result = fetchWithErrorHandling($url, $proxy);

            if ($result['success']) {
                echo "Erfolg über $proxy (Versuch $attempt, {$result['time']}s)\n";
                return $result['body'];
            }

            echo "Fehler über $proxy: {$result['error']}\n";

            if ($attempt < $maxRetries) {
                sleep(2); // Pause vor dem Wiederholen
            }
        }
    }

    return null; // Alle Proxys haben nicht funktioniert
}

Fehlerbehandlung in Guzzle

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\ClientException;

$client = new Client(['timeout' => 30]);

$proxies = [
    'http://user1:[email protected]:8080',
    'http://user2:[email protected]:8080',
];

function fetchGuzzleWithFallback(Client $client, string $url, array $proxies): ?string
{
    foreach ($proxies as $proxy) {
        try {
            $response = $client->get($url, [
                'proxy'   => $proxy,
                'timeout' => 20,
            ]);

            return (string) $response->getBody();

        } catch (ConnectException $e) {
            // Proxy nicht erreichbar oder Timeout bei der Verbindung
            echo "Proxy nicht erreichbar ($proxy): " . $e->getMessage() . "\n";

        } catch (ClientException $e) {
            // HTTP 4xx — Clientfehler (403, 404, 429)
            $code = $e->getResponse()->getStatusCode();
            echo "HTTP $code für $url über $proxy\n";

            if ($code === 429) {
                echo "Rate limit — Pause von 5 Sekunden\n";
                sleep(5);
            }

        } catch (ServerException $e) {
            // HTTP 5xx — Serverfehler
            echo "Serverfehler: " . $e->getResponse()->getStatusCode() . "\n";

        } catch (RequestException $e) {
            // Andere Anfragefehler
            echo "Anfragefehler: " . $e->getMessage() . "\n";
        }
    }

    return null;
}

cURL vs Guzzle: Was wählen

Beide Werkzeuge funktionieren hervorragend mit Proxys, haben jedoch unterschiedliche Stärken. Hier ist ein Vergleich nach wichtigen Kriterien:

Kriterium cURL Guzzle
Installation ✅ In PHP integriert ⚠️ Composer erforderlich
Code-Lesbarkeit ⚠️ Viele Optionen, umständlich ✅ Saubere, benutzerfreundliche API
Leistung ✅ Etwas schneller (keine Wrapper) ✅ Vergleichbar, bietet async
Asynchrone Anfragen ⚠️ curl_multi (schwierig) ✅ Eingebaute Unterstützung
Middleware / Hooks ❌ Nicht vorhanden ✅ HandlerStack, Middleware
SOCKS5-Unterstützung ✅ Nativ ✅ Über cURL-Handler
Fehlerbehandlung ⚠️ Fehlercodes manuell ✅ Ausnahmen mit Typen
Integration in Laravel/Symfony ⚠️ Manuell ✅ Native Unterstützung
Geeignet für Einfache Skripte, ohne Abhängigkeiten Projekte in Frameworks, komplexe Logik

Empfehlung: Wenn Sie ein einfaches Skript schreiben oder auf einem Hosting ohne Composer arbeiten — verwenden Sie cURL. Für Projekte in Laravel, Symfony oder anderen modernen PHP-Anwendungen wird Guzzle deutlich bequemer sein und mehr Möglichkeiten für die Skalierung bieten.

🚀 Schnelle Checkliste vor dem Start

  • ✅ Überprüfen Sie, ob der Proxy funktioniert: curl -x http://login:pass@host:port https://httpbin.org/ip
  • ✅ Setzen Sie Timeouts: timeout und connect_timeout
  • ✅ Fügen Sie einen realistischen User-Agent hinzu
  • ✅ Implementieren Sie Pausen zwischen Anfragen (mindestens 500 ms)
  • ✅ Berücksichtigen Sie die Fehlerbehandlung und Fallback auf einen anderen Proxy
  • ✅ Verwenden Sie für SOCKS5 CURLPROXY_SOCKS5_HOSTNAME (nicht SOCKS5)
  • ✅ Deaktivieren Sie die SSL-Überprüfung nicht in der Produktion

Fazit

Die Konfiguration von Proxys in PHP ist nicht schwierig, wenn man die richtigen Optionen und Formate kennt. Für grundlegende Aufgaben reicht cURL mit CURLOPT_PROXY und CURLOPT_PROXYUSERPWD. Für Projekte in Frameworks bietet Guzzle eine benutzerfreundlichere API, typisierte Ausnahmen und Unterstützung für Middleware zur Proxy-Rotation.

Die wichtigsten Prinzipien für eine zuverlässige Arbeit: Verwenden Sie SOCKS5 mit DNS-Resolution über den Proxy (CURLPROXY_SOCKS5_HOSTNAME), setzen Sie immer Timeouts, fügen Sie Pausen zwischen Anfragen hinzu und implementieren Sie die Proxy-Rotation für großangelegte Aufgaben. Die Fehlerbehandlung mit Fallback auf einen anderen Proxy ist ein unverzichtbarer Bestandteil jedes Produktionscodes.

```