如何使用PHP cURL发送XML文件?

如何使用PHP cURL发送XML文件?,php,xml,curl,Php,Xml,Curl,这个问题在本帖中得到了回答: 但在我看来,这个答案并不是真正正确的答案,因为它只是展示了如何使用cURL发送XML代码。我需要发送一个XML文件 基本上,我需要将此C#代码转换为PHP: public Guid? UploadXmlFile() { var fileUploadClient = new WebClient(); fileUploadClient.Headers.Add("Content-Type", "application/xml"); fileUpl

这个问题在本帖中得到了回答:

但在我看来,这个答案并不是真正正确的答案,因为它只是展示了如何使用cURL发送XML代码。我需要发送一个XML文件

基本上,我需要将此C#代码转换为PHP:

public Guid? UploadXmlFile()
{
    var fileUploadClient = new WebClient();
    fileUploadClient.Headers.Add("Content-Type", "application/xml");
    fileUploadClient.Headers.Add("Authorization", "api " + ApiKey);

    var rawResponse = fileUploadClient.UploadFile(Url, FilePath);
    var stringResponse = Encoding.ASCII.GetString(rawResponse);

    var jsonResponse = JObject.Parse(stringResponse);
    if (jsonResponse != null)
    {
        var importFileId = jsonResponse.GetValue("ImportId");
        if (importFileId != null)
        {
            return new Guid(importFileId.ToString());
        }
    }
    return null;
}
我试过几种方法,这是我最近的一次尝试

cURL调用:

/**
 * CDON API Call
 *
 */
function cdon_api($way, $method, $postfields=false, $contenttype=false)
{
    global $api_key;

    $contenttype = (!$contenttype) ? 'application/x-www-form-urlencoded' : $contenttype;

    $curlOpts = array(
        CURLOPT_URL => 'https://admin.marketplace.cdon.com/api/'.$method,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_TIMEOUT => 60,
        CURLOPT_HTTPHEADER => array('Authorization: api '.$api_key, 'Content-type: '.$contenttype, 'Accept: application/xml')
    );

        if ($way == 'post')
        {
            $curlOpts[CURLOPT_POST] = TRUE;
        }
        elseif ($way == 'put')
        {
            $curlOpts[CURLOPT_PUT] = TRUE;
        }

        if ($postfields !== false)
        {
            $curlOpts[CURLOPT_POSTFIELDS] = $postfields;
        }

    # make the call
    $ch = curl_init();
    curl_setopt_array($ch, $curlOpts);
    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}
/**
 * Export products
 *
 */
function cdon_export()
{
    global $api_key;

    $upload_dir = wp_upload_dir();
    $filepath = $upload_dir['basedir'] . '/cdon-feed.xml';

    $response = cdon_api('post', 'importfile', array('uploaded_file' => '@/'.realpath($filepath).';type=text/xml'), 'multipart/form-data');

    echo '<br>Response 1: <pre>'.print_r(json_decode($response), true).'</pre><br>';

    $data = json_decode($response, true);

        if (!empty($data['ImportId']))
        {
            $response = cdon_api('put', 'importfile?importFileId='.$data['ImportId'], false, 'text/xml');

            echo 'Response 2: <pre>'.print_r(json_decode($response), true).'</pre><br>';

            $data = json_decode($response, true);
        }
}
文件导出:

/**
 * CDON API Call
 *
 */
function cdon_api($way, $method, $postfields=false, $contenttype=false)
{
    global $api_key;

    $contenttype = (!$contenttype) ? 'application/x-www-form-urlencoded' : $contenttype;

    $curlOpts = array(
        CURLOPT_URL => 'https://admin.marketplace.cdon.com/api/'.$method,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_TIMEOUT => 60,
        CURLOPT_HTTPHEADER => array('Authorization: api '.$api_key, 'Content-type: '.$contenttype, 'Accept: application/xml')
    );

        if ($way == 'post')
        {
            $curlOpts[CURLOPT_POST] = TRUE;
        }
        elseif ($way == 'put')
        {
            $curlOpts[CURLOPT_PUT] = TRUE;
        }

        if ($postfields !== false)
        {
            $curlOpts[CURLOPT_POSTFIELDS] = $postfields;
        }

    # make the call
    $ch = curl_init();
    curl_setopt_array($ch, $curlOpts);
    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}
