php 在Skiddle上发出API请求时出错:301移动

jhkqcmku  于 2023-04-28  发布在  PHP
关注(0)|答案(2)|浏览(150)

我试图通过skiddle API请求事件,使用端点http://www.skiddle.com/api/v1/events/search/,但是当我尝试时,我得到了以下响应:

HTTP/1.1 301 Moved Permanently
Server: CloudFront
Date: Wed, 19 Apr 2023 14:21:19 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: https://www.skiddle.com/api/v1/events/search/?api_key=xxxxxx&latitude=51.509865&longitude=-0.118092&radius=30&keyword=trance&limit=100&offset=0
X-Cache: Redirect from cloudfront
Via: 1.1 3fff5cbe8229c22a8e7cfe60a8827a1e.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: LHR61-P6
Alt-Svc: h3=":443"; ma=86400
X-Amz-Cf-Id: SLXpElnGSXFF0oD360hjXiwDF2sqfuHD5LggX96rDlUaoHGecskp1Q==

下面是我的代码:

$skiddle = new Skiddle();
$rr = $skiddle->searchEvents('london','trance');
echo $rr->get();

class Locations
{
    public static $london = [
        'latitude'=>51.509865,
        'longitude'=>-0.118092,
        'radius'=>30
    ];
}
class Skiddle
{
    const EVENTS_SEARCH_URL = 'http://www.skiddle.com/api/v1/events/search/';
    const KEY = "xxxxxxx";
    public function __construct(){}
    public function searchEvents($location = "", $keyword = "")
    {
        $params = [
            'api_key' => self::KEY
        ];
        if ($location)
        {
            $params['latitude'] = Locations::$$location['latitude'];
            $params['longitude'] = Locations::$$location['longitude'];
            $params['radius'] = Locations::$$location['radius'];
        }
        if ($keyword)
        {
            $params['keyword'] = $keyword;
        }
        return new SkiddlePaginatedRequestResponse(
            self::EVENTS_SEARCH_URL,
            $params
        );
    }
}
class SkiddlePaginatedRequestResponse extends RequestResponse
{
    protected $limit;
    protected $offset;
    public function __construct($url, $params = [], $limit = 100, $offset = 0)
    {
        parent::__construct($url, $params);
        $this->limit = $limit;
        $this->offset = $offset;
    }
    public function get()
    {
        return parent::get();
    }
    public function nextPage()
    {
        return new SkiddlePaginatedRequestResponse(
            $this->url,
            $this->params,
            $this->limit,
            $this->offset + $this->limit
        );
    }
    protected function buildRequest()
    {
        parent::buildRequest();
        $this->request['limit'] = $this->limit;
        $this->request['offset'] = $this->offset;
    }
    protected function handleBadStatus($rawBody, $status, $headers)
    {
        $errorBody = json_decode($rawBody);
        if (isset($errorBody->errormessage) && isset($errorBody->error)) {
            // Error from the API
            fault("Skiddle error", $errorBody->errormessage."\n".$errorBody->error);
            die();
        } else {
            $this->dieHttpErrorFault($status, $headers);
        }
    }
}
class RequestResponse
{
    protected $params;
    protected $url;
    protected $request;
    protected $cookies = false;
    public function __construct($url, $params = [])
    {
        $this->params = $params;
        $this->url = $url;
    }
    public function setCookies($cookies)
    {
        //"mycookie1=value1; mycookie2=value2"
        $this->cookies = $cookies;
    }
    public function get()
    {
        $this->buildRequest();
        $url = $this->url . '?' . http_build_query($this->request);
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HEADER => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL => $url,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        if ($this->cookies) curl_setopt($ch, CURLOPT_COOKIE, $this->cookies);
        $response = curl_exec($ch);
        //$rawBody = curl_exec($ch);
        if (curl_error($ch))
        {
            fault('cURL transport error', curl_errno($ch).'\n'.curl_error($ch));
            die();
        }
        list($headers, $rawBody) = explode("\r\n\r\n", $response, 2);
        $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($status < 200 || $status > 299) {
            $this->handleBadStatus($rawBody, $status, $headers);
        }
        $object = json_decode($rawBody, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            fault('JSON parsing', "Error ".json_last_error_string()." (".json_last_error().")");
        }
        return $object;
    }
    protected function buildRequest()
    {
        $this->request = $this->params;
    }
    protected function handleBadStatus($rawBody, $status, $headers)
    {
        $this->dieHttpErrorFault($status, $headers);
    }
    protected function dieHttpErrorFault($status, $headers)
    {
        fault('HTTP error', "Code $status, \nHeaders:\n$headers");
        die();
    }
}

请指教谢谢

5rgfhyps

5rgfhyps1#

301表示已移动的资源(如果您喜欢,也可以重定向)。可能有几个原因,但我的猜测是,他们重定向您的http请求到https,所以解决方案将只是正确的URL使用https。或者,你可以像其他人建议的那样设置CURLOPT_FOLLOWLOCATION,但这不是最佳的,因为你将做两个请求,即使你现在知道第一个是静脉+你的第一个是未加密的。

**编辑:**我还注意到searchEvents()实现中的一个bug。这些行:

$params['latitude'] = Locations::$$location['latitude'];
$params['longitude'] = Locations::$$location['longitude'];
$params['radius'] = Locations::$$location['radius'];

我觉得你用的是可变变量($$)。我怀疑是复制-粘贴错误,所以我建议开始使用任何静态linter或至少更智能的IDE:)

hgqdbh6s

hgqdbh6s2#

一般来说,使用CURLOPT_FOLLOWLOCATIONhttps://www.php.net/manual/en/function.curl-setopt.php)选项使cURL自动跟随重定向。
在您的特定情况下,它似乎只是一个http://https://协议的重定向,您可以通过直接向https://版本发出请求来克服它。这将避免每次都提出两个请求。

相关问题