PHP curl 奇怪的行为 PUT 与 POST

PHP curl strange behavior PUT vs. POST

我的一个项目包含一个基于 Web 的数据库的接口,我使用 curl 调用它。 使用 -X PUT 的 curl 将创建新记录,使用 -X POST 的 curl 将更新现有记录。 如果我使用 Advanced REST Client 执行此操作,它会正常工作。 如果我使用 PHP 脚本中的 curl_exec 调用来尝试此操作,则 POST 有效但 PUT 失败。 'Fails' 意味着,我得到一个 http 100 作为响应而不是 200 或 400。

$strXML = "<XML></XML>"; //valid XML here
$cURL = "https://www.webURL.here";
$cToken = "this_is_my_very_secret_token";
$ch = curl_init();

//POST

curl_setopt_array($ch, array(
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => "$strXML",
                CURLOPT_URL => $cURL,
                CURLOPT_HTTPHEADER => array("X-Auth-Token: $cToken","Content-Type:text/xml"),
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_VERBOSE => true
));
$strXMLEvents = curl_exec($ch);

PUT 调用看起来很相似:

// PUT
curl_setopt_array($ch, array(
                    CURLOPT_PUT => true,
                    CURLOPT_POSTFIELDS => "$strXML",
                    CURLOPT_URL => $cURL,
                    CURLOPT_HTTPHEADER  => array("X-Auth-Token: $cToken","Content-Type:text/xml","Content-Length: ".strlen($strXML)),
                    CURLOPT_RETURNTRANSFER  => true,
                    CURLOPT_VERBOSE     => true
));
$strXMLEvents = curl_exec($ch);

自从我在开发系统(win 10 PC)上遇到这个问题后,我想,这可能是原因。但是在我将代码部署到 Linux 网络服务器之后,行为保持不变...

由于使用 ARC 进行“手动”传输,我怀疑我的脚本中存在错误 - 但我找不到它。

来自手册:

CURLOPT_PUT

TRUE to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.

因为我们没有放置文件,所以 CURLOPT_PUT => true 试试 CURLOPT_CUSTOMREQUEST => "PUT"

// PUT
curl_setopt_array($ch, array(
                    CURLOPT_CUSTOMREQUEST => "PUT",
                    CURLOPT_POSTFIELDS => "$strXML",
                    CURLOPT_URL => $cURL,
                    CURLOPT_HTTPHEADER  => array("X-Auth-Token: $cToken","Content-Type:text/xml" /* ,"Content-Length: ".strlen($strXML) */ ),
                    CURLOPT_RETURNTRANSFER  => true,
                    CURLOPT_VERBOSE     => true
));
$strXMLEvents = curl_exec($ch);

这样我们只需将 HTTP 动词从 POST 更改为 PUT

我想,我明白了!

问题是,我试图将内容作为字符串发送。 当我将它作为文件发送时,它起作用了:

// PUT
$fXML=fopen($path2File,'r' ); // filestream with XML content
curl_setopt_array($ch, array(
                    CURLOPT_PUT => true,
                    CURLOPT_URL => $cURL,
                    CURLOPT_HTTPHEADER  => array("X-Auth-Token: $cToken","Content-Type:text/xml"),
                    CURLOPT_RETURNTRANSFER  => true,
                    CURLOPT_VERBOSE     => true,
                    CURLOPT_INFILESIZE =>strlen($strXML),
                    CURLOPT_INFILE => $fXML
));
$strXMLEvents = curl_exec($ch);