我的代码中有一个cURL请求,它在本地运行时运行良好:
$url = "http://ipinfo.io/{$_SERVER['REMOTE_ADDR']}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$locale = json_decode($response);
并按预期返回JSON。然而,我们的生产系统是在谷歌应用程序引擎上,在那里我可以获得浏览器的网站版本,而不是JSON。
如果我更改,我可以让这个cURL请求工作
google_app_engine.enable_curl_lite = "1"
在我的项目根目录中的php.ini
中
extension = "curl.so"
但谷歌的文件坚持前者将用于生产。此外,使用后者会破坏Monolog的SlackHandler等功能。
有没有一种方法可以在使用谷歌的"cURL Lite"的同时从这个cURL请求中获得JSON?
来自ipinfo.io文档:
"我们在服务器上做了一点魔术来确定我们应该发送JSON响应还是网页。我们通常做得很好,但如果你看到的是网页而不是JSON(或者想在浏览器中检查JSON输出),你可以通过在URL末尾添加/JSON来强制发送JSON响应"
在这种情况下,将/json
添加到URL的末尾对我有效,但我想要一个更通用的解决方案。由于谷歌的cURLLite在后台使用他们的URLFetch,ipinfo.io的"魔力"不知何故变得混乱起来。我发现,通过指定Accept
标头,就不需要添加/json
。在PHP中:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
感谢NashDev Slack的#php频道上的人们在这一点上帮助我!