PHP curl问题 - 如果使用变量作为URL,则出错,但字符串工作正常

时间:2016-12-22 14:17:49

标签: php curl

我在php中有一个非常奇怪的卷曲问题。当我将URL作为变量传入时,请求将返回400错误,说“错误请求 - 缺少要约ID cookie”。

但是如果将URL硬编码到代码中而不是传递变量,那么它可以正常工作!

这是我的代码 -

            function resolveURL($url) {

                $ch = curl_init("$url");  
                echo var_dump("$url");

                curl_setopt($ch, CURLOPT_HEADER, 1); 
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); 
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
                $results = curl_exec($ch); 
                curl_close($ch); 

                echo var_dump($results);
            }

$ url的var_dump返回 - string(104) "http://click.linksynergy.com/fs-bin/click?id=SN4dmHdm/i8&offerid=462146.45&type=3&subid=0"

$ results的var_dump返回

string(319) "HTTP/1.1 400 Bad Request Server: Apache-Coyote/1.1 Content-Length: 187 Date: Thu, 22 Dec 2016 14:14:38 GMT Connection: close Missing offer id cookie "

但如果我对上面的代码做了一处更改 -

$ch = curl_init("http://click.linksynergy.com/fs-bin/click?id=SN4dmHdm/i8&offerid=462146.45&type=3&subid=0");

然后$ results返回我期望的完整数据 -

string(1125) "HTTP/1.1 302 Found Server: Apache-Coyote/1.1 Set-Cookie: lsn_statp=SSUMBwoAAAAlJc5KdQpJiw%3D%3D; Domain=.linksynergy.com; Expires=Wed, 17-Dec-2036 14:16:14 GMT; Path=/ Set-Cookie: rmuid=e431e402-a482-4611-a78a-71aa74f859f5; Domain=.linksynergy.com; Expires=Fri, 22-Dec-2017 14:16:14 GMT; Path=/ Set-Cookie: lsn_qstring=SN4dmHdm%2Fi8%3A462146%3A; Domain=.linksynergy.com; Expires=Fri, 23-Dec-2016 14:16:14 GMT; Path=/ Set-Cookie: lsn_track=UmFuZG9tSVZDI%2Bw8hSY%2BdfkMlwCUwBvtWwSdxm0SOqHNgxhyQqiQeQ0nwzwxomWBIzUbWVW%2Ft7lFTQ3k3hZXdQ%3D%3D; Domain=.linksynergy.com; Expires=Sun, 20-Dec-2026 14:16:14 GMT; Path=/ Set-Cookie: lsclick_mid38366="2016-12-22 14:16:14.418|SN4dmHdm_i8-R8CHpEfhXw637RnHirbegw"; Version=1; Domain=.linksynergy.com; Max-Age=63072000; Expires=Sat, 22-Dec-2018 14:16:14 GMT; Path=/ P3P: policyref="/w3c/p3p.xml", CP="NOI DSP COR CURa ADMa DEVa OUR BUS STA" Expires: Thu, 01 Jan 1970 00:00:00 GMT Date: Thu, 22 Dec 2016 14:16:14 GMT Cache-Control: no-cache Pragma: no-cache Location: http://www.daskeyboard.com/?siteID=SN4dmHdm_i8-R8CHpEfhXw637RnHirbegw Content-Length: 0 Connection: close "

为什么会这样?我认为由于某种原因,当我将URL作为变量留下时,第一个&之后的所有内容都被剥离了,但我无法解释原因。

我尝试通过urlencode()htmlentities()htmlspecialchars()运行$ url,但我仍然得到相同的结果。我尝试过$url而不是"$url",而且没有任何问题可以解决问题。

更新:当我在设置URL后执行echo var_dump(curl_getinfo($ch));时,看起来字符串的长度在某种程度上比传入$url时的长度要长,但在使用时是正确的长度硬编码的字符串。结果如下 -

//$url
`array(21) { ["url"]=> string(104) "http://click.linksynergy.com/fs-bin/click?id=SN4dmHdm/i8&offerid=462146.45&type=3&subid=0" ["content_type"]=> NULL ["http_code"]=> int(0) ["header_size"]=> int(0) ["request_size"]=> int(0) ["filetime"]=> int(0) ["ssl_verify_result"]=> int(0) ["redirect_count"]=> int(0) ["total_time"]=> float(0) ["namelookup_time"]=> float(0) ["connect_time"]=> float(0) ["pretransfer_time"]=> float(0) ["size_upload"]=> float(0) ["size_download"]=> float(0) ["speed_download"]=> float(0) ["speed_upload"]=> float(0) ["download_content_length"]=> float(-1) ["upload_content_length"]=> float(-1) ["starttransfer_time"]=> float(0) ["redirect_time"]=> float(0) ["certinfo"]=> array(0) { } } `

//hard-coded
`array(21) { ["url"]=> string(89) "http://click.linksynergy.com/fs-bin/click?id=SN4dmHdm/i8&offerid=462146.45&type=3&subid=0" ["content_type"]=> NULL ["http_code"]=> int(0) ["header_size"]=> int(0) ["request_size"]=> int(0) ["filetime"]=> int(0) ["ssl_verify_result"]=> int(0) ["redirect_count"]=> int(0) ["total_time"]=> float(0) ["namelookup_time"]=> float(0) ["connect_time"]=> float(0) ["pretransfer_time"]=> float(0) ["size_upload"]=> float(0) ["size_download"]=> float(0) ["speed_download"]=> float(0) ["speed_upload"]=> float(0) ["download_content_length"]=> float(-1) ["upload_content_length"]=> float(-1) ["starttransfer_time"]=> float(0) ["redirect_time"]=> float(0) ["certinfo"]=> array(0) { } } `

当我使用变量时,有人可以解释额外的15个字符的来源吗?

更新:在str_split上执行$url,我发现由于某种原因,有一个隐藏的'#038;'在我回显字符串时未显示的每个&之后的变量中。下面是数组返回的内容 -

[56]=> string(1) "&" [57]=> string(1) "#" [58]=> string(1) "0" [59]=> string(1) "3" [60]=> string(1) "8" [61]=> string(1) ";"

这就是修复它的原因..

$url= str_replace("#038;", "", $url);

3 个答案:

答案 0 :(得分:0)

尝试像这样组装:

$ch = curl_init();
   curl_setopt_array($ch, array(
   CURLOPT_RETURNTRANSFER => 1,
   CURLOPT_URL => $url,
   (the rest of your setopt array)
));

More info

答案 1 :(得分:0)

您需要对请求字符串的不同部分使用不同的编码。

对URL使用rawurlencode(),然后使用urlencode()为每个参数构造请求字符串:

$url = rawurlencode("http://click.linksynergy.com/fs-bin/click");

$params_urlencoded = array_map("urlencode", $params);
$getfields = "id=".$params_urlencoded['id']
            ."&offerid=".$params_urlencoded['offerid']
            ."&type=".$params_urlencoded['type']
            ."&subid=".$params_urlencoded['subid'];

$ch = curl_init($url.'?'.$getfields);

似乎你的&符号分隔参数名称被编码为特殊字符(&),因此在服务器上解析时会出现更多符号和错误的变量名称。

另外,阅读文档:)

B.2.2 Ampersands in URI attribute values

php urlencode

php rawurlencode

答案 2 :(得分:0)

故事的寓意 - 我假设因为我在浏览器中进行调试,我无法看到URL中的&符号是用"#038;"编码的,即使我是从php回应的。

显然,curl不适用于这些,因此解决方法是将它们从URL变量中删除 -

$url = str_replace("#038;", "", $url);

可以根据需要对URL进行编码。