8

我有一个类函数来与Last.FM的 RESTful API 交互——它的目的是为我的用户获取最新的曲目。这里是:

private static $base_url = 'http://ws.audioscrobbler.com/2.0/';

public static function getTopTracks($options = array())
{
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ), $options);

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init();
  curl_setopt_array($ch, array(
    CURLOPT_URL            => self::$base_url,
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

这返回"Empty reply from server"。我知道有些人认为这个错误来自网络基础设施的一些故障;在我的情况下,我不相信这是真的。如果我通过命令行运行 cURL 请求,我会得到我的数据;Last.FM 服务已启动并可访问。

在我去找那些人看看是否有任何变化之前,我想和你们好好谈谈,看看我的代码中是否存在导致这种情况的问题。

谢谢!

答案: @Jan Kuboschek 帮助我偶然发现了这里(可能)发生的事情。通过提供CURLOPT_POSTFIELDS关联数组,指定了可能不适用于某些 RESTful 服务的特定内容类型。更聪明的解决方案是手动创建该数据的 URL 编码版本并将其作为CURLOPT_POSTFIELDS.

有关更多信息,请查看:http ://www.brandonchecketts.com/archives/array-versus-string-in-curlopt_postfields

4

5 回答 5

12

一个常见问题是 URL 中的空格 - 开头、中间或结尾。你检查了吗?

编辑- 根据下面的评论,间距不是问题。

我运行了您的代码并遇到了同样的问题 - 没有任何输出。我尝试了 URL,并通过 GET 请求,服务器与我交谈。我会做以下事情:

  1. 使用以下作为 $base_url: $base_url = ' http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=xxx&method=user.getTopTracks ';

  2. 从您的请求中删除帖子字段。

编辑 我将您的代码移出课堂,因为我没有其余的并对其进行了修改。以下代码对我来说运行完美。如果这些更改对您不起作用,我建议您的错误出在不同的函数中。

<?php


function getTopTracks()
{
  $base_url = 'http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=8066d2ebfbf1e1a8d1c32c84cf65c91c&method=user.getTopTracks';
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ));

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => $base_url,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

echo getTopTracks();

?>
于 2010-06-10T20:55:24.757 回答
8

服务器收到您的请求,但发送了一个空响应。检查结果curl_getinfo($ch, CURLINFO_HTTP_CODE)以了解服务器是否以 HTTP 错误代码响应。

更新:好的,因此服务器使用100 ContinueHTTP 状态代码进行响应。在这种情况下,这应该可以解决您的问题:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

我在这里找到了这个:PHP and cURL: Disabling 100-continue header。希望它有效!

于 2010-06-10T21:15:59.037 回答
1

我遇到了同样的问题。我的 Http_code 返回 200 但我的响应是空的。正如我所经历的那样,这可能有很多原因。

--您的 hedaers 可能不正确

CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:')

--您可能需要将数据作为 culr 中的 post 字段发送,而不是像url?p1=a1&p2=a2这样附加到 URl

$data = array (p1=>a1, p2=>a2)
CURLOPT_POSTFIELDS => $data

所以你的选项数组将类似于下面

array(
    CURLOPT_URL => $url,
    CURLOPT_FAILONERROR => TRUE, // FALSE if in debug mode
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 4,
    CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:'),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $data,
);
于 2013-08-21T05:14:40.313 回答
0

根据 Last.FM API 文档,您应该使用 GET 方法而不是 POST 来传递参数。当我将 POST 更改为 GET 时,我收到了关于不正确密钥的答案。

于 2010-06-10T21:35:27.327 回答
0

这是从 Laft.FM获取专辑信息的代码,即使返回错误:

功能:

function getAlbum($xml,$artist,$album)
{
  $base_url = $xml;
  $options = array_merge(array(
    'user' => 'YOUR_USERNAME',
    'artist'=>$artist,
    'album'=>$album,
    'period' => NULL,
    'api_key' => 'xYxOxUxRxxAxPxIxxKxExYxx', 
  ));

  $options['method'] = 'album.getinfo';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => 'http://ws.audioscrobbler.com/2.0/',
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_HTTPHEADER        => array( 'Expect:' ) ,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  unset ($options);
  return $results;
}

用法:

// Get the XML
$xml_error = getAlbum($xml,$artist,$album);

// Show XML error
if (preg_match("/error/i", $xml_error)) {
    echo " <strong>ERRO:</strong> ".trim(strip_tags($xml_error));
}
于 2011-05-05T17:00:18.900 回答