【问题标题】:Set proxy in Guzzle在 Guzzle 中设置代理
【发布时间】:2015-11-26 07:02:42
【问题描述】:

我在 guzzle 中设置代理时遇到问题,显示空白页面,而使用 curl 一切正常。我在 guzzle 和 curl 中使用的代码如下。 这段代码有什么问题: 狂饮:

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

require_once "vendor/autoload.php";

try {
  $client = new Client();
  $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
  $response = $client->send($request, [
      'timeout'  => 30,
      'curl'  => [
          'CURLOPT_PROXY' => '*.*.*.*',
          'CURLOPT_PROXYPORT' => *,
          'CURLOPT_PROXYUSERPWD' => '*:*',
      ],

  ]);
  echo '</pre>';
  echo($response->getBody());
  exit;
} catch (RequestException $e) {
  echo $e->getRequest();
  if ($e->hasResponse()) {
      echo $e->getResponse();
  }
}

以及带有 CURL 的代码:

$url = 'http://httpbin.org';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_PROXY, '*.*.*.*');
curl_setopt($ch, CURLOPT_PROXYPORT, *);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, '*:*');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$page = curl_exec($ch);
echo $page;

谢谢。

【问题讨论】:

    标签: php curl proxy guzzle


    【解决方案1】:

    至于Guzzle 6

    Guzzle docs 提供有关为单个请求设置代理的信息

    $client->request('GET', '/', ['proxy' => 'tcp://localhost:8125']);
    

    但是你可以在初始化客户端的时候设置为所有请求

        $client = new Client([
            'base_uri' => 'http://doma.in/',
            'timeout' => 10.0,
            'cookie' => true,
            'proxy' => 'tcp://12.34.56.78:3128',
        ]);
    

    UPD。我不知道为什么,但我面临着一种奇怪的行为。具有 guzzle 版本 6.2.2 的一台服务器与上述配置配合得很好,而另一台具有相同版本的服务器从代理收到400 Bad Request HTTP 错误。它通过另一个配置结构解决(在docs for guzzle 3中找到)

    $client = new Client([
        'base_uri' => 'http://doma.in/',
        'timeout' => 10.0,
        'cookie' => true,
        'request.options' => [
            'proxy' => 'tcp://12.34.56.78:3128',
        ],
    ]);
    

    【讨论】:

      【解决方案2】:

      对于代理,如果你有用户名和密码,你可以使用:

      $client = new GuzzleHttp\Client();
      
      $res = $client->request("POST", "https://endpoint.com", [
          "proxy" => "http://username:password@192.168.16.1:10",
      ]);
      

      这适用于 php 中的 guzzle。

      【讨论】:

        【解决方案3】:

        对于 Guzzle6,我认为最好的方法是实现一个用于设置代理的中间件。

        来自 Guzzle6 文档:

        我们可以如下设置代理:

        use Psr\Http\Message\RequestInterface;
        use GuzzleHttp\HandlerStack;
        use GuzzleHttp\Handler\CurlHandler;
        use GuzzleHttp\Client;
        use GuzzleHttp\Middleware;
        use Util\Api;
        function add_proxy_callback($proxy_callback) {
            return function (callable $handler) use ($proxy_callback) {
                return function (RequestInterface $request,$options) use ($handler,$proxy_callback) {
                    $ip = $proxy_callback();
                    $options['proxy'] = $ip;
                    return $handler($request,$options);
                };
            };
        } 
        $stack = new HandlerStack();
        $stack->setHandler(new CurlHandler());
        $stack->push(add_proxy_callback(function() {
            return Api::getIp(); //function return a ip 
        }));
        $client = new Client(['handler'=>$stack]);
        $response = $client->request('GET','http://httpbin.org/ip');
        var_dump((string)$response->getBody());
        

        【讨论】:

          【解决方案4】:

          现在有同样的问题,我需要做的就是使用 curl 数组键作为常量而不是字符串..

          $response = $client->send($request, [
                        'timeout'  => 30,
                        'curl'  => [
                            CURLOPT_PROXY => '*.*.*.*',
                            CURLOPT_PROXYPORT => *,
                            CURLOPT_PROXYUSERPWD => '*:*',
                       ],
                   ]);
          

          查看 CURL 选项 Keys ,它们不再是字符串了。

          【讨论】:

            【解决方案5】:

            psr-7 的过程可能会有所不同,但如果您使用的是 实例化客户端的标准方法,

            path\to\project\vendor\guzzlehttp\guzzle\src\Client.php, lines 164-170 包含读取环境变量的代码,以查看当前机器上是否设置了 HTTP_PROXY 和 HTTPS_PROXY,如果是,Guzzle 将使用这些值。

            此外,我必须设置我的 HTTPS_PROXY = http://ip:port(不是 https),因为我们的工作场所代理似乎通过 http 协议同时处理 https 和 http 请求。

            此配置的优点是您不必在源代码中更改代理设置。

            【讨论】:

            【解决方案6】:
            $response = \Drupal::httpClient()->post($settings['base_url'] . 'api/search/', [
                'verify' => true,
                'body' => $post_data,
                  'headers' => [
                    'Content-type' => 'application/json',
                  ],
                'curl' => [
                    CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2, 
                    CURLOPT_PROXY => 'proxyip:58080'],
                ]
              )->getBody()->getContents();
            

            在 Guzzle 和 SSL 中设置代理/https 完美运行。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-19
              • 2011-12-06
              • 2018-10-06
              • 2016-06-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多