【发布时间】:2011-04-23 00:00:46
【问题描述】:
我的代理服务器不允许直接连接到互联网。我所有的 PHP 应用程序都无法连接到互联网进行更新检查等。
如何告诉 PHP 我的代理设置?
我不想在代码中输入代理设置,我希望 PHP 本身通过全局配置设置或类似的方式使用它。
【问题讨论】:
我的代理服务器不允许直接连接到互联网。我所有的 PHP 应用程序都无法连接到互联网进行更新检查等。
如何告诉 PHP 我的代理设置?
我不想在代码中输入代理设置,我希望 PHP 本身通过全局配置设置或类似的方式使用它。
【问题讨论】:
如果几乎所有的互联网访问都需要代理,我更愿意这样做。
//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
【讨论】:
curl_setopt($handle, CURLOPT_PROXY, $proxy_url);,如果你同时使用,你可以同时添加两个。
stream_context_set_default(['http'=>['proxy'=>'proxy-host:proxy-port', 'header'=>'Proxy-Authorization: Basic '.base64_encode('your-username:your-password')]]);
Proxy-Authorization 标头,您可以在@pascal-martin 's answer 找到更多信息
这取决于您的 PHP 应用程序如何连接到 Internet。
如果最可能的情况是使用 PHP cUrl。在这种情况下,以下选项将为您提供帮助:
curl_setopt($handle, CURLOPT_PROXY, $proxy_url);
curl_setopt($handle, CURLOPT_PROXYUSERPWD, "[username]:[password]");
【讨论】:
示例代码:
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");
【讨论】:
是的,这是可能的!
您可以在一个文件中配置stream_context_set_default,并通过使用auto_prepend_file php.ini 属性将该文件包含在您的所有Php 程序中。
我写了一个小要点:
https://gist.github.com/ebuildy/381f116e9cd18216a69188ce0230708d
还有一篇法语文章:
这种技术很“酷”,因为它允许您的系统管理员配置主机,因此开发人员不必更改代码中的任何内容。
【讨论】:
curl_setopt。
我在 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 作为响应!
【讨论】:
我使用 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();
【讨论】:
【讨论】:
对于某些脚本,您只需设置环境变量HTTP_PROXY。 composer.phar 和 media-wiki 的维护/update.php 脚本都是这种情况。
例如:
setenv HTTP_PROXY http://1.2.3.4:3934
如果您的代理在 1.2.3.4 上侦听端口 3934。为我工作。
【讨论】: