命令行cURL和PHP cURL之间的区别 [英] Difference between command line cURL and PHP cURL

查看:60
本文介绍了命令行cURL和PHP cURL之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似cURL的命令:

I have a cURL command like this:

curl 'https://www.example.com' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36' \
  -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' \
  -H 'accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'authority: www.example.com'

像在Mac上的终端应用程序中那样在命令行中执行此操作,结果将达到预期的输出.

Executing this in a command line like in Terminal app on my Mac, results to the expected output.

(如果您自己进行测试:如果此输出包含Sicherheitsüberprüfung字样,则表示该地理位置已被屏蔽,您必须使用德语IP对其进行测试.)

(In case you test it yourself: If this output contains the word Sicherheitsüberprüfung it's geo blocked and you have to use a German IP to test it.)

我将确切的命令这样传输到PHP cURL:

I transferred the exact command to PHP cURL like this:

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = array();
$headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
$headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
$headers[] = 'Authority: www.example.com';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>

运行此代码时,我收到一条消息,提示我的请求被识别为自动请求/机器人:它表示Sicherheitsüberprüfung,表示安全检查.

When I run this code I'm getting a message that my request was recognized as automated request/robot: It says Sicherheitsüberprüfung, means security check.

当然,我为命令行和PHP cURL请求使用了相同的IP.

Of course, I'm using the same IP for both, command line and PHP cURL request.

为什么呢?命令行cURL是否与PHP cURL相同?

Why that? Isn't command line cURL the same as PHP cURL?

或者我的PHP脚本有什么问题吗?

Or is there anything wrong with my PHP script?

更新

我很幸运地发现了以下内容:我在Mac上使用 Coda 作为代码编辑器.它具有内置的PHP渲染引擎.与我的PHP脚本一起使用时,结果是预期的.这与我在命令行中得到的结果相同.

I fortuitously found out the following: I'm using Coda as code editor on my Mac. This has a build-in PHP rendering engine. Using this with my PHP script, the result is as expected. It's the same result I'm getting in the command line.

更新2

我做了 Jannes Botis 在他的回答中建议的内容.然后,我在Coda代码编辑器应用程序中运行PHP脚本(输出预期结果),并以MAMP作为本地主机(始终被视为自动请求).

I made what Jannes Botis suggested in his answer. I then ran the PHP script in my Coda code editor app (what output the expected) and with MAMP as localhost (what is always recognized as automated request).

我发现用MAMP执行的代码使用的是 HTTP/2 ,而在Coda中执行的代码使用的是 HTTP/1.1 .为了解决这个问题,我在脚本中添加了以下内容:

I figured out that the the code executed with MAMP was using HTTP/2 while the code executed in Coda is using HTTP/1.1. To solve this, I added the following to the script:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

现在,两个输出都完全相同的字符串:

Now, both output exact the same string:

GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Authority: www.example.com

但是,还是一样:一个正在工作,另一个被认为是自动请求.

But, it's still the same: The one is working, the other is recognized as automated request.

推荐答案

在两种情况下都尝试调试请求:

Try to debug the request in both cases:

a)终端:使用curl

a) Terminal: use curl verbose mode: curl -v and check the http request sent, especially check the header list

b) php curl :使用测试不同的标头,使其起作用的原因是在请求中添加了"Pragma:no-cache"标头:

Testing the different headers, what made it work was adding "Pragma: no-cache" header to the request:

$headers[] = 'Pragma: no-cache';

另一方面,在终端curl中,我不得不将请求标头大写,例如用户代理等.

On the other hand, in terminal curl, I had to uppercase the request headers, e.g. User-Agent etc.

尝试使用 fsockopen 创建TCP连接:

Try to create a tcp connection with fsockopen:

$fp = fsockopen("ssl://"."www.example.com", 443, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $headers = array();
    $headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
    $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
    $headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
    $headers[] = 'Authority: www.example.com';
    $out .= $headers;
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 1024);
    }
    fclose($fp);

并测试是否可行.也许问题是php curl向http请求中添加了一些信息,或者问题是在tcp连接级别上,在此添加了一些信息.

and test if this works. Maybe the issue is either that php curl adds some info to the http request or the problem is on the tcp connection level, some info added there.

参考

这篇关于命令行cURL和PHP cURL之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