【问题标题】:Coop API - posting with PHPCoop API - 使用 PHP 发布
【发布时间】:2011-04-18 23:13:50
【问题描述】:

我正在尝试使用 CURL 及其 API 向 Web 服务发布一个简单的帖子,但我收到了 422 响应。我的代码如下:

include 'CurlRequest.php';

$secret_key = 'mykeyhere';
$group_id = 'group_id';

$postData = array(
    'group_id' => $group_id,
    'key' => $secret_key,
    'status' => 'test'
);

$curl = new CurlRequest('http://coopapp.com/statuses/update.json');
$curl->exec(array(
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($postData)
));

我正在使用现有的 Curl 库来处理帖子。我确定这与我格式化 POST url 的方式(我尝试了很多不同的方式)或我发布数据的方式有关。

他们的文档在这里:http://coopapp.com/api/statuses

谢谢!

【问题讨论】:

  • 422 为错误码,通常在请求有效时使用,但因某些内部约束无法处理。查看响应的正文,其中可能包含有关问题的详细信息。
  • 尝试将 json_encode($postData) 替换为 http_build_query($postData)。可能有帮助,也可能没有。

标签: php xml json api curl


【解决方案1】:

对于这样的 API,HTTP 错误似乎很奇怪。

Co-Op API 文档有点……嗯……在状态更新方面令人困惑,因为它谈到了 POST 数据,但该示例显示了一个查询字符串。您可以做的是尝试将这些内容放入查询字符串中,或​​者不使用 CURL。 PHP 的 file_get_contents 实际上是一个可用的 HTTP 客户端,如果你传递足够多的参数的话。所以试试这个:

$params = array(
    'group_id' => $group_id,
    'secret_key' => $secret_key,
    'status' => 'test'
);
$context = stream_context_create(
   array(
    'http' => array(
     'method' => 'POST'
   ))
);
file_get_contents("http://coopapp.com/statuses/update.json?" .
   http_build_query($params), false, $context);

如果这不起作用,排除 CURL 错误,通过在没有 CURL 的情况下执行相同的操作:

$params = array(
    'group_id' => $group_id,
    'secret_key' => $secret_key,
    'status' => 'test'
);
$context = stream_context_create(
   array('http' => array(
     'method' => 'POST',
     'content' => http_build_query($params)      
   ))
);
file_get_contents("http://coopapp.com/statuses/update.json", false, $context);

请注意,我尚未测试代码,因此可能需要进行一些错误检查/修复。

【讨论】:

  • 好点。 HTTP 错误真的很奇怪 - 422 似乎通常是为 WebDAV 保留的,我敢打赌,状态码 The request was well-formed but was unable to be followed due to semantic errors. 的官方描述与 API 的意图不符。
  • 发布查询字符串应该不会让人感到困惑。这就是表单数据通常从浏览器发送的方式,并且许多 API 都以这种方式接受发布数据。
  • @GZipp:是的,我知道,但是如果没有帖子正文,为什么还要使用 POST?如果你使用 POST,很多程序员会尝试将变量作为 post body 传递,因为大多数时候参数是在 post 中传递的。因此 -> 理解错误的空间。
  • 没有争论,我承认我自己对文档和您的代码感到困惑。正如您所说,您的第二个示例与第一个示例不同。它将在请求正文中发送查询字符串,即使文档似乎表明它应该在 uri a la GET 中。 (如果您的第一个示例不适用于 op,那么在我看来,api 已损坏或文档有误。)
  • 很好的演示了 file_get_contents() 的灵活性,顺便说一句,虽然 'http' 上下文参数需要包装在一个数组中。 :)
【解决方案2】:

解决方案是缺少content-type'application/json'

这是工作代码:

include 'CurlRequest.php';

$key = 'mykeyhere';
$group_id = '1234';

$status = 'Awesome status update';

$curl = new CurlRequest('http://coopapp.com/statuses/update.xml?group_id=' . $group_id . '&key=' . $key);
$curl->exec(array(
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode(array('status' => $status)),
    CURLOPT_HTTPHEADER => array("Content-Type: application/json")
 ));

【讨论】:

    【解决方案3】:

    这是来自 api 页面的引用

    发布 /statuses/update.xml?group_id=#{group_id}&status=An%20encoded%20status&key=#{secret_key}

    它应该是 key 而不是 secret_key

    $postData = array(
        'group_id' => $group_id,
        'key' => $secret_key,
        'status' => 'test'
    );
    

    【讨论】:

    • 很好的通话 - 修复了这个问题,但仍然得到相同的响应代码。
    【解决方案4】:

    我认为您不应该json_decode() POSTFIELDS 数据,对吗?响应将是 JSON,但输入应为 POST 字段。根据manual

    要在 HTTP“POST”操作中发布的完整数据。要发布文件,请在文件名前加上 @ 并使用完整路径。这可以作为 urlencoded 字符串传递,如 'para1=val1&para2=val2&...' 或作为字段名称作为键和字段数据作为值的数组。如果 value 是一个数组,则 Content-Type 标头将设置为 multipart/form-data。

    这应该可行:

    $curl = new CurlRequest('http://coopapp.com/statuses/update.json');
    $curl->exec(array(
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => $postData
    ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多