【问题标题】:How to send an XML-file with PHP cURL?如何使用 PHP cURL 发送 XML 文件?
【发布时间】:2017-12-14 23:09:59
【问题描述】:

这个问题是市场在这个线程中回答的:

How to POST an XML file using cURL on php?

但在我看来,这个答案并不是真正的正确答案,因为它只是展示了如何使用 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);
        }
}

但我得到的输出是这样的:


响应 1:

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


我在不同的地方尝试了不同的类型,application/xmlmultipart/form-datatext/xml,但没有任何效果。

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

【问题讨论】:

  • 来自 PHP 手册 "CURLOPT_POSTFIELDS: The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with @ and use the full path."
  • @RamRaider 是的,正如您所见,我就是这样做的。但这行不通。
  • @RamRaider @ 方法在几年前就被弃用了,在 5.5 中变得不可靠,在 5.6 中更加不可靠,在 7.0 中完全停止工作,使用 CURLFile 代替 @
  • @hanshenrik - 我不知道,我还有 php 5.3.2,所以从来没有在手册中读过它:( 升级时间可能

标签: php xml curl


【解决方案1】:

在我看来,C# 代码的作用相当于

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;
}

但至少有1个区别,你的PHP代码添加了标题'Accept: application/xml',你的C#代码没有

【讨论】:

  • 嗯,$response 现在是空的。它应该包含 json 数据。
  • 我同意。诀窍是将 CURLOPT_POSTFIELD 设置为 string 以便 cURL 不会像其他方式那样尝试查看 Content-Type(并允许您使用正确的 application/xml Content-Type)。前段时间我不得不为 SOAP 客户端做同样的事情,这是一个主要的绊脚石。
  • 我将它添加为字符串,现在无论我做什么我都会得到The request does not contain a valid multipart content....
  • @PeterWesterlund 那么这是 api 服务器的错误,让 api 开发人员知道当您发送标头 Content-Type: application/xml 时,服务器会尝试将其解析为 Content-Type: Multipart/form-data。但这也意味着fileUploadClient 在调用uploadFile 时默默地覆盖了Content-Type 标头,这是一种很糟糕的行为,它至少应该生成一个警告.. 最后这意味着您必须修改curl 代码才能在@ 中传输文件987654329@ 格式,所以删除Content-Type: application/xml 标头,并且(评论太长)
  • @PeterWesterlund 并将 CURLOPT_POSTFIELDS =&gt; file_get_contents ( $filepath ) 替换为 CURLOPT_POSTFIELDS =&gt; array(new CURLFile($filepath)) - 现在 curl 将以 multipart/form-data 格式上传 xml
猜你喜欢
  • 1970-01-01
  • 2013-12-09
  • 2012-12-27
  • 2011-08-26
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
相关资源
最近更新 更多