westerndogの小屋

westerndogの小屋


- ほしいなぁと思って作ってみたWebサービスたちの開発Blog -

[ カテゴリー » develop ]

PHPでDOMを使って配列をXMLファイルにする

PHPでDOM(Document Object Model)を使用すると、文法的に正しい構造のXMLを、比較的容易に作成することができます。

XMLファイルの書き込みサンプル

makeXML.php

<?php
// 元データ
// 親ノードID(くっつき先)と子ノードID(自分)を含む
// 順番は問わない
// 木構造
// contents─1┬2─3
//           └4─5
$data = array(
  array(
    'parentId' => '',
    'childId' => '1',
    'comment' => 'comment1',
  ),
  array(
    'parentId' => '1',
    'childId' => '2',
    'comment' => 'comment1-1',
  ),
  array(
    'parentId' => '4',
    'childId' => '5',
    'comment' => 'comment1-2-1',
  ),
  array(
    'parentId' => '1',
    'childId' => '4',
    'comment' => 'comment1-2',
  ),
  array(
    'parentId' => '2',
    'childId' => '3',
    'comment' => 'comment1-1-1',
  ),
);

// 出力ファイル名
$fileName = 'comment.xml';

// DOMオブジェクト作成
$dom = new DomDocument('1.0');
$dom->encoding = "UTF-8";

// 出力XMLを改行
$dom->formatOutput = true;

// XML作成
$contents = $dom->appendChild($dom->createElement('contents'));

// 子ノードを追加
foreach($data as $array){
  $parentId = $array['parentId'];
  $childId = $array['childId'];

  // parentIdが無い場合contentsに付加
  if(empty($parentId)){
    $parentId = 'contents';
  }

  // 親ノードが無い場合
  if(empty($parentId)){
    $parentId = $dom->createElement('content');
  }

  // 子ノードが無い場合
  if(empty($childId)){
    $childId = $dom->createElement('content');
  }

  // 子ノードを付加
  $parentId->appendChild($childId);

  // 属性値を付加
  $childId->setAttribute('id', $childId);
  $childId->setAttribute('comment', $array['comment']);
}

//XMLを出力
file_put_contents($fileName, $dom->saveXML());
?>

実行例

$ php makeXML.php
$ cat comment.xml
<?xml version="1.0" encoding="UTF-8"?>
<contents>
  <content id="1" comment="comment1">
    <content id="2" comment="comment1-1">
      <content id="3" comment="comment1-1-1"/>
    </content>
    <content id="4" comment="comment1-2">
      <content id="5" comment="comment1-2-1"/>
    </content>
  </content>
</contents>

DOMの他の使い方は、DOMのリファレンスLink を参照してください。

— posted by westerndog at 01:37 am  

PHPでpear Configを使って配列をiniファイルにする

PHPのparse_ini_file関数を使用するとiniファイルを読み込むことができますが、その逆、配列をiniファイルにする手法を調べたところ、pearのConfigパッケージLink を使用すると楽にできることがわかりました。

準備

すでにpearがインストールされていて、pearへのパスが設定されているなら、パッケージを入れるだけです。

$ sudo pear install Config
Did not download optional dependencies: pear/XML_Parser, pear/XML_Util, use --alldeps to download automatically
pear/Config can optionally use package "pear/XML_Parser"
pear/Config can optionally use package "pear/XML_Util"
downloading Config-1.10.12.tgz ...
Starting to download Config-1.10.12.tgz (32,291 bytes)
.........done: 32,291 bytes
install ok: channel://pear.php.net/Config-1.10.12

Configで、iniファイルからXMLファイルへ、XMLファイルから配列へ、などの処理をしたい場合は、XML_Parserを追加インストールするとそれらの機能を使用できるようになります。今回はiniファイルの読み書きだけなので、スルーします。

iniファイルの書き込みサンプル

writeConfig.php

<?php
require_once ("Config.php");

