3

我正在尝试使用 REST API 和 PHP/cURL 更新一些自定义字段。

我想知道我是否可能在没有意识到的情况下编辑了某些内容,而我昨天在下面“工作”的内容(我认为)现在不起作用。

我使用不同的“方法”得到不同的响应,来自:

  1. 我使用 POST 方法得到这个,因为它在下面没有注释。

    HTTP 405 - 请求的资源 () 不允许指定的 HTTP 方法。

  2. 如果我使用注释掉的 PUT 方法,而 POST 被注释掉,我会得到这个。

    {"status-code":500,"message":"Read timed out"}
    
  3. 而这个混合和匹配 PUT 和 POST。

    {"errorMessages":["No content to map to Object due to end of input"]}
    

我错过了什么/做错了什么?我正在使用以下代码:

<?php

$username = 'username';
$password = 'password';

$url = "https://example.com/rest/api/2/issue/PROJ-827";
$ch = curl_init();

$headers = array(
    'Accept: application/json',
    'Content-Type: application/json'
);

$test = "This is the content of the custom field.";

$data = <<<JSON
{
    "fields": {
        "customfield_11334" : ["$test"]
    }
}
JSON;

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// Also tried, with the above two lines commented out...
// curl_setopt($ch, CURLOPT_PUT, 1);
// curl_setopt($ch, CURLOPT_INFILE, $data);
// curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");

$result = curl_exec($ch);
$ch_error = curl_error($ch);

if ($ch_error) {
    echo "cURL Error: $ch_error";
} else {
    echo $result;
}

curl_close($ch);

?> 
4

1 回答 1

8

这里的问题是 PHP 的 cURL API 不是特别直观。

您可能会认为,因为 POST 请求正文是使用以下选项发送的,所以 PUT 请求将以相同的方式完成:

// works for sending a POST request
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// DOES NOT work to send a PUT request
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_PUTFIELDS, $data);

相反,要发送 PUT 请求(带有关联的正文数据),您需要以下内容:

// The correct way to send a PUT request
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

请注意,即使您正在发送 PUT 请求,您仍然必须使用该CURLOPT_POSTFIELDS 选项来发送您的 PUT 请求正文。这是一个令人困惑且不一致的过程,但如果您想使用 PHP cURL 绑定,您就可以这样做。

根据相关的手动输入文档,该CURLOPT_PUT选项似乎仅适用于直接放置文件:

TRUE 以 HTTP PUT 文件。必须使用 CURLOPT_INFILE 和 CURLOPT_INFILESIZE 设置要 PUT 的文件。

恕我直言,更好的选择是使用自定义流包装器进行 HTTP 客户端操作。这带来了额外的好处,即不让您的应用程序依赖于底层的 libcurl 库。但是,这样的实现超出了这个问题的范围。如果您有兴趣开发流包装解决方案,Google 是您的朋友。

于 2012-07-29T19:46:33.550 回答