【问题标题】:How to have PHP to use Proxy Setting to connect to internet?如何让 PHP 使用代理设置来连接互联网?
【发布时间】:2011-04-23 00:00:46
【问题描述】:

我的代理服务器不允许直接连接到互联网。我所有的 PHP 应用程序都无法连接到互联网进行更新检查等。

如何告诉 PHP 我的代理设置?

我不想在代码中输入代理设置,我希望 PHP 本身通过全局配置设置或类似的方式使用它。

【问题讨论】:

    标签: php proxy


    【解决方案1】:

    如果几乎​​所有的互联网访问都需要代理,我更愿意这样做。

    //add this as the first line of the entry file may it is the index.php or config.php
    stream_context_set_default(['http'=>['proxy'=>'proxy-host:proxy-port']]);
    

    代理适用于file_get_contents,但不适用于curl_exec

    here is a official document.

    【讨论】:

    • 对不起,stream api 不影响curl,如果你使用curl,你最好设置curl_setopt($handle, CURLOPT_PROXY, $proxy_url);,如果你同时使用,你可以同时添加两个。
    • 我无法让它与有密码的代理服务器一起工作
    • @Tarik 如果您的代理服务器需要基本身份验证,您需要这样做stream_context_set_default(['http'=>['proxy'=>'proxy-host:proxy-port', 'header'=>'Proxy-Authorization: Basic '.base64_encode('your-username:your-password')]]);
    • @Tarik 关键是Proxy-Authorization 标头,您可以在@pascal-martin 's answer 找到更多信息
    • @IanHu 谢谢,我用这个代码找到了我的解决方案: '$curlProxy = array( 'http'=>array( 'method'=>"GET", 'header'=>"Proxy-授权:基本 AUTH_CODE_HERE==\r\n" . "Proxy-Connection: Keep-Alive", 'proxy'=>"IP_ADDRESS:PORT" ) );'
    【解决方案2】:

    这取决于您的 PHP 应用程序如何连接到 Internet。

    如果最可能的情况是使用 PHP cUrl。在这种情况下,以下选项将为您提供帮助:

    curl_setopt($handle, CURLOPT_PROXY, $proxy_url); 
    curl_setopt($handle, CURLOPT_PROXYUSERPWD, "[username]:[password]"); 
    

    另请参阅:http://www.php.net/manual/en/function.curl-setopt.php

    【讨论】:

    • 感谢您的回答。但考虑到这可能仅适用于我自己的代码。其他 PHP 应用程序(例如 Drupal)呢?我需要 PHP 本身通过代理连接而不是通过代码。
    【解决方案3】:

    示例代码:

    function getUrl($url)
    {
        $ch = curl_init(); 
        $timeout = 5; // set to zero for no timeout 
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
        curl_setopt ($ch, CURLOPT_URL, $url); 
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_PROXY, "http://proxy.example.com"); //your proxy url
        curl_setopt($ch, CURLOPT_PROXYPORT, "8080"); // your proxy port number 
        curl_setopt($ch, CURLOPT_PROXYUSERPWD, "username:pass"); //username:pass 
        $file_contents = curl_exec($ch); 
        curl_close($ch); 
        return $file_contents;
    }
    
    echo  getUrl("http://www.google.com");
    

    【讨论】:

      【解决方案4】:

      是的,这是可能的!

      您可以在一个文件中配置stream_context_set_default,并通过使用auto_prepend_file php.ini 属性将该文件包含在您的所有Php 程序中。

      我写了一个小要点:

      https://gist.github.com/ebuildy/381f116e9cd18216a69188ce0230708d

      还有一篇法语文章:

      https://medium.com/@thomasdecaux/param%C3%A9trer-par-d%C3%A9faut-un-proxy-pour-php-file-get-content-3e9a32416979#.6zbg605cx

      这种技术很“酷”,因为它允许您的系统管理员配置主机,因此开发人员不必更改代码中的任何内容。

      【讨论】:

      • 最明智的方法,虽然可能也需要curl_setopt
      【解决方案5】:

      我在 Internet 上进行了搜索,但没有找到任何关于 stream_context_set_default() 的信息以及 密码保护 代理服务器。

      然后我认为基本授权中的密码是在标头中发送的。 因此,我使用从 CURL 请求中提取的密码修改了标头,并且效果很好!!!

      您可以这样做:

      首先将此请求发送到任何域(example.com),如下所示:

      curl -v -U user:pass -x your_proxy_ip:port --url https://example.com
      

      查看 curl 发送的标头,我得到了这些代理行以供以后使用:

      >   Trying XXX.XXX.XXX.XXX...
      > Connected to XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX) port YYYY (#0)
      > Establish HTTP proxy tunnel to example.com:443
      > Proxy auth using Basic with user 'your_username_here'
      > CONNECT example.com:443 HTTP/1.1
      > Host: example.com:443
      > Proxy-Authorization: Basic YW1hem9uOnXXXXXXXXXXXXXXX25SMg
      > User-Agent: curl/7.47.0
      > Proxy-Connection: Keep-Alive
      >
      < HTTP/1.1 200 Connection established
      <
      < Proxy replied OK to CONNECT request
      

      好的,现在是时候构建我们​​的自定义标题了:

      $default_opts = array(
        'http'=>array(
          'method'=>"GET",
          'header'=>"Proxy-Authorization: Basic YW1hem9uOnXXXXXXXXXXXXXXX25SMg\r\n" .
                    "Proxy-Connection: Keep-Alive",
          'proxy'=>"XXX.XXX.XXX.XXX:YYYY"
        )
      );
      
      $default = stream_context_set_default($default_opts);
      
      
      $result = file_get_contents("https://ipleak.net/json/");
      print_r(json_decode($result));
      

      而且效果很好,您可以得到代理服务器的 IP 作为响应!

      【讨论】:

      【解决方案6】:

      我使用 PEAR HTTP_Request2 模块。

      这是我的 UrlOpen() 函数的简化版本:

      function UrlOpen($url)
      {
        $request = new HTTP_Request2($url);
      
        $request->setConfig(array(
          'proxy_host' => '192.168.1.6',
          'proxy_port' => 8080,
          'proxy_user' => 'MYUSER',
          'proxy_password' => 'MYPASS',
          'ssl_verify_peer' => False,
          'connect_timeout' => 3,
        );
      
        return $request;
      }
      
      $req = UrlOpen($url);
      $res = $req->send();
      if ($res->getStatus() == '200')
        $data = $request->getBody();
      

      【讨论】:

        【解决方案7】:

        对于 Drupal,您可以在 settings.php 文件中设置代理配置。

        $conf['proxy_server'] 等等。

        更多详情here

        【讨论】:

          【解决方案8】:

          对于某些脚本,您只需设置环境变量HTTP_PROXYcomposer.phar 和 media-wiki 的维护/update.php 脚本都是这种情况。

          例如:

          setenv HTTP_PROXY http://1.2.3.4:3934
          

          如果您的代理在 1.2.3.4 上侦听端口 3934。为我工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-04-11
            • 2013-07-24
            • 2017-04-23
            • 2014-01-29
            • 2015-07-12
            • 2014-08-08
            • 1970-01-01
            相关资源
            最近更新 更多