$conf = array(
    'DB' => array(
        'type' => 'mysql',
        'host' => 'localhost',
        'user' => 'root',
        'pass' => 'root'
     ),
    'TT' => array(
        'encode' => 'sjis',
        'path' => './template'
     )
);

$config = new Config();

// 配列をパース
$root =& $config->parseConfig($conf, 'phparray', array('name' => 'conf'));
if( PEAR::isError( $root ) ) {
  die('配列読み込みエラー: ' . $root->getMessage());
}

// iniファイル書き込み
$root =& $config->writeConfig('conf.ini', 'inifile');
if( PEAR::isError( $root ) ) {
  die('設定書き込みエラー: ' . $root->getMessage());
}
?>

実行例

$ php writeConfig.php
$ cat conf.ini
[DB]
type=mysql
host=localhost
user=root
pass=root
[TT]
encode=sjis
path=./template

iniファイルの読み込みサンプル

parseConfig.php

<?php
require_once ("Config.php");

$config = new Config();

// iniファイル読み込み
$root =& $config->parseConfig('./conf.ini', 'inifile');
if( PEAR::isError( $root ) ) {
  die('設定読み込みエラー: ' . $root->getMessage());
}

// 配列作成
$array = $root->toArray();
print_r($array['root']);
?>

実行例

$ php parseConfig.php
Array
(
    [DB] => Array
        (
            [type] => mysql
            [host] => localhost
            [user] => root
            [pass] => root
        )

    [TT] => Array
        (
            [encode] => sjis
            [path] => ./template
        )

)

Configパッケージの他の使い方は、ConfigマニュアルページLink を参照してください。

— posted by westerndog at 02:06 pm  

さくらインターネットのレンタルサーバにsvnをインストール

