【问题标题】:Avoid hardcoding XML in PHP for an API request避免在 PHP 中为 API 请求硬编码 XML
【发布时间】:2013-10-22 12:13:39
【问题描述】:

我正在使用 cURL 将以下 XML 发送到 api:

$xml = "<request type='auth' timestamp='$timestamp'>
                <merchantid>$merchantid</merchantid>
                <account>$account</account>
                <orderid>$orderid</orderid>
                <amount currency='$currency'>$amount</amount>
                <card> 
                    <number>$cardnumber</number>
                    <expdate>$expdate</expdate>
                    <type>$cardtype</type> 
                    <chname>$cardname</chname>

                </card> 
                <sha1hash>$sha1hash</sha1hash>
            </request>";

避免硬编码此 XML 的最佳方法是什么?我正在考虑使用 XMLWriter,但看起来很奇怪,因为它不会改变。

我应该使用模板吗?或者使用 XMLWriter / Simple XML 生成它?

【问题讨论】:

  • 你有选择,对此没有真正的正确答案:XMLwriterSimpleXMLDOMDocument,甚至只是你自己的String Appender .=
  • 你会推荐哪一个?
  • @MackieeE:字符串追加器不是一个真正的选择,因为这通常会产生编码问题。

标签: php xml api


【解决方案1】:

正如我在 cmets 中提到的,这不一定是正确的答案,但我最近也不得不围绕 XML API 提要编写一个项目。我决定使用XMLWriter,并且通过使用他们受人尊敬的.loadXML() 功能,它仍然非常很容易与其他人轻松交换。

class SomeApi extends XMLwriter {

    public function __construct() {
        $this->openMemory();
        $this->setIndent( true );
        $this->setIndentString ( "&#09;" );
        $this->startDocument( '1.0', 'UTF-8', 'no' );
        $this->startElement( 'root' );
    }

    public function addNode( $Name, $Contents ) {
        $this->startElement( $Name );
            $this->writeCData( $Contents ); 
        $this->endElement(); 
    }

   public function output() {
        $this->endElement();
        $this->endDocument();
   }

   //Returns a String of Xml.
   public function render() {
        return $this->outputMemory();
   }

}

$newRequest = new SomeApi();
$newRequest->addNode( 'some', 'Some Lots of Text' );
$Xml = $newRequest->render();

我认为用 PHP 编写 XML Feed 是一种非常干净的方式,此外,您还可以添加内部函数,例如:

$this->addHeader();

private function addHeader() {
   $this->addNode( 'login', 'xxxxx' );
   $this->addNode( 'password', 'xxxxx' );
}

然后添加您将反复使用的节点。然后,如果您突然需要使用 DOMDocument 对象,例如(我也需要 XSL)。

$Dom = new DOMDocument();
$Dom->loadXML( $Xml );

【讨论】:

  • 写入 CDATA?为了那个原因?很可能完全膨胀,我想知道你为什么这么建议。另外,您为什么要在 API 名称后面隐藏创建 XML 的责任? XML 最有可能在协议层中用于与远程端点进行通信。
【解决方案2】:

我应该使用模板吗?

您实际上已经在这里使用了模板。

或者使用 XMLWriter / Simple XML 生成它?

XMLWriterSimpleXMLElement 是允许您轻松创建 XML 的组件。对于您的具体情况,我将使用 SimpleXML 作为开始:

$xml = new SimpleXMLElement('<request type="auth"/>');
$xml['timestamp'] = $timestamp;

$xml->merchantid = $merchantid;
$xml->account    = $account;
$xml->orderid    = $orderid;
$xml->addChild('amount', $amount)['currency'] = $currency;

$card = $xml->addChild('card');
$card->number  = $cardnumber;
$card->expdate = $expdate;
$card->type    = $cardtype;
$card->chname  = $cardname;

$xml->sha1hash = $sha1hash;

请注意,XML 不再是硬编码的,只有使用的名称是硬编码的。 SimpleXML 库负责创建 XML(demo,此处的输出经过美化以提高可读性):

<?xml version="1.0"?>
<request type="auth" timestamp="">
  <merchantid></merchantid>
  <account></account>
  <orderid></orderid>
  <amount currency=""/>
  <card>
    <number></number>
    <expdate></expdate>
    <type></type>
    <chname></chname>
  </card>
  <sha1hash></sha1hash>
</request>

感谢库,输出始终是有效的 XML,您无需关心这里的细节。您可以通过对其进行更多包装来进一步简化它,但我认为这对于您这里拥有的非常小的 XML 没有多大用处。

【讨论】:

  • @Phpdna:对答案投票和对用户投票是有区别的。你不应该这样做。
  • 谢谢,与 XMLWriter 相比,使用 SimpleXML 有什么主要优势吗?我不确定要使用哪一个。
  • 您创建的 XML 块有多大?如果有问题,您可以在此处的答案中查看代码示例,我会说 SimpleXML 非常适合您的工作。 XMLWriter 的接口不是那么紧凑,也不是那么模块化。 DOMDocument 是另一种选择,但它的界面更加模块化,因为 SimpleXML 也更加冗长,所以我想说从 SimpleXML 开始这里是一个很好的入口。
  • XML 稍大一些,带有另一个嵌套元素。我快速尝试了您的示例,但 netbeans 似乎在抱怨这一行 $xml->addChild('amount', $amount)['currency'] = $currency;它说我的语言版本 (5.3) 不支持该语法?
  • 是的,那是 PHP 5.4。对于该变体,创建一个$amount 变量,就像使用$code 一样。然后在下一行使用$amount['currency'] = $currency;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 2022-10-31
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 2011-01-01
相关资源
最近更新 更多