CakePHP2.0で配列をXMLに変換し出力する

notoです。

今回もまたCakePHP2.0を引っ張ります。 CakePHP2.0では、XMLヘルパーがなくなり、RSSヘルパーが追加されました。しかし、簡単なXML形式のレスポンスを返したいんだよ!と思い、すこし調べてみました。

動作環境

  • CakePHP 2.0.4
  • PHP 5.3.8
  • CentOS 5.6

XMLを出力する

まずはコードです。 xml用のレイアウトを作成します。

app/View/Layouts/xml/default.ctp
1
<?php echo $content_for_layout; ?>

XMLを出力するだけなので、ビューで渡されたデータをそのまま表示させます。

app/View/Layouts/xml/default.ctp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
class HogesController extends AppController{

    /**
    * コントローラー名
    * @var String
    */
    public $name = 'Hoges';

    /**
     * (non-PHPdoc)
     * @see Controller::beforeRender()
     */
    public function beforeRender(){
      Configure::write('debug', 0);
    }

    /**
     * 配列をxmlに変換する
     */
   public function index(){

      $bar = array('codelife' => array(
          'date'   => date("Ymd"),
          'member' => array(
                  'noto',
                  'sakemi',
                  'iyama'
              )
          )
      );

      App::uses('Xml', 'Utility');
      $xmlObject = Xml::fromArray($bar);
      $this->set('xmlString', $xmlObject->asXML());
    }
}

コアライブラリのXMLクラスを利用して配列をXMLオブジェクトへ変換します。 1.3との違いはドキュメントに記載しているコードがわかりやすいと思うので、引用します。

1
2
3
4
5
6
7
8
9
10
<?php
// Old method:
$xmlArray = array('root' => array('child' => 'value'));
$xmlObject = new Xml($xmlArray, array('format' => 'tags'));
$xmlString = $xmlObject->toString();

// New method:
$xmlArray = array('root' => array('child' => 'value'));
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags')); // You can use Xml::build() too
$xmlString = $xmlObject->asXML();

2.0ではXMLオブジェクトの静的メソッド「fromArray」に配列を渡すことで、SimpleXMLElementもしくはDOMDocumentを返却します。

デフォルトではSimpleXMLElementを返却しますので、DOMDocumentを返却させたい場合は、以下のようにオプションでDOMDocumentを返却するよう指定する必要があります。

1
$xmlObject = Xml::fromArray($bar,array('return' => 'domdocument'));

最後にビューになります。 コントローラーから渡されたデータを出力するだけですね。 ビューから先ほど作成したレイアウトを指定しています。

app/View/Hoges/index.ctp
1
2
3
<?php
$this->layout = 'xml/default';
echo $xmlString ;

実行結果

app/View/Hoges/index.ctp
1
2
<?xml version="1.0" encoding="UTF-8"?>
<codelife><date>20111206</date><member>noto</member><member>sakemi</member><member>iyama</member></codelife>

DOMDocument not foundが発生する場合

php-xmlをインストールしましょう。 XMLを出力する為に、この書き方でもいいのですがカッコ悪いので簡単なヘルパーを作成します。

XMLヘルパーの作成

app/View/Helper/XmlHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

App::uses('AppHelper', 'View/Helper');
App::uses('Xml', 'Utility');

/**
 * XMLHelper
 */

class XmlHelper extends AppHelper {

    /**
     * コンストラクタ
     * @param View $View
     * @param array $settings
     */
    public function __construct(View $View, $settings = array()) {
        $View->layout = 'xml/default';
        parent::__construct($View, $settings);
    }

    /**
     * 配列をXMLへ変換して返却する
     * @param array $data
     */
    public function render($data){
        $xmlObject = Xml::fromArray($data);
        return $xmlObject->asXML();
    }
}

レイアウトの指定と、配列からの変換はXMLヘルパーに任せます。

app/Controller/HogesController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
class HogesController extends AppController{

    /**
    * コントローラー名
    * @var String
    */
    public $name = 'Hoges';

    /**
     *  ヘルパー
     */
    public $helpers = array('Xml');

    /**
     * (non-PHPdoc)
     * @see Controller::beforeRender()
     */
    public function beforeRender(){
      Configure::write('debug', 0);
    }

    /**
     * XMLヘルパーを利用する。
     */
   public function index(){

      $bar = array('codelife' => array(
          'date'   => date("Ymd"),
          'member' => array(
                  'noto',
                  'sakemi',
                  'iyama'
              )
          )
      );

      $this->set(compact('bar'));
    }
}

先ほど作成したXMLヘルパーを指定します。変換処理はビューにお任せです。

app/View/Hoges/index.ctp**
1
2
<?php
echo $this->Xml->render($bar);

ビューではXMLヘルパーのrenderメソッドを呼ぶだけです。 最初のコードよりはスマートになりましたね。RSSヘルパーでも似たようなことができるかもしれないですが、未確認です。。。

ヘルパーをあまり作成したことがないので、間違いやこうしたほうがいいよ等コメント頂けたら幸いです。

Comments