さくらのレンタルサーバのプレミアムプランを借りています。SVNをインストールしたので、そのときの記録です。こちらのサイトLink を参考にインストールさせていただきました。

  • サーバOS:FreeBSD 7.1-RELEASE-p15
  • subversion:1.6.16(2011/03/04リリース)
  • インストール

    $ mkdir -p ~/local/src/svn
    $ wget http://subversion.tigris.org/downloads/subversion-1.6.16.tar.gzLink 
    $ wget http://subversion.tigris.org/downloads/subversion-deps-1.6.16.tar.gzLink 
    
    $ tar zxvf subversion-1.6.16.tar.gz
    $ tar zxvf subversion-deps-1.6.16.tar.gz
    
    $ cd subversion-1.6.16
    $ ./configure --prefix=$HOME/local --with-ssl --without-berkeley-db
    $ gmake clean
    $ gmake
    $ gmake install
    

    いままで$HOME/local/binにパスが通っていなかった場合、source .cshrcしてパスを通します。

    $ source .cshrc
    $ svn --version
    svn, version 1.6.16 (r1073529)
       compiled Mar 20 2011, 15:44:38
    
    Copyright (C) 2000-2009 CollabNet.
    Subversion is open source software, see http://subversion.apache.org/Link 
    This product includes software developed by CollabNet (http://www.Collab.Net/Link ).
    

    testリポジトリを作成します。

    $ mkdir -p svn/repos
    $ cd svn/repos/
    $ svnadmin create test
    $ cd ~
    $ mkdir temp
    $ cd temp
    $ svn co file:///home/<ユーザ名>/svn/repos/test test
    Checked out revision 0.
    $ cd test/
    $ svn mkdir trunk branches tags
    A         trunk
    A         branches
    A         tags
    $ svn commit -m "first commit"
    Adding         branches
    Adding         tags
    Adding         trunk
    
    Committed revision 1.
    $ svn list file:///home/<ユーザ名>/svn/repos/test
    branches/
    tags/
    trunk/
    

    インストールを開始して最初のcommitまで、30分程度で完了しました。

    — posted by westerndog at 04:44 pm  

    ウィジェット

    諸事情でYウィジェットを作ることになりそうなので、製作過程のメモを作ることにしました。

    準備

    1. Yウィジェットエンジンをダウンロードしてインストール。
    2. 次に、ウィジェットコンバータをダウンロード。ウィジェットコンバータは、コマンドラインツールとウィジェットバージョンがあるが、コマンドラインバージョンはVistaでうまく動かないので、ウィジェットバージョンを使うことにする。
    3. ウィジェットクリエイションチュートリアルに従い、CPUポータルを解凍し、ソース(XML)が見られた状態になったことを確認。

    HelloWorld

    <?xml version="1.0" encoding="UTF-8"?>
    <widget minimumVersion="4.5">
    //デバッグモードの設定
      <settings> 
        <setting name="debug" value="on"/>
      </settings>
    //ウィンドウの生成
      <window title="mainWindow" name="mainWindow" height="100" width="100" >
    //テキストの生成
        <text data="Hello World!" size="16" anchorStyle="topLeft"/>
      </window>
    </widget>
    
    1. helloWorld.konファイル(UTF-8、改行LF)を作成。
    2. helloworldフォルダの中にContentsフォルダをつくり、Contentsフォルダの中にhelloWorld.konを入れて、helloworldフォルダをウィジェットコンバータウィジェットにドラッグアンドドロップ。
    3. 変換する形式flat-fileを選び、変換するとhelloworld.widgetができるので、ProgramFilesのウィジェットエンジンのWidgetsフォルダにコピー。ダブルクリックしてインストールすると、ウィジェット一覧にhelloworldが現れ実行可能になる。

    時計

    <?xml version="1.0" encoding="UTF-8"?>
    <widget minimumVersion="4.0">
    <window title="TestClock">
    <name>mainWindow</name>
    <width>500</width>
    <height>50</height>
    <shadow>0</shadow>
    <alignment>left</alignment>
    <visible>0</visible>
    <onFirstDisplay>
    mainWindow.hOffset = screen.availWidth / 2 + screen.availLeft - 250;
    mainWindow.vOffset = screen.availHeight / 2 + screen.availTop - 25;
    </onFirstDisplay>
    
    <image src="Images/bg.png">
    <name>body</name>
    <hOffset>0</hOffset>
    <vOffset>0</vOffset>
    </image>
    
    <text name="window" data="時間" alignment=right hOffset=488 vOffset=36 size=28 color="#ffffff" />
    </window>
    
    <timer name="Ticker" interval="1" ticking="true">
    <onTimerFired>
    doCalc();
    </onTimerFired>
    </timer>
    
    <action trigger="onLoad">
    <![CDATA[
    function doCalc(){
    var now = new Date();
    
    var year = now.getFullYear();
    var month = now.getMonth()+1;
    var date = now.getDate();
    var hour = now.getHours();
    var min = now.getMinutes();
    var sec = now.getSeconds();
    var day = now.getDay();
    
    if ( day == 0 ) { day = "日" }
    if ( day == 1 ) { day = "月" }
    if ( day == 2 ) { day = "火" }
    if ( day == 3 ) { day = "水" }
    if ( day == 4 ) { day = "木" }
    if ( day == 5 ) { day = "金" }
    if ( day == 6 ) { day = "土" }
    
    if ( month < 10 ) { month = "0" + month }
    if ( date < 10 ) { date = "0" + date }
    if ( hour < 10 ) { hour = "0" + hour }
    if ( min < 10 ) { min = "0" + min }
    if ( sec < 10 ) { sec = "0" + sec }
    
    window.text = year + "年" + month + "月" + date + "日(" + day + ") "+ hour + "時" + min + "分" + sec + "秒";
    }
    ]]>
    </action>
    </widget>
    
    1. TestClock.konファイル(UTF-8、改行LF)を作成。
    2. TestClockフォルダの中にContentsフォルダをつくり、Contentsフォルダの中にTestClock.konを入れて、TestClockフォルダの中にImagesフォルダをつくり、bg.png(横500px縦50px)に入れる。
    3. 通常通り変換。

    — posted by westerndog at 03:53 pm