Bloga geri dön

PHP'de cURL ve Guzzle HTTP Client ile Proxy Ayarlama: Kod Örnekleriyle Tam Kılavuz

PHP'de cURL ve Guzzle HTTP Client ile proxy ayarlama için kapsamlı rehber - kod örnekleri, IP döngüsü ve tarama ile otomasyon için proxy türü seçimi hakkında ipuçları ile.

📅12 Ağustos 2026
```html

Eğer bir parser yazıyorsanız, veri toplama işlemini otomatikleştiriyorsanız veya IP kısıtlamalarını aşmaya çalışıyorsanız — PHP'de proxy kullanmadan olmaz. Bu kılavuzda iki ana aracı inceleyeceğiz: yerleşik cURL ve popüler kütüphane Guzzle HTTP Client — hemen projede kullanabileceğiniz hazır kod örnekleri ile.

PHP projelerinde proxy neden gerekli

PHP, sunucu otomasyonu için en yaygın dillerden biri olmaya devam ediyor ve proxy gerektiren görevler sürekli olarak ortaya çıkıyor. İşte proxy olmadan yapamayacağınız temel senaryolar:

  • Web siteleri ve pazar yerlerinden veri çekme — Wildberries, Ozon, Avito, AliExpress birkaç on istekten sonra IP'yi engelliyor. Proxy'ler, yükü farklı adresler arasında dağıtarak 403/429 hatası almamanızı sağlar.
  • Coğrafi olarak bağımlı kaynaklardan veri toplama — fiyatlar, arama motoru sonuçları, içerik ülkeye göre değişebilir. İhtiyaç duyulan coğrafi konumda proxy'ler bu sorunu çözer.
  • Rate limiting aşma — birçok API, bir IP'den gelen istek sayısını sınırlar. Proxy rotasyonu, bu sınırlamaları aşmanıza olanak tanır.
  • Coğrafi olarak bağımlı içeriği test etme — ofisten çıkmadan farklı ülkelerden kullanıcılar için sitenin nasıl göründüğünü kontrol edin.
  • Otomasyonda anonimlik — dış kaynaklara toplu isteklerde sunucunun gerçek IP'sini gizleyin.
  • Rakipleri izleme — rakip sitelerden fiyat, ürün yelpazesi, kampanya verilerini toplamak için risk almadan düzenli olarak veri toplayın.

PHP'de HTTP istekleri için genellikle iki araç kullanılır: yerleşik cURL ve Guzzle HTTP Client kütüphanesi. Her ikisi de HTTP, HTTPS, SOCKS4 ve SOCKS5 proxy'lerini destekler — her birini detaylı olarak inceleyeceğiz.

PHP için hangi proxy türünü seçmelisiniz

Kod yazmadan önce, hangi proxy türünün görevlerinize uygun olduğunu anlamak önemlidir. Farklı türlerin hız, güvenilirlik ve anonimlik açısından farklı özellikleri vardır.

Proxy Türü Hız Anonimlik En iyi kullanım alanı
Veri merkezi proxy'leri Çok yüksek Orta Sıkı anti-bot sistemleri olmayan veri çekme, API istekleri
Konut proxy'leri Orta Yüksek Korunan sitelerden veri çekme, pazar yerleri, coğrafi veriler
Mobil proxy'ler Orta Maksimum Sert anti-bot koruması olan siteler, sosyal medya

Çoğu veri çekme görevi için Wildberries veya Ozon gibi pazar yerlerinden en iyi seçim konut proxy'leri olacaktır — bunların IP'leri gerçek ev kullanıcılarına aittir, bu da isteklerin neredeyse normal tarayıcı trafiğinden ayırt edilemez olmasını sağlar. Veri merkezi proxy'leri, hızın gizlilikten daha önemli olduğu ve korumanın zayıf olduğu yerlerde uygundur.

Üç proxy türü de HTTP/HTTPS ve SOCKS5 protokollerini desteklediğinden, kod açısından ayar aynıdır. Tek fark bağlantı dizesindedir.

cURL'de proxy: temel ayar

cURL uzantısı PHP'de kutudan çıktığı gibi mevcuttur ve sunucuda HTTP istekleri gerçekleştirmek için standart bir yöntemdir. Proxy bağlamak için iki ana seçenek kullanılır: CURLOPT_PROXY ve CURLOPT_PROXYTYPE.

Kimlik doğrulama olmadan HTTP proxy

<?php

$ch = curl_init();

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

    // Proxy adresini belirtiyoruz
    CURLOPT_PROXY          => '185.199.100.1:8080',

    // Proxy türü: HTTP (varsayılan)
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
]);

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

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

Burada CURLOPT_PROXY host:port formatında bir dize alır. HTTPS trafiği için HTTP proxy üzerinden cURL otomatik olarak CONNECT yöntemini kullanır — tünelleme, bu nedenle isteğin içeriği şifreli kalır.

Proxy ile çalışmak için yararlı cURL seçenekleri

Seçenek Açıklama
CURLOPT_PROXY Proxy sunucu adresi (host:port)
CURLOPT_PROXYTYPE Tür: CURLPROXY_HTTP, CURLPROXY_SOCKS4, CURLPROXY_SOCKS5
CURLOPT_PROXYUSERPWD Kullanıcı adı ve şifre formatında user:password
CURLOPT_HTTPPROXYTUNNEL HTTP CONNECT üzerinden tünelleme etkinleştir
CURLOPT_SSL_VERIFYPEER SSL sertifikası kontrolü (false — devre dışı bırak)
CURLOPT_TIMEOUT İsteğin zaman aşımı süresi (saniye cinsinden)
CURLOPT_CONNECTTIMEOUT Proxy'ye bağlantı zaman aşımı süresi

cURL'de kimlik doğrulama ve SOCKS5

Çoğu ticari proxy, kullanıcı adı ve şifre ile kimlik doğrulaması gerektirir. Ayrıca SOCKS5, tam anonimlik gerektiğinde tercih edilen protokoldür, çünkü X-Forwarded-For gibi proxy kullanımını açığa çıkarabilecek başlıklar eklemez.

Kullanıcı adı ve şifre ile HTTP proxy

<?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,

    // Kimlik doğrulamalı proxy
    CURLOPT_PROXY          => "$proxyHost:$proxyPort",
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
    CURLOPT_PROXYUSERPWD   => "$proxyUser:$proxyPass",

    // HTTPS için tünelleme
    CURLOPT_HTTPPROXYTUNNEL => true,

    // Maskeleme için tarayıcı başlıkları
    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 Hatası: ' . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

cURL'de SOCKS5 proxy

<?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',

    // DNS çözümlemesi ile SOCKS5 (önerilir!)
    CURLOPT_PROXYTYPE      => CURLPROXY_SOCKS5_HOSTNAME,

    // Kimlik doğrulama (gerekirse)
    CURLOPT_PROXYUSERPWD   => 'login:password',
]);

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

echo $response;

💡 Önemli: SOCKS5 vs SOCKS5_HOSTNAME

CURLPROXY_SOCKS5_HOSTNAME kullanın, CURLPROXY_SOCKS5 yerine. SOCKS5_HOSTNAME ile DNS istekleri de proxy üzerinden geçer, bu da DNS sızıntısını önler ve anonimliği artırır. Normal SOCKS5 ile DNS yerel olarak çözülür — bu, gerçek IP'nizi açığa çıkarabilir.

cURL'de proxy rotasyonu

Tek bir proxy, toplu isteklerde hızlı bir şekilde engellenebilir. Doğru strateji, bir proxy havuzuna sahip olmak ve bunları sırayla kullanmaktır. İşte basit ama etkili bir uygulama:

<?php

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

    public function __construct(array $proxies)
    {
        $this->proxies = $proxies;
        shuffle($this->proxies); // Rastgele sıraya koy
    }

    /**
     * Havuzdan bir sonraki proxy'yi al
     */
    public function getNext(): string
    {
        $proxy = $this->proxies[$this->currentIndex];
        $this->currentIndex = ($this->currentIndex + 1) % count($this->proxies);
        return $proxy;
    }

    /**
     * Rastgele bir proxy al
     */
    public function getRandom(): string
    {
        return $this->proxies[array_rand($this->proxies)];
    }
}

// login:password@host:port formatında proxy listesi
$proxyList = [
    'user1:[email protected]:8080',
    'user2:[email protected]:8080',
    'user3:[email protected]:8080',
    'user4:[email protected]:8080',
];

$rotator = new ProxyRotator($proxyList);

/**
 * Proxy ile otomatik seçim yapan istek fonksiyonu
 */
function fetchWithProxy(string $url, ProxyRotator $rotator): ?string
{
    $proxyStr = $rotator->getNext();

    // Proxy dizesini ayrıştır
    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 erişilemez: $error");
        return null;
    }

    return $response;
}

// Örnek: proxy rotasyonu ile 10 sayfa çekme
$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 "Alındı: " . strlen($html) . " bayt\n";
    }
    usleep(500000); // İstekler arasında 0.5 saniye bekleme
}

usleep(500000) ile dikkat edin — istekler arasındaki bekleme süresi kritik öneme sahiptir. Proxy rotasyonuna rağmen, çok sık istekler davranış kalıpları nedeniyle engellenebilir. Önerilen aralık — siteye bağlı olarak 500 ms ile 2 saniye arasında.

Guzzle HTTP Client'de proxy: temel ayar

Guzzle, HTTP istekleri için güçlü bir PHP kütüphanesidir ve çoğu modern PHP framework'ünde (Laravel, Symfony) kullanılır. Temel cURL'e göre daha kullanıcı dostu ve okunabilir bir API sunar, asenkron istekleri destekler, middleware ve hata işleme konusunda kolaylık sağlar.

Composer ile kurulum

composer require guzzlehttp/guzzle

Kimlik doğrulama olmadan HTTP proxy

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client([
    // Temel URL (isteğe bağlı)
    'base_uri' => 'https://httpbin.org',

    // Tüm istekler için varsayılan ayarlar
    'timeout'  => 30,
    'connect_timeout' => 10,

    // Tüm istemci istekleri için proxy
    '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"}

Guzzle'da proxy, URL formatında proxy seçeneği ile belirtilir. Bu, cURL'dan daha sezgisel bir yaklaşımdır. Proxy, hem istemci düzeyinde (tüm istekler için) hem de her bir isteğe ayrı ayrı belirtilebilir.

Kimlik doğrulama ile HTTP proxy

<?php

use GuzzleHttp\Client;

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

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

// Kimlik doğrulamalı proxy URL formatında belirtilir
$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();

Guzzle'da proxy URL formatı: scheme://user:password@host:port. HTTP proxy için http://, SOCKS5 için ise socks5:// kullanılır.

Guzzle ile ileri düzey çalışma: zaman aşımı, başlıklar, SOCKS5

Daha karmaşık senaryoları inceleyelim: HTTP ve HTTPS için farklı proxy'ler, SOCKS5, SSL kontrolünü devre dışı bırakma ve tarayıcı taklidi için başlıkları ayarlama.

HTTP ve HTTPS için farklı proxy'ler

<?php

use GuzzleHttp\Client;

$client = new Client([
    'timeout' => 30,
    'proxy'   => [
        // HTTP istekleri için proxy
        'http'  => 'http://login:[email protected]:8080',
        // HTTPS istekleri için proxy
        'https' => 'http://login:[email protected]:8080',
        // İstisnalar — bu hostlar proxy olmadan gider
        'no'    => ['localhost', '127.0.0.1', '.internal.corp'],
    ],
]);

Guzzle'da SOCKS5

<?php

use GuzzleHttp\Client;

// Guzzle'da SOCKS5 için ek bir paket gereklidir
// composer require clue/socks-react (veya curl handler kullanın)

$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();

Tarayıcı başlıkları ile tam yapılandırma

<?php

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;

$client = new Client([
    'timeout'         => 30,
    'connect_timeout' => 10,
    'verify'          => false, // SSL kontrolünü devre dışı bırak (hata ayıklama için)
    '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 "Durum: $statusCode, Boyut: " . strlen($body) . " bayt\n";

⚠️ verify => false hakkında

SSL kontrolünü devre dışı bırakmak ('verify' => false) yalnızca hata ayıklama veya iç hizmetlerle çalışırken kabul edilebilir. Üretim kodunda her zaman SSL kontrolünü açık bırakın, aksi takdirde man-in-the-middle saldırılarına karşı savunmasız olursunuz.

Guzzle'de proxy rotasyonu

Guzzle'da rotasyonu middleware ile kolayca gerçekleştirebilirsiniz — her isteği yakalayan ve ona proxy ekleyen ara katman. Bu, her çağrıda proxy'yi manuel olarak geçmekten daha şıktır.

<?php

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

/**
 * Proxy otomatik rotasyonu için middleware
 */
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++;

            // Proxy'yi isteğin başlıklarına ekle
            // (handler'da options ile geçir)
            return $request->withHeader('X-Selected-Proxy', $proxy);
        }
    );
}

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

// Guzzle üzerinde rotasyon ile basit bir sınıf
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);
    }
}

// Kullanım
$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 "Tamam [{$response->getStatusCode()}]: $url\n";
        sleep(1);
    } catch (\Exception $e) {
        echo "Hata: " . $e->getMessage() . "\n";
    }
}

Hata işleme ve hata ayıklama

Proxy ile çalışırken hatalar kaçınılmazdır: proxy erişilemez, yavaş yanıt verebilir veya hedef site hata dönebilir. Tüm bu durumları doğru bir şekilde işlemek önemlidir.

cURL'de hata işleme

<?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);

    // Proxy için cURL hata kodları
    $proxyErrors = [
        CURLE_COULDNT_CONNECT    => 'Proxy\'ye bağlanılamadı',
        CURLE_OPERATION_TIMEDOUT => 'Proxy bağlantısı zaman aşımına uğradı',
        CURLE_RECV_ERROR         => 'Veri alma hatası',
        CURLE_SSL_CONNECT_ERROR  => 'Proxy üzerinden SSL hatası',
    ];

    if ($errno) {
        $message = $proxyErrors[$errno] ?? "cURL hatası #$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),
    ];
}

// Yeniden deneme ile kullanım
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 "Başarı $proxy üzerinden (deneme $attempt, {$result['time']}s)\n";
                return $result['body'];
            }

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

            if ($attempt < $maxRetries) {
                sleep(2); // Yeniden denemeden önce bekleme
            }
        }
    }

    return null; // Tüm proxy'ler başarısız oldu
}

Guzzle'da hata işleme

<?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 erişilemez veya bağlantı zaman aşımı
            echo "Proxy erişilemez ($proxy): " . $e->getMessage() . "\n";

        } catch (ClientException $e) {
            // HTTP 4xx — istemci hatası (403, 404, 429)
            $code = $e->getResponse()->getStatusCode();
            echo "$url için $proxy üzerinden HTTP $code\n";

            if ($code === 429) {
                echo "Rate limit — 5 saniye bekleme\n";
                sleep(5);
            }

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

        } catch (RequestException $e) {
            // Diğer istek hataları
            echo "İstek hatası: " . $e->getMessage() . "\n";
        }
    }

    return null;
}

cURL vs Guzzle: hangisini seçmelisiniz

Her iki araç da proxy ile mükemmel çalışır, ancak farklı güçlü yönlere sahiptir. İşte ana kriterlere göre bir karşılaştırma:

Kriter cURL Guzzle
Kurulum ✅ PHP'de yerleşik ⚠️ Composer gerektirir
Kod okunabilirliği ⚠️ Çok fazla seçenek, ayrıntılı ✅ Temiz, kullanıcı dostu API
Performans ✅ Biraz daha hızlı (sarmalayıcı yok) ✅ Karşılaştırılabilir, asenkron var
Asenkron istekler ⚠️ curl_multi (zor) ✅ Yerleşik destek
Middleware / hook'lar ❌ Yok ✅ HandlerStack, Middleware
SOCKS5 desteği ✅ Yerel ✅ curl handler ile
Hata işleme ⚠️ Hata kodları manuel ✅ Türlerle istisnalar
Laravel/Symfony entegrasyonu ⚠️ Manuel ✅ Yerleşik destek
Uygun olduğu yerler Basit betikler, bağımlılık olmadan Framework projeleri, karmaşık mantık

Tavsiye: Eğer basit bir betik yazıyorsanız veya Composer olmayan bir hostta çalışıyorsanız — cURL kullanın. Laravel, Symfony veya herhangi bir modern PHP uygulaması için — Guzzle çok daha kullanışlı olacak ve ölçeklenebilirlik için daha fazla olanak sunacaktır.

🚀 Başlatmadan önce hızlı kontrol listesi

  • ✅ Proxy'nin çalıştığını kontrol edin: curl -x http://login:pass@host:port https://httpbin.org/ip
  • ✅ Zaman aşımını ayarlayın: timeout ve connect_timeout
  • ✅ Gerçekçi bir User-Agent ekleyin
  • ✅ İstekler arasında bekleme süreleri uygulayın (en az 500 ms)
  • ✅ Hata işleme ve başka bir proxy'ye geçiş için önlemler alın
  • ✅ SOCKS5 için CURLPROXY_SOCKS5_HOSTNAME kullanın (SOCKS5 değil)
  • ✅ Üretimde SSL doğrulamasını devre dışı bırakmayın

Sonuç

PHP'de proxy ayarlamak, doğru seçenekleri ve formatları bilmek koşuluyla zor bir görev değildir. Temel görevler için cURL ile CURLOPT_PROXY ve CURLOPT_PROXYUSERPWD yeterlidir. Framework projeleri için Guzzle, daha kullanıcı dostu bir API, tipli istisnalar ve proxy rotasyonu için middleware desteği sunar.

Güvenilir çalışma için anahtar ilkeler: DNS çözümlemesi ile SOCKS5 kullanın (CURLPROXY_SOCKS5_HOSTNAME), her zaman zaman aşım sürelerini ayarlayın, istekler arasında bekleme süreleri ekleyin ve büyük ölçekli görevler için proxy rotasyonu uygulayın. Hata işleme ve başka bir proxy'ye geçiş, her üretim kodunun zorunlu bir parçasıdır.

```