file_get_contents 通过 php 失败,通过浏览器工作

use*_*601 5 php curl timeout simplexml file-get-contents

我想要实现的目标:
\n向 API 端点发出请求,检索 XML 并随后解析结果。
\n我正在发送一个file_get_contents请求来实现此目的。

\n\n

问题:

\n\n
`file_get_Contents` fails, error:  \n\nWarning: file_get_contents(https://api.twitter.com/1.1/statuses/mentions_timeline.json):\nfailed to open stream: \n        A connection attempt failed because the connected party did not properly \nrespond after a period of time, or established connection failed because \nconnected host has failed to respond. \n
Run Code Online (Sandbox Code Playgroud)\n\n

更新 17/08

\n\n

为了巩固我目前的理解:
\n 1. PHP 失败:
\n1.a 它通过 php (超时)失败
\n1.b 它通过命令行失败(curl -G http://api.eve-central.com/api /quicklook?typeid=34 )
\n1.c file_get_contents
\n1.d file_get_contents w/ create_stream_context

\n\n

2. 有效方法:
\n2.a 通过 postman 将 url 粘贴到 chrome 选项卡中
\n2.b

\n\n

已尝试的内容: \n- 检查 Postman 中的标头,并尝试通过 php 复制它们

\n\n
Postman Headers sent back by eve-central:\nAccess-Control-Allow-Origin \xe2\x86\x92 *  \nConnection \xe2\x86\x92 Keep-Alive  \nContent-Encoding \xe2\x86\x92 gzip  \nContent-Type \xe2\x86\x92 text/xml; charset=UTF-8  \nDate \xe2\x86\x92 Wed, 17 Aug 2016 10:40:24 GMT  \nProxy-Connection \xe2\x86\x92 Keep-Alive  \nServer \xe2\x86\x92 nginx  \nTransfer-Encoding \xe2\x86\x92 chunked  \nVary \xe2\x86\x92 Accept-Encoding  \nVia \xe2\x86\x92 HTTP/1.1 proxy10014\n
Run Code Online (Sandbox Code Playgroud)\n\n

对应代码:

\n\n
$headers = array(     \n\'method\'  => \'GET\',        \n\'header\'  => \'Connection: Keep-Alive\', \n\'header\'  => \'Content-Encoding: gzip\', \n\'header\'  => \'Content-Type: text/xml\',\n\'header\'  => \'Proxy-Connection: Keep-Alive\', \n\'header\'  => \'Server: nginx\', \n\'header\'  => \'Transfer-Encoding: chunked\', \n\'header\'  => \'Vary: Accept-Encoding\', \n\'header\'  => \'Via: HTTP/1.1 proxy10014\');\ncurl_setopt($curl, CURLOPT_HTTPHEADER, $headers); \ncurl_setopt($curl, CURLOPT_RETURNTRANSFER, true );\ncurl_setopt($curl, CURLOPT_PORT , 8080); // Attempt at changing port in the event it was blocked.\ncurl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);\ncurl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);\ncurl_setopt($curl, CURLOPT_POST,           false );            \ncurl_setopt($curl, CURLOPT_URL,            $url );   \n\n$resp = curl_exec($curl);\nif(curl_error($curl))\n{\necho \'error:\' . curl_error($curl);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  • 使用 Wireshark 捕获 GET 请求以查看更改端口是否有帮助
  • \n
  • 通过命令行运行 cUrl
    \n我没有想法和选项。\n所以问题是:\n\n
      \n
    1. 如果它在浏览器和 Postman 中工作,为什么它不能通过 PHP 工作?
    2. \n
    3. 如何修改我的代码以模仿 Postman 的功能??
    4. \n
  • \n
\n\n

以前的尝试\n我尝试过的: \n来自其他线程的各种 cURL 选项,例如

\n\n
function curl_get_contents($url) { \n$ch = curl_init();\nif (!$ch) \n{\ndie("Couldn\'t initialize a cURL handle");\n} else\necho "Curl Handle initialized ";\ncurl_setopt($ch, CURLOPT_URL, $url);\ncurl_setopt($ch, CURLOPT_USERAGENT, \'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)\');\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\ncurl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);\ncurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\ncurl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);\ncurl_setopt($ch, CURLOPT_TIMEOUT, 5);\n$data = curl_exec($ch);\n// Check if any error occurred\nif (!curl_errno($ch)) \n{\n$info = curl_getinfo($ch);\necho \'Took \', $info[\'total_time\'], \' seconds to send a request to \', $info[\'url\'], "";\ndisplayData($info);\n} else\necho "Failed Curl, reason: ".curl_error($ch)." ";\ncurl_close($ch);\nreturn $data;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:什么都没有,没有返回数据。
\n-检查 php.ini 选项:
\n-allow_fopen 已打开
\n-allow_url_include = on
\n- 已启用相关 ssl 扩展
\n-提高超时窗口
\n- 均通过 php.ini
\n- 也通过显式php 文件中的声明。
\n-尝试使用不同的 url
\n- 相同的错误,因此它并不真正取决于我的特定端点
\n- 例如,twitter/wikipedia/google 都返回特定错误\n-尝试过:
\n - 本地 xml 文件 ( https://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx ) 上的 file_get_contents -->在远程 xml 文件 ( http )上运行\n- file_get_contents ://www.xmlfiles.com/examples/note.xml ) -->失败同样的错误\n-总体而言,到目前为止,以下情况正确: \n- Curl 失败,超时\n- file_get_Contents 失败,超时\n - 在浏览器中打开 XML 文件 url 有效\n- 通过 Postman 发出 GET 请求,有效





\n\n

显然,在通过 php 失败的所有情况下file_get_contents,我都可以通过任何浏览器轻松访问该文件。

\n\n

试图解决这个问题。
\n尝试一:
\n使用 nitrous.io,创建 LAMP 堆栈,通过平台执行操作\n结果:file_get_contents 可以工作,但由于要检索的 xml 文件较多,导致操作超时。\n暂定解决方案:
\n- 从源下载 XML 文件
\n- 压缩它们
\n- 下载 xml_file
\n- 本地解析所述 xml 文件
\n稍后,编写一个小的 php 脚本,在调用时执行上述位,将数据发送到本地目录,然后将其解压并对其执行其他工作。
\n另一种尝试是使用 Google Sheets,通过用户函数将数据提取到工作表中,然后将 excel 文件/值转储到 mysql 中。
\n就我的目的而言,虽然这是一个非常无知的解决方案,但它确实有效。

\n\n

用于避免共享主机超时问题的代码:

\n\n
function downloadUrlToFile2($url, $outFileName)\n{\n    //file_put_contents($xmlFileName, fopen($link, \'r\'));\n    //copy($link, $xmlFileName); // download xml file\n    ;\n    echo "Passing $url into $outFileName ";\n    // $outFileName = touch();\n    $fp = fopen($outFileName, "w");\n    if(is_file($url)) \n    {\n        copy($url, $outFileName); // download xml file\n    } else \n        {\n            $ch = curl_init();\n            $options = array(\n            CURLOPT_TIMEOUT =>  28800, // set this to 8 hours so we dont timeout on big files\n            CURLOPT_URL     => $url\n        );\n\n            curl_setopt($ch, CURLOPT_FILE, $fp);\n            curl_setopt_array($ch, $options);\n            $contents = curl_exec($ch);\n            fwrite($fp, $contents);\n            curl_close($ch);\n        }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还在 ini 脚本之上添加了以下内容:

\n\n
ignore_user_abort(true);\nset_time_limit(0);\nini_set(\'memory_limit\', \'2048M\');\n
Run Code Online (Sandbox Code Playgroud)\n

Har*_*dja 3

我发现 HTTPS url 请求存在一些问题,要解决问题,您必须在 CURL 请求中添加以下行

function curl_get_contents($url) { 
    $ch = curl_init();
    $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
    $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 300";
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[] = "Accept-Language: en-us,en;q=0.5";
    $header[] = "Pragma: ";
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $header ); 

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);

    // I have added below two lines
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

    $data = curl_exec($ch);
    curl_close($ch);

    return $data;
}
Run Code Online (Sandbox Code Playgroud)