Kembali ke blog

Pengaturan Proxy di PHP Menggunakan cURL dan Guzzle HTTP Client: Panduan Lengkap dengan Contoh Kode

Panduan lengkap untuk mengatur proxy di PHP melalui cURL dan Guzzle HTTP Client — dengan contoh kode, rotasi IP, dan tips memilih jenis proxy untuk pengambilan data dan otomatisasi.

📅12 Agustus 2026
```html

Jika Anda menulis parser, mengotomatisasi pengumpulan data, atau menghindari batasan IP — tanpa proxy di PHP tidak mungkin. Dalam panduan ini, kita akan membahas dua alat utama: cURL yang terintegrasi dan pustaka populer Guzzle HTTP Client — dengan contoh kode siap pakai yang bisa langsung digunakan dalam proyek.

Mengapa proxy di proyek PHP

PHP tetap menjadi salah satu bahasa yang paling umum digunakan untuk otomatisasi server, dan tugas yang memerlukan proxy selalu muncul. Berikut adalah skenario utama di mana proxy tidak bisa dihindari:

  • Pemrograman situs web dan marketplace — Wildberries, Ozon, Avito, AliExpress memblokir IP setelah beberapa puluh permintaan. Proxy memungkinkan distribusi beban antara alamat yang berbeda dan tidak mendapatkan 403/429.
  • Pengumpulan data dari sumber yang bergantung pada geolokasi — harga, hasil pencarian, konten dapat berbeda tergantung pada negara. Proxy dengan geolokasi yang tepat menyelesaikan masalah ini.
  • Menghindari pembatasan laju — banyak API membatasi jumlah permintaan dari satu IP. Rotasi proxy memungkinkan untuk menghindari batasan ini.
  • Pengujian konten yang bergantung pada geolokasi — memeriksa bagaimana tampilan situs untuk pengguna dari negara yang berbeda, tanpa meninggalkan kantor.
  • Anonymitas saat otomatisasi — menyembunyikan IP nyata server saat melakukan permintaan massal ke sumber eksternal.
  • Memantau pesaing — pengumpulan harga, variasi, promosi secara teratur dari situs pesaing tanpa risiko diblokir.

Di PHP, untuk permintaan HTTP, biasanya digunakan dua alat: ekstensi terintegrasi cURL dan pustaka Guzzle HTTP Client. Keduanya mendukung proxy HTTP, HTTPS, SOCKS4, dan SOCKS5 — mari kita bahas satu per satu secara mendetail.

Jenis proxy apa yang dipilih untuk PHP

Sebelum menulis kode, penting untuk memahami jenis proxy mana yang sesuai untuk tugas Anda. Berbagai jenis memiliki karakteristik yang berbeda dalam hal kecepatan, keandalan, dan tingkat anonimitas.

Jenis Proxy Kecepatan Anonimitas Terbaik untuk
Proxy pusat data Sangat tinggi Sedang Pengambilan data tanpa sistem anti-bot yang ketat, permintaan API
Proxy residensial Sedang Tinggi Pengambilan data dari situs yang dilindungi, marketplace, data geolokasi
Proxy seluler Sedang Maksimal Situs dengan perlindungan anti-bot yang ketat, media sosial

Untuk sebagian besar tugas pengambilan data dari marketplace seperti Wildberries atau Ozon, pilihan optimal adalah proxy residensial — IP mereka dimiliki oleh pengguna rumah nyata, sehingga permintaan hampir tidak dapat dibedakan dari lalu lintas browser biasa. Proxy pusat data cocok di tempat di mana kecepatan lebih penting daripada ketidaknampakan, dan perlindungan lemah.

Ketiga jenis proxy mendukung protokol HTTP/HTTPS dan SOCKS5, jadi dari segi kode — pengaturannya sama. Perbedaannya hanya pada string koneksi.

Proxy di cURL: pengaturan dasar

Ekstensi cURL tersedia di PHP secara default dan merupakan cara standar untuk melakukan permintaan HTTP di server. Untuk menghubungkan proxy, digunakan dua opsi utama: CURLOPT_PROXY dan CURLOPT_PROXYTYPE.

Proxy HTTP tanpa autentikasi

<?php

$ch = curl_init();

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

    // Menentukan alamat proxy
    CURLOPT_PROXY          => '185.199.100.1:8080',

    // Jenis proxy: HTTP (default)
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
]);

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

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

Di sini CURLOPT_PROXY menerima string dalam format host:port. Untuk lalu lintas HTTPS melalui proxy HTTP, cURL secara otomatis menggunakan metode CONNECT — tunneling, sehingga konten permintaan tetap terenkripsi.

Opsi cURL yang berguna untuk bekerja dengan proxy

Opsi Deskripsi
CURLOPT_PROXY Alamat server proxy (host:port)
CURLOPT_PROXYTYPE Jenis: CURLPROXY_HTTP, CURLPROXY_SOCKS4, CURLPROXY_SOCKS5
CURLOPT_PROXYUSERPWD Login dan password dalam format user:password
CURLOPT_HTTPPROXYTUNNEL Aktifkan tunneling melalui HTTP CONNECT
CURLOPT_SSL_VERIFYPEER Verifikasi sertifikat SSL (false — nonaktifkan)
CURLOPT_TIMEOUT Timeout permintaan dalam detik
CURLOPT_CONNECTTIMEOUT Timeout koneksi ke proxy

Autentikasi dan SOCKS5 di cURL

Sebagian besar proxy komersial memerlukan autentikasi dengan login dan password. Selain itu, SOCKS5 adalah protokol yang lebih disukai ketika diperlukan anonimitas penuh, karena tidak menambahkan header seperti X-Forwarded-For, yang dapat mengungkapkan penggunaan proxy.

Proxy HTTP dengan login dan password

<?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 dengan autentikasi
    CURLOPT_PROXY          => "$proxyHost:$proxyPort",
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
    CURLOPT_PROXYUSERPWD   => "$proxyUser:$proxyPass",

    // Tunneling untuk HTTPS
    CURLOPT_HTTPPROXYTUNNEL => true,

    // Header browser untuk menyamarkan
    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 'Kesalahan cURL: ' . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

Proxy SOCKS5 di 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 dengan resolusi DNS melalui proxy (disarankan!)
    CURLOPT_PROXYTYPE      => CURLPROXY_SOCKS5_HOSTNAME,

    // Autentikasi (jika diperlukan)
    CURLOPT_PROXYUSERPWD   => 'login:password',
]);

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

echo $response;

💡 Penting: SOCKS5 vs SOCKS5_HOSTNAME

Gunakan CURLPROXY_SOCKS5_HOSTNAME alih-alih CURLPROXY_SOCKS5. Perbedaannya adalah, dengan SOCKS5_HOSTNAME, permintaan DNS juga dilakukan melalui proxy, yang mencegah kebocoran DNS dan meningkatkan anonimitas. Dengan SOCKS5 biasa, DNS diselesaikan secara lokal — ini dapat mengungkapkan IP nyata Anda.

Rotasi proxy di cURL

Satu proxy akan cepat diblokir saat melakukan permintaan massal. Strategi yang tepat adalah memiliki kumpulan proxy dan mengalirkannya. Berikut adalah implementasi sederhana namun efektif:

<?php

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

    public function __construct(array $proxies)
    {
        $this->proxies = $proxies;
        shuffle($this->proxies); // Mengacak untuk urutan acak
    }

    /**
     * Mendapatkan proxy berikutnya dari kumpulan
     */
    public function getNext(): string
    {
        $proxy = $this->proxies[$this->currentIndex];
        $this->currentIndex = ($this->currentIndex + 1) % count($this->proxies);
        return $proxy;
    }

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

// Daftar proxy dalam 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);

/**
 * Fungsi permintaan dengan pemilihan proxy otomatis
 */
function fetchWithProxy(string $url, ProxyRotator $rotator): ?string
{
    $proxyStr = $rotator->getNext();

    // Parsing string proxy
    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 tidak tersedia: $error");
        return null;
    }

    return $response;
}

// Contoh: mengambil 10 halaman dengan rotasi proxy
$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 "Diterima: " . strlen($html) . " byte\n";
    }
    usleep(500000); // Jeda 0.5 detik antara permintaan
}

Perhatikan usleep(500000) — jeda antara permintaan sangat penting. Bahkan dengan rotasi proxy, permintaan yang terlalu sering dapat menyebabkan pemblokiran berdasarkan pola perilaku. Interval yang disarankan adalah antara 500 ms hingga 2 detik tergantung pada situs.

Proxy di Guzzle HTTP Client: pengaturan dasar

Guzzle adalah pustaka PHP yang kuat untuk permintaan HTTP, yang digunakan di sebagian besar kerangka kerja PHP modern (Laravel, Symfony). Ini menyediakan API yang lebih nyaman dan mudah dibaca dibandingkan dengan cURL mentah, mendukung permintaan asinkron, middleware, dan penanganan kesalahan yang nyaman.

Instalasi melalui Composer

composer require guzzlehttp/guzzle

Proxy HTTP tanpa autentikasi

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client([
    // URL dasar (opsional)
    'base_uri' => 'https://httpbin.org',

    // Pengaturan default untuk semua permintaan
    'timeout'  => 30,
    'connect_timeout' => 10,

    // Proxy untuk semua permintaan klien
    '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"}

Di Guzzle, proxy ditentukan melalui opsi proxy dalam format URL. Ini lebih intuitif dibandingkan dengan cURL. Proxy dapat ditentukan baik di tingkat klien (untuk semua permintaan) maupun untuk setiap permintaan secara terpisah.

Proxy HTTP dengan autentikasi

<?php

use GuzzleHttp\Client;

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

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

// Proxy dengan autentikasi dikirim dalam format URL
$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();

Format URL proxy di Guzzle: scheme://user:password@host:port. Untuk proxy HTTP, gunakan http://, untuk SOCKS5 — socks5://.

Pekerjaan lanjutan dengan Guzzle: timeout, header, SOCKS5

Mari kita lihat skenario yang lebih kompleks: berbagai proxy untuk HTTP dan HTTPS, SOCKS5, menonaktifkan verifikasi SSL, dan pengaturan header untuk meniru browser.

Proxy yang berbeda untuk HTTP dan HTTPS

<?php

use GuzzleHttp\Client;

$client = new Client([
    'timeout' => 30,
    'proxy'   => [
        // Proxy untuk permintaan HTTP
        'http'  => 'http://login:[email protected]:8080',
        // Proxy untuk permintaan HTTPS
        'https' => 'http://login:[email protected]:8080',
        // Pengecualian — host ini tidak menggunakan proxy
        'no'    => ['localhost', '127.0.0.1', '.internal.corp'],
    ],
]);

SOCKS5 di Guzzle

<?php

use GuzzleHttp\Client;

// Untuk SOCKS5 di Guzzle, diperlukan paket tambahan
// composer require clue/socks-react (atau gunakan 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();

Konfigurasi lengkap dengan header browser

<?php

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;

$client = new Client([
    'timeout'         => 30,
    'connect_timeout' => 10,
    'verify'          => false, // Nonaktifkan verifikasi SSL (untuk 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, Ukuran: " . strlen($body) . " byte\n";

⚠️ Tentang verify => false

Menonaktifkan verifikasi SSL ('verify' => false) hanya diperbolehkan saat debugging atau bekerja dengan layanan internal. Dalam kode produksi, selalu biarkan verifikasi SSL diaktifkan, jika tidak, Anda rentan terhadap serangan man-in-the-middle.

Rotasi proxy di Guzzle

Di Guzzle, rotasi dapat dengan mudah diimplementasikan melalui middleware — lapisan perantara yang menangkap setiap permintaan dan menambahkan proxy ke dalamnya. Ini lebih elegan dibandingkan dengan mengirimkan proxy secara manual di setiap panggilan.

<?php

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

/**
 * Middleware untuk rotasi proxy otomatis
 */
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++;

            // Menambahkan proxy ke atribut permintaan
            // (dikirim melalui opsi di handler)
            return $request->withHeader('X-Selected-Proxy', $proxy);
        }
    );
}

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

// Versi sederhana: kelas pembungkus di atas Guzzle dengan rotasi
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);
    }
}

// Penggunaan
$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 "Kesalahan: " . $e->getMessage() . "\n";
    }
}

Penanganan kesalahan dan debugging

Saat bekerja dengan proxy, kesalahan tidak dapat dihindari: proxy mungkin tidak tersedia, merespons lambat, atau situs target mungkin mengembalikan kesalahan. Penting untuk menangani semua situasi ini dengan baik.

Penanganan kesalahan di 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);

    // Kode kesalahan cURL untuk proxy
    $proxyErrors = [
        CURLE_COULDNT_CONNECT    => 'Tidak dapat terhubung ke proxy',
        CURLE_OPERATION_TIMEDOUT => 'Timeout koneksi ke proxy',
        CURLE_RECV_ERROR         => 'Kesalahan menerima data',
        CURLE_SSL_CONNECT_ERROR  => 'Kesalahan SSL melalui proxy',
    ];

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

// Penggunaan dengan percobaan ulang
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 "Sukses melalui $proxy (percobaan $attempt, {$result['time']}s)\n";
                return $result['body'];
            }

            echo "Kesalahan melalui $proxy: {$result['error']}\n";

            if ($attempt < $maxRetries) {
                sleep(2); // Jeda sebelum mencoba lagi
            }
        }
    }

    return null; // Semua proxy tidak berhasil
}

Penanganan kesalahan di 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 tidak tersedia atau timeout koneksi
            echo "Proxy tidak tersedia ($proxy): " . $e->getMessage() . "\n";

        } catch (ClientException $e) {
            // HTTP 4xx — kesalahan klien (403, 404, 429)
            $code = $e->getResponse()->getStatusCode();
            echo "HTTP $code untuk $url melalui $proxy\n";

            if ($code === 429) {
                echo "Batas laju — jeda 5 detik\n";
                sleep(5);
            }

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

        } catch (RequestException $e) {
            // Kesalahan permintaan lainnya
            echo "Kesalahan permintaan: " . $e->getMessage() . "\n";
        }
    }

    return null;
}

cURL vs Guzzle: mana yang dipilih

Kedua alat bekerja dengan baik dengan proxy, tetapi memiliki kelebihan yang berbeda. Berikut adalah perbandingan berdasarkan kriteria kunci:

Kriteria cURL Guzzle
Instalasi ✅ Terintegrasi dalam PHP ⚠️ Membutuhkan Composer
Keterbacaan kode ⚠️ Banyak opsi, verbose ✅ API bersih, nyaman
Kinerja ✅ Sedikit lebih cepat (tanpa pembungkus) ✅ Sebanding, ada async
Permintaan asinkron ⚠️ curl_multi (sulit) ✅ Dukungan bawaan
Middleware / hooks ❌ Tidak ada ✅ HandlerStack, Middleware
Dukungan SOCKS5 ✅ Native ✅ Melalui curl handler
Penanganan kesalahan ⚠️ Kode kesalahan manual ✅ Pengecualian dengan tipe
Integrasi di Laravel/Symfony ⚠️ Manual ✅ Dukungan native
Cocok untuk Skrip sederhana, tanpa ketergantungan Proyek di framework, logika kompleks

Rekomendasi: Jika Anda menulis skrip sederhana atau bekerja di hosting tanpa Composer — gunakan cURL. Untuk proyek di Laravel, Symfony, atau aplikasi PHP modern lainnya — Guzzle akan jauh lebih nyaman dan memberikan lebih banyak kemungkinan untuk skala.

🚀 Daftar periksa cepat sebelum peluncuran

  • ✅ Periksa bahwa proxy berfungsi: curl -x http://login:pass@host:port https://httpbin.org/ip
  • ✅ Tetapkan timeout: timeout dan connect_timeout
  • ✅ Tambahkan User-Agent yang realistis
  • ✅ Laksanakan jeda antara permintaan (minimal 500 ms)
  • ✅ Pertimbangkan penanganan kesalahan dan fallback ke proxy lain
  • ✅ Untuk SOCKS5, gunakan CURLPROXY_SOCKS5_HOSTNAME (bukan SOCKS5)
  • ✅ Jangan menonaktifkan verifikasi SSL di produksi

Kesimpulan

Mengatur proxy di PHP adalah tugas yang tidak sulit jika Anda tahu opsi dan format yang tepat. Untuk tugas dasar, cukup gunakan cURL dengan CURLOPT_PROXY dan CURLOPT_PROXYUSERPWD. Untuk proyek di framework, Guzzle menyediakan API yang lebih nyaman, pengecualian bertipe, dan dukungan middleware untuk rotasi proxy.

Prinsip kunci untuk operasi yang andal: gunakan SOCKS5 dengan resolusi DNS melalui proxy (CURLPROXY_SOCKS5_HOSTNAME), selalu tetapkan timeout, tambahkan jeda antara permintaan, dan laksanakan rotasi proxy untuk tugas besar. Penanganan kesalahan dengan fallback ke proxy lain adalah elemen wajib dari setiap kode produksi.

```