यदि आप एक पार्सर लिख रहे हैं, डेटा संग्रहण को स्वचालित कर रहे हैं या IP प्रतिबंधों को बायपास कर रहे हैं — PHP में प्रॉक्सी के बिना काम नहीं चलेगा। इस गाइड में हम दो मुख्य उपकरणों पर चर्चा करेंगे: अंतर्निहित cURL और लोकप्रिय पुस्तकालय Guzzle HTTP Client — तैयार कोड के उदाहरणों के साथ, जिन्हें आप तुरंत अपने प्रोजेक्ट में उपयोग कर सकते हैं।
PHP प्रोजेक्ट में प्रॉक्सी की आवश्यकता क्यों
PHP सर्वर स्वचालन के लिए सबसे व्यापक रूप से उपयोग किए जाने वाले भाषाओं में से एक है, और प्रॉक्सी की आवश्यकता वाली कार्यक्षेत्र लगातार मिलते हैं। यहाँ कुछ मुख्य परिदृश्य हैं, जहाँ प्रॉक्सी के बिना काम नहीं चलेगा:
- वेबसाइटों और मार्केटप्लेस का पार्सिंग — Wildberries, Ozon, Avito, AliExpress कुछ दर्जन अनुरोधों के बाद IP को ब्लॉक कर देते हैं। प्रॉक्सी विभिन्न पते के बीच लोड को वितरित करने की अनुमति देती हैं और 403/429 प्राप्त नहीं होती हैं।
- भौगोलिक रूप से निर्भर संसाधनों से डेटा संग्रहण — कीमतें, खोज इंजन का परिणाम, सामग्री देश के अनुसार भिन्न हो सकती हैं। आवश्यक भौगोलिक स्थिति के साथ प्रॉक्सी इस समस्या को हल करती हैं।
- रेट लिमिटिंग को बायपास करना — कई API एक IP से अनुरोधों की संख्या को सीमित करते हैं। प्रॉक्सी का रोटेशन इन सीमाओं को बायपास करने की अनुमति देता है।
- भौगोलिक रूप से निर्भर सामग्री का परीक्षण — यह जांचने के लिए कि विभिन्न देशों के उपयोगकर्ताओं के लिए वेबसाइट कैसी दिखती है, कार्यालय से बाहर निकले बिना।
- स्वचालन में गुमनामी — बाहरी संसाधनों के लिए बड़े पैमाने पर अनुरोध करते समय सर्वर का वास्तविक IP छिपाना।
- प्रतिस्पर्धियों की निगरानी — बिना बैन में आने के जोखिम के बिना प्रतिस्पर्धियों की वेबसाइटों से कीमतों, रेंज, और प्रचारों का नियमित संग्रह।
PHP में HTTP अनुरोधों के लिए आमतौर पर दो उपकरणों का उपयोग किया जाता है: अंतर्निहित cURL और पुस्तकालय Guzzle HTTP Client। दोनों HTTP, HTTPS, SOCKS4 और SOCKS5 प्रॉक्सी का समर्थन करते हैं — हम प्रत्येक को विस्तार से देखेंगे।
PHP के लिए किस प्रकार की प्रॉक्सी चुनें
कोड लिखने से पहले, यह समझना महत्वपूर्ण है कि आपकी आवश्यकता के लिए कौन सी प्रकार की प्रॉक्सी उपयुक्त है। विभिन्न प्रकारों की गति, विश्वसनीयता और गुमनामी की डिग्री में भिन्नताएँ होती हैं।
| प्रॉक्सी का प्रकार | गति | गुमनामी | के लिए सबसे अच्छा |
|---|---|---|---|
| डेटा सेंटर प्रॉक्सी | बहुत उच्च | मध्यम | कड़ी एंटी-बॉट सिस्टम के बिना पार्सिंग, API अनुरोध |
| रेजिडेंट प्रॉक्सी | मध्यम | उच्च | सुरक्षित वेबसाइटों का पार्सिंग, मार्केटप्लेस, भौगोलिक डेटा |
| मोबाइल प्रॉक्सी | मध्यम | अधिकतम | कड़ी एंटी-बॉट सुरक्षा वाली वेबसाइटें, सोशल नेटवर्क |
अधिकांश डेटा पार्सिंग कार्यों के लिए, जैसे कि Wildberries या Ozon, रेजिडेंट प्रॉक्सी सबसे उपयुक्त विकल्प होंगे — उनके IP वास्तविक घरेलू उपयोगकर्ताओं के हैं, जिससे अनुरोध सामान्य ब्राउज़र ट्रैफ़िक से लगभग अप्रभेद्य हो जाते हैं। डेटा सेंटर प्रॉक्सी उन स्थानों के लिए उपयुक्त हैं जहाँ गति गुमनामी से अधिक महत्वपूर्ण है और सुरक्षा कमजोर है।
तीनों प्रकार की प्रॉक्सी HTTP/HTTPS और SOCKS5 प्रोटोकॉल का समर्थन करते हैं, इसलिए कोड के दृष्टिकोण से — सेटअप समान है। केवल कनेक्शन स्ट्रिंग में अंतर है।
cURL में प्रॉक्सी: बुनियादी सेटअप
cURL एक्सटेंशन PHP में डिफ़ॉल्ट रूप से उपलब्ध है और सर्वर पर HTTP अनुरोध करने का मानक तरीका है। प्रॉक्सी को कनेक्ट करने के लिए दो मुख्य विकल्पों का उपयोग किया जाता है: CURLOPT_PROXY और CURLOPT_PROXYTYPE।
प्रमाणीकरण के बिना HTTP प्रॉक्सी
<?php
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://httpbin.org/ip',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30,
// प्रॉक्सी का पता निर्दिष्ट करें
CURLOPT_PROXY => '185.199.100.1:8080',
// प्रॉक्सी का प्रकार: HTTP (डिफ़ॉल्ट)
CURLOPT_PROXYTYPE => CURLPROXY_HTTP,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "HTTP कोड: $httpCode\n";
echo $response;
यहाँ CURLOPT_PROXY host:port प्रारूप में एक स्ट्रिंग लेता है। HTTPS ट्रैफ़िक के लिए HTTP प्रॉक्सी के माध्यम से cURL स्वचालित रूप से CONNECT विधि का उपयोग करता है — टनलिंग, इसलिए अनुरोध की सामग्री एन्क्रिप्टेड रहती है।
प्रॉक्सी के साथ काम करने के लिए cURL के उपयोगी विकल्प
| विकल्प | विवरण |
|---|---|
CURLOPT_PROXY |
प्रॉक्सी सर्वर का पता (host:port) |
CURLOPT_PROXYTYPE |
प्रकार: CURLPROXY_HTTP, CURLPROXY_SOCKS4, CURLPROXY_SOCKS5 |
CURLOPT_PROXYUSERPWD |
उपयोगकर्ता नाम और पासवर्ड user:password प्रारूप में |
CURLOPT_HTTPPROXYTUNNEL |
HTTP CONNECT के माध्यम से टनलिंग सक्षम करें |
CURLOPT_SSL_VERIFYPEER |
SSL प्रमाणपत्र की जांच (false — बंद करें) |
CURLOPT_TIMEOUT |
अनुरोध का टाइमआउट सेकंड में |
CURLOPT_CONNECTTIMEOUT |
प्रॉक्सी से कनेक्ट करने का टाइमआउट |
cURL में प्रमाणीकरण और SOCKS5
अधिकांश व्यावसायिक प्रॉक्सी प्रमाणीकरण के लिए उपयोगकर्ता नाम और पासवर्ड की आवश्यकता होती है। SOCKS5 भी एक पसंदीदा प्रोटोकॉल है जब पूर्ण गुमनामी की आवश्यकता होती है, क्योंकि यह X-Forwarded-For जैसे हेडर नहीं जोड़ता है, जो प्रॉक्सी के उपयोग का खुलासा कर सकते हैं।
HTTP प्रॉक्सी के साथ लॉगिन और पासवर्ड
<?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,
// प्रमाणीकरण के साथ प्रॉक्सी
CURLOPT_PROXY => "$proxyHost:$proxyPort",
CURLOPT_PROXYTYPE => CURLPROXY_HTTP,
CURLOPT_PROXYUSERPWD => "$proxyUser:$proxyPass",
// HTTPS के लिए टनलिंग
CURLOPT_HTTPPROXYTUNNEL => true,
// मास्किंग के लिए ब्राउज़र हेडर
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 त्रुटि: ' . curl_error($ch);
} else {
echo $response;
}
curl_close($ch);
cURL में SOCKS5 प्रॉक्सी
<?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 के माध्यम से प्रॉक्सी के साथ SOCKS5 (अनुशंसित!)
CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5_HOSTNAME,
// प्रमाणीकरण (यदि आवश्यक हो)
CURLOPT_PROXYUSERPWD => 'login:password',
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
💡 महत्वपूर्ण: SOCKS5 बनाम SOCKS5_HOSTNAME
CURLPROXY_SOCKS5_HOSTNAME का उपयोग करें CURLPROXY_SOCKS5 के बजाय। अंतर यह है कि SOCKS5_HOSTNAME में DNS अनुरोध भी प्रॉक्सी के माध्यम से होते हैं, जो DNS लीक को रोकता है और गुमनामी बढ़ाता है। सामान्य SOCKS5 में DNS स्थानीय रूप से हल होता है — यह आपके वास्तविक IP को उजागर कर सकता है।
cURL में प्रॉक्सी का रोटेशन
एक प्रॉक्सी बड़े पैमाने पर अनुरोधों के दौरान जल्दी से ब्लॉक हो जाएगी। सही रणनीति — प्रॉक्सी का एक पूल होना और उन्हें बारी-बारी से उपयोग करना। यहाँ एक सरल, लेकिन कार्यात्मक कार्यान्वयन है:
<?php
class ProxyRotator
{
private array $proxies;
private int $currentIndex = 0;
public function __construct(array $proxies)
{
$this->proxies = $proxies;
shuffle($this->proxies); // यादृच्छिक क्रम के लिए शफल करें
}
/**
* पूल से अगली प्रॉक्सी प्राप्त करें
*/
public function getNext(): string
{
$proxy = $this->proxies[$this->currentIndex];
$this->currentIndex = ($this->currentIndex + 1) % count($this->proxies);
return $proxy;
}
/**
* एक यादृच्छिक प्रॉक्सी प्राप्त करें
*/
public function getRandom(): string
{
return $this->proxies[array_rand($this->proxies)];
}
}
// प्रॉक्सी की सूची 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);
/**
* स्वचालित प्रॉक्सी चयन के साथ अनुरोध करने का कार्य
*/
function fetchWithProxy(string $url, ProxyRotator $rotator): ?string
{
$proxyStr = $rotator->getNext();
// प्रॉक्सी स्ट्रिंग को पार्स करें
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("प्रॉक्सी $host:$port अनुपलब्ध है: $error");
return null;
}
return $response;
}
// उदाहरण: प्रॉक्सी के रोटेशन के साथ 10 पृष्ठों को पार्स करें
$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 "प्राप्त: " . strlen($html) . " बाइट\n";
}
usleep(500000); // अनुरोधों के बीच 0.5 सेकंड का विराम
}
usleep(500000) पर ध्यान दें — अनुरोधों के बीच का विराम महत्वपूर्ण है। प्रॉक्सी के रोटेशन के साथ भी, बहुत बार अनुरोध करने से व्यवहार पैटर्न के कारण ब्लॉक हो सकता है। अनुशंसित अंतराल — 500 मिलीसेकंड से 2 सेकंड तक, साइट के आधार पर।
Guzzle HTTP Client में प्रॉक्सी: बुनियादी सेटअप
Guzzle HTTP अनुरोधों के लिए एक शक्तिशाली PHP पुस्तकालय है, जिसका उपयोग अधिकांश आधुनिक PHP फ्रेमवर्क (Laravel, Symfony) में किया जाता है। यह cURL की तुलना में अधिक सुविधाजनक और पठनीय API प्रदान करता है, असिंक्रोनस अनुरोधों, मिडलवेयर और त्रुटियों को संभालने की सुविधाओं का समर्थन करता है।
Composer के माध्यम से स्थापना
composer require guzzlehttp/guzzle
प्रमाणीकरण के बिना HTTP प्रॉक्सी
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
// बेस URL (वैकल्पिक)
'base_uri' => 'https://httpbin.org',
// सभी अनुरोधों के लिए डिफ़ॉल्ट सेटिंग्स
'timeout' => 30,
'connect_timeout' => 10,
// क्लाइंट के सभी अनुरोधों के लिए प्रॉक्सी
'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 में प्रॉक्सी को URL प्रारूप में proxy विकल्प के माध्यम से सेट किया जाता है। यह cURL की तुलना में अधिक सहज है। प्रॉक्सी को क्लाइंट स्तर पर (सभी अनुरोधों के लिए) या प्रत्येक अनुरोध के लिए अलग से सेट किया जा सकता है।
HTTP प्रॉक्सी के साथ प्रमाणीकरण
<?php
use GuzzleHttp\Client;
$login = 'your_login';
$password = 'your_password';
$host = '185.199.100.1';
$port = '8080';
$client = new Client([
'timeout' => 30,
]);
// प्रमाणीकरण के साथ प्रॉक्सी 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();
Guzzle में प्रॉक्सी URL का प्रारूप: scheme://user:password@host:port। HTTP प्रॉक्सी के लिए http:// का उपयोग करें, SOCKS5 के लिए — socks5://।
Guzzle के साथ उन्नत कार्य: टाइमआउट, हेडर, SOCKS5
चलिए अधिक जटिल परिदृश्यों पर विचार करते हैं: HTTP और HTTPS के लिए विभिन्न प्रॉक्सी, SOCKS5, SSL सत्यापन को बंद करना और ब्राउज़र की नकल के लिए हेडर सेट करना।
HTTP और HTTPS के लिए विभिन्न प्रॉक्सी
<?php
use GuzzleHttp\Client;
$client = new Client([
'timeout' => 30,
'proxy' => [
// HTTP अनुरोधों के लिए प्रॉक्सी
'http' => 'http://login:[email protected]:8080',
// HTTPS अनुरोधों के लिए प्रॉक्सी
'https' => 'http://login:[email protected]:8080',
// अपवाद — ये होस्ट बिना प्रॉक्सी के जाएंगे
'no' => ['localhost', '127.0.0.1', '.internal.corp'],
],
]);
Guzzle में SOCKS5
<?php
use GuzzleHttp\Client;
// Guzzle में SOCKS5 के लिए अतिरिक्त पैकेज की आवश्यकता है
// composer require clue/socks-react (या cURL हैंडलर का उपयोग करें)
$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();
ब्राउज़र हेडर के साथ पूर्ण कॉन्फ़िगरेशन
<?php
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
$client = new Client([
'timeout' => 30,
'connect_timeout' => 10,
'verify' => false, // डिबगिंग के लिए SSL सत्यापन बंद करें
'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 "स्थिति: $statusCode, आकार: " . strlen($body) . " बाइट\n";
⚠️ verify => false के बारे में
SSL सत्यापन को बंद करना ('verify' => false) केवल डिबगिंग या आंतरिक सेवाओं के साथ काम करते समय स्वीकार्य है। उत्पादन कोड में हमेशा SSL सत्यापन को चालू रखें, अन्यथा आप मैन-इन-द-मिडल प्रकार के हमलों के लिए संवेदनशील हैं।
Guzzle में प्रॉक्सी का रोटेशन
Guzzle में रोटेशन को मिडलवेयर के माध्यम से आसानी से लागू किया जा सकता है — एक मध्यवर्ती परत, जो प्रत्येक अनुरोध को पकड़ती है और उसमें प्रॉक्सी जोड़ती है। यह प्रत्येक कॉल में प्रॉक्सी को मैन्युअल रूप से पास करने की तुलना में अधिक सुरुचिपूर्ण है।
<?php
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
/**
* प्रॉक्सी के स्वचालित रोटेशन के लिए मिडलवेयर
*/
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++;
// अनुरोध के गुणों में प्रॉक्सी जोड़ें
// (हैंडलर में विकल्पों के माध्यम से पास करें)
return $request->withHeader('X-Selected-Proxy', $proxy);
}
);
}
// प्रॉक्सी की सूची
$proxies = [
'http://user1:[email protected]:8080',
'http://user2:[email protected]:8080',
'http://user3:[email protected]:8080',
];
// सरल विकल्प: Guzzle के चारों ओर रोटेशन के साथ एक क्लास
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);
}
}
// उपयोग
$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 "ठीक है [{$response->getStatusCode()}]: $url\n";
sleep(1);
} catch (\Exception $e) {
echo "त्रुटि: " . $e->getMessage() . "\n";
}
}
त्रुटियों को संभालना और डिबगिंग
प्रॉक्सी के साथ काम करते समय त्रुटियाँ अपरिहार्य हैं: प्रॉक्सी अनुपलब्ध हो सकती है, धीमी प्रतिक्रिया दे सकती है, या लक्षित वेबसाइट त्रुटि लौटा सकती है। इन सभी स्थितियों को सही तरीके से संभालना महत्वपूर्ण है।
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 त्रुटि कोड
$proxyErrors = [
CURLE_COULDNT_CONNECT => 'प्रॉक्सी से कनेक्ट नहीं हो सका',
CURLE_OPERATION_TIMEDOUT => 'प्रॉक्सी के लिए कनेक्शन टाइमआउट',
CURLE_RECV_ERROR => 'डेटा प्राप्त करने में त्रुटि',
CURLE_SSL_CONNECT_ERROR => 'प्रॉक्सी के माध्यम से SSL त्रुटि',
];
if ($errno) {
$message = $proxyErrors[$errno] ?? "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),
];
}
// पुनः प्रयास के साथ उपयोग
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 "सफलता $proxy के माध्यम से (प्रयास $attempt, {$result['time']}से)\n";
return $result['body'];
}
echo "$proxy के माध्यम से त्रुटि: {$result['error']}\n";
if ($attempt < $maxRetries) {
sleep(2); // पुनः प्रयास से पहले विराम
}
}
}
return null; // सभी प्रॉक्सी काम नहीं आईं
}
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) {
// प्रॉक्सी अनुपलब्ध है या कनेक्शन टाइमआउट
echo "प्रॉक्सी अनुपलब्ध ($proxy): " . $e->getMessage() . "\n";
} catch (ClientException $e) {
// HTTP 4xx — क्लाइंट त्रुटि (403, 404, 429)
$code = $e->getResponse()->getStatusCode();
echo "$url के लिए HTTP $code $proxy के माध्यम से\n";
if ($code === 429) {
echo "रेट लिमिट — 5 सेकंड का विराम\n";
sleep(5);
}
} catch (ServerException $e) {
// HTTP 5xx — सर्वर त्रुटि
echo "सर्वर त्रुटि: " . $e->getResponse()->getStatusCode() . "\n";
} catch (RequestException $e) {
// अन्य अनुरोध त्रुटियाँ
echo "अनुरोध त्रुटि: " . $e->getMessage() . "\n";
}
}
return null;
}
cURL बनाम Guzzle: क्या चुनें
दोनों उपकरण प्रॉक्सी के साथ अच्छी तरह से काम करते हैं, लेकिन उनकी अलग-अलग ताकतें हैं। यहाँ प्रमुख मानदंडों पर तुलना है:
| मानदंड | cURL | Guzzle |
|---|---|---|
| स्थापना | ✅ PHP में अंतर्निहित | ⚠️ Composer की आवश्यकता है |
| कोड की पठनीयता | ⚠️ बहुत सारे विकल्प, शब्दों की अधिकता | ✅ साफ, उपयोग में आसान API |
| प्रदर्शन | ✅ थोड़ा तेज़ (कोई लपेटन नहीं) | ✅ तुलनीय, असिंक्रोनस है |
| असिंक्रोनस अनुरोध | ⚠️ curl_multi (जटिल) | ✅ अंतर्निहित समर्थन |
| मिडलवेयर / हुक | ❌ नहीं | ✅ HandlerStack, Middleware |
| SOCKS5 समर्थन | ✅ स्वदेशी | ✅ cURL हैंडलर के माध्यम से |
| त्रुटियों को संभालना | ⚠️ त्रुटियों के कोड मैन्युअल रूप से | ✅ प्रकार के साथ अपवाद |
| Laravel/Symfony में एकीकरण | ⚠️ मैन्युअल रूप से | ✅ स्वदेशी समर्थन |
| के लिए उपयुक्त | सरल स्क्रिप्ट, बिना निर्भरताओं के | फ्रेमवर्क पर प्रोजेक्ट, जटिल लॉजिक |
अनुशंसा: यदि आप एक सरल स्क्रिप्ट लिख रहे हैं या Composer के बिना होस्टिंग पर काम कर रहे हैं — cURL का उपयोग करें। Laravel, Symfony या किसी भी आधुनिक PHP अनुप्रयोगों पर प्रोजेक्ट के लिए — Guzzle काफी अधिक सुविधाजनक होगा और स्केलिंग के लिए अधिक अवसर प्रदान करेगा।
🚀 लॉन्च से पहले त्वरित चेकलिस्ट
- ✅ सुनिश्चित करें कि प्रॉक्सी काम कर रहा है:
curl -x http://login:pass@host:port https://httpbin.org/ip - ✅ टाइमआउट सेट करें:
timeoutऔरconnect_timeout - ✅ यथार्थवादी User-Agent जोड़ें
- ✅ अनुरोधों के बीच विराम लागू करें (कम से कम 500 मिलीसेकंड)
- ✅ त्रुटियों को संभालने और दूसरे प्रॉक्सी पर फॉलबैक का प्रावधान करें
- ✅ SOCKS5 के लिए CURLPROXY_SOCKS5_HOSTNAME का उपयोग करें (SOCKS5 नहीं)
- ✅ उत्पादन में SSL सत्यापन बंद न करें
निष्कर्ष
PHP में प्रॉक्सी सेटअप करना एक सरल कार्य है, यदि सही विकल्पों और प्रारूपों को जानें। बुनियादी कार्यों के लिए cURL के साथ CURLOPT_PROXY और CURLOPT_PROXYUSERPWD पर्याप्त हैं। फ्रेमवर्क पर प्रोजेक्ट के लिए Guzzle एक अधिक सुविधाजनक API, प्रकारित अपवाद और प्रॉक्सी के रोटेशन के लिए मिडलवेयर का समर्थन प्रदान करता है।
विश्वसनीय कार्य के लिए मुख्य सिद्धांत: DNS के माध्यम से प्रॉक्सी के साथ SOCKS5 का उपयोग करें (CURLPROXY_SOCKS5_HOSTNAME), हमेशा टाइमआउट सेट करें, अनुरोधों के बीच विराम जोड़ें और बड़े पैमाने पर कार्यों के लिए प्रॉक्सी का रोटेशन लागू करें। त्रुटियों को संभालना और दूसरे प्रॉक्सी पर फॉलबैक एक आवश्यक तत्व है किसी भी उत्पादन कोड का।
```