use*_*601 5 php curl timeout simplexml file-get-contents
我想要实现的目标:
\n向 API 端点发出请求,检索 XML 并随后解析结果。
\n我正在发送一个file_get_contents请求来实现此目的。
问题:
\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. \nRun 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
2. 有效方法:
\n2.a 通过 postman 将 url 粘贴到 chrome 选项卡中
\n2.b
已尝试的内容: \n- 检查 Postman 中的标头,并尝试通过 php 复制它们
\n\nPostman 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\nRun 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}\nRun Code Online (Sandbox Code Playgroud)\n\n以前的尝试\n我尝试过的: \n来自其他线程的各种 cURL 选项,例如
\n\nfunction 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}\nRun 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 请求,有效
显然,在通过 php 失败的所有情况下file_get_contents,我都可以通过任何浏览器轻松访问该文件。
试图解决这个问题。
\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\nfunction 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}\nRun Code Online (Sandbox Code Playgroud)\n\n我还在 ini 脚本之上添加了以下内容:
\n\nignore_user_abort(true);\nset_time_limit(0);\nini_set(\'memory_limit\', \'2048M\');\nRun Code Online (Sandbox Code Playgroud)\n
我发现 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)