/**
 * Export products
 *
 */
function cdon_export()
{
    global $api_key;

    $upload_dir = wp_upload_dir();
    $filepath = $upload_dir['basedir'] . '/cdon-feed.xml';

    $response = cdon_api('post', 'importfile', array('uploaded_file' => '@/'.realpath($filepath).';type=text/xml'), 'multipart/form-data');

    echo '<br>Response 1: <pre>'.print_r(json_decode($response), true).'</pre><br>';

    $data = json_decode($response, true);

        if (!empty($data['ImportId']))
        {
            $response = cdon_api('put', 'importfile?importFileId='.$data['ImportId'], false, 'text/xml');

            echo 'Response 2: <pre>'.print_r(json_decode($response), true).'</pre><br>';

            $data = json_decode($response, true);
        }
}
/**
*出口产品
*
*/
函数CDU导出()
{
全球$api_密钥;
$upload_dir=wp_upload_dir();
$filepath=$upload_dir['basedir']./cdon feed.xml';
$response=cdon_-api('post','importfile',array('uploaded_-file'=>'@/'.realpath('filepath.);type=text/xml'),'multipart/form data');
回显“
响应1:”。打印(json解码($Response),true)。“
”;
function UploadXmlFile(): ?string {
    $ch = curl_init ( $url );
    curl_setopt_array ( $ch, array (
            CURLOPT_POST => 1,
            CURLOPT_HTTPHEADER => array (
                    "Content-Type: application/xml",
                    "Authorization: api " . $ApiKey 
            ),
            CURLOPT_POSTFIELDS => file_get_contents ( $filepath ),
            CURLOPT_RETURNTRANSFER => true 
    ) );
    $jsonResponse = json_decode ( ($response = curl_exec ( $ch )) );
    curl_close ( $ch );
    return $jsonResponse->importId ?? NULL;
}
$data=json_decode($response,true); 如果(!empty($data['ImportId'])) { $response=cdon_api('put','importfile?importFileId='。$data['ImportId'],false,'text/xml'); 回显“响应2:”。打印(json解码($Response),true)。”
; $data=json_decode($response,true); } }
但我得到的结果是:


答复1:

stdClass对象 ( [消息]=>请求不包含有效的媒体类型。 )


我在不同的地方尝试了不同的类型,
application/xml
multipart/formdata
text/xml
,但都不起作用

我该怎么做才能让它工作?如何使用cURL发送XML文件?

对我来说,C代码似乎只是做了与


但至少有一个区别,您的PHP代码添加了标题
'Accept:application/xml'
,您的C代码与PHP手册
“CURLOPT#u POSTFIELDS:在HTTP“post”操作中发布的完整数据不一致。要发布文件,请在文件名前面加上@并使用完整路径。”
@RamRaider Yes,正如您所看到的,这正是我所做的。但是它不起作用。@RamRaider该@方法在几年前就被弃用了,在5.5中变得不可靠,在5.6中甚至更不可靠,在7.0中完全停止工作,使用CURLFile而不是@hanshenrik-我不知道,我仍然有php 5.3.2,因此从未在手册中阅读过:(也许是时候升级了,
$response
现在是空的。它应该包含json数据。我同意。诀窍是将CURLOPT_POSTFIELD设置为字符串,这样cURL就不会像其他方式那样尝试查看内容类型(并允许您使用正确的
应用程序/xml
内容类型)。不久前,我不得不对SOAP客户端执行同样的操作,这是一个主要的绊脚石。我将其添加为字符串,现在我得到
请求不包含有效的多部分内容。
无论我做什么…@PeterWesterlund那么,这是api服务器的一个错误,请在发送头
内容类型:applic时让api开发人员知道当调用uploadFile时,服务器试图将其解析为
内容类型:多部分/表单数据
。但这也意味着
fileUploadClient
会在调用uploadFile时默默地覆盖内容类型头,这有点糟糕,它至少会生成一个警告。最后,这意味着您必须将curl代码修改为trans以
multipart/form data
格式传递文件,因此删除
Content-Type:application/xml
头和@PeterWesterlund(太长,无法评论)并将
CURLOPT\u POSTFIELDS=>file\u get\u contents($filepath)
替换为
CURLOPT\u POSTFIELDS=>数组(新的CURLFile($filepath))
-现在curl将以多部分/表单数据格式上传xml