php file_get_contents和&

时间:2010-04-17 02:09:54

标签: php

我正在尝试使用php的file_get_content('a url');

问题是如果网址有'&'在其中,例如

file_get_contents('http://www.google.com/?var1=1&var2=2')

它会自动向www.google.com/?var1=1&var2=2

发出请求

如何防止这种情况发生?

7 个答案:

答案 0 :(得分:8)

我同意问题的原始海报。非常具体:

http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=301+E.+Linwood+Avenue++Turlock%2C+CA

这需要传递sensor = false变量,否则查询将返回Google的BAD结果。如果我通过file_get_contents传递此STRING,它(PHP file_get_contents)将替换“&”与"&"一样,谷歌不喜欢我:

Array
(
    [type] => 2
    [message] => file_get_contents(http://maps.googleapis.com/maps/api/geocode/json?address=301 E. Linwood Avenue  Turlock, CA&amp;sensor=false) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
)

所以这是我提出的解决方案,使用http_build_query

$myURL = 'http://maps.googleapis.com/maps/api/geocode/json?';   
        $options = array("address"=>$myAddress,"sensor"=>"false");
    $myURL .= http_build_query($options,'','&');

    $myData = file_get_contents($myURL) or die(print_r(error_get_last()));

我还包括我在PHP website上找到的代码(感谢Marco K.)使用PHP的自定义函数&lt; 5:

if (!function_exists('http_build_query')) { 
    function http_build_query($data, $prefix='', $sep='', $key='') { 
        $ret = array(); 
        foreach ((array)$data as $k => $v) { 
            if (is_int($k) && $prefix != null) { 
                $k = urlencode($prefix . $k); 
            } 
            if ((!empty($key)) || ($key === 0))  $k = $key.'['.urlencode($k).']'; 
            if (is_array($v) || is_object($v)) { 
                array_push($ret, http_build_query($v, '', $sep, $k)); 
            } else { 
                array_push($ret, $k.'='.urlencode($v)); 
            } 
        } 
        if (empty($sep)) $sep = ini_get('arg_separator.output'); 
        return implode($sep, $ret); 
    }// http_build_query 
}//if

答案 1 :(得分:2)

您应该尝试查看PHP中的CURL库,它们可以让您执行以下操作:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://mysite.com/file.php?blah=yar&test=blah");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);

然后,您可以从$ data获得结果。

答案 2 :(得分:1)

请尝试将简单引用'替换为双引号"

file_get_contents("http://www.google.com/?var1=1&var2=2")

看起来很奇怪,但有效!

答案 3 :(得分:0)

看起来你实际上有一个带“&amp; amp;”的字符串。您可能无法看到它,因为您只是在浏览器中显示输出。您应该使用浏览器源视图使html元素可见。

答案 4 :(得分:0)

问题很可能是PHP代码的一部分。我怀疑你认为发生的事情实际上并没有发生。

我怀疑你发布的代码可能不是你发布的代码,而是从变量中获取部分URL,例如:

$data = file_get_contents("http://example.com/?$myvariable");

将该变量回应到浏览器可能会隐藏您在上一步中无意中编码特殊字符的事实,因为在浏览器中有“&amp; amp;”看起来像“&amp;”。

你的file_get_contents()请求也可能正常工作,你认为编码&amp;的问题是什么?签名可能是其他地方的问题 - 发布实际的源代码可能有助于确定问题。

答案 5 :(得分:0)

在php.ini中尝试此配置

allow_url_fopen = On

如果使用https url,则必须配置

extension=php_openssl.dll

答案 6 :(得分:-1)

实际上,在查询字符串中使用&amp;作为字段分隔符并没有错。它完全是valid甚至是recommended by w3c。使用&的问题在于它与字符实体引用(形式为&xxx;)进行交互。

另外,请参阅PHP手册中关于url_encode()功能的说明:

  

注意变量   可以匹配HTML实体。像   &amp; amp,&amp; copy和&amp; pound被解析   浏览器和实际实体是   用来代替所需的变量   名称。这是一个明显的麻烦   W3C一直在告诉人们   多年。 PHP支持更改参数   隔离到W3C建议   通过arg_separator进行分号   .ini指令。最不幸的是   用户代理不发送表单数据   这种分号分隔格式。一个   更便携的方式是这个   使用&amp;代替&   分离器。

如果您真的不喜欢网址中的&amp;,我建议您检查php.ini文件中arg_separator指令的设置,尽管我不是100%肯定它会影响file_get_contents修改URL的方式