capsctrldays

2008-08-12 (火) [長年日記]

[CakePHP] 郵便局のサイトから自動で郵便番号データをインポートする

masuidriveさんのRakeタスクをポートしてみる。

とその前に

デフォルトでトランザクション機能がついていないという素晴らしいPHPっぷりを発揮していらっしゃるので、

でメソッドを追加しておく。

モデル作成

<?php
class Zip extends AppModel {
    var $name = 'Zip';
}

テーブル作成

create table zips (
  id varchar(7) primary key,  --zip7
  prefecture_id integer,
  city varchar(64),
  town varchar(254)
);

vendors/shell/zip.php にコマンドを配置

<?php
class ZipShell extends Shell {
   var $uses = array("Zip");

   function main() {
       system("rm ken_all.csv; wget -O - http://www.post.japanpost.jp/".
              "zipcode/dl/oogaki/lzh/ken_all.lzh | lha x -");

       $this->Zip->begin();
       $this->Zip->deleteAll(array("NOT" => array("id" => null)));
       $fh = fopen("ken_all.csv", "r");
       while($cols = fgetcsv($fh)) {
           $data = array(
               "id" => $cols[2],
               "prefecture_id" => substr($cols[0], 0, 2),
               "city" => mb_convert_encoding($cols[7], "UTF-8", "SJIS"),
               "town" => mb_convert_encoding($cols[8], "UTF-8", "SJIS")
               );
           $this->Zip->create();
           if (!$this->Zip->save($data)) {
               $this->Zip->rollback();
               $this->error("rollback!! at " . $cols[2]);
               exit();
           }
       }
       $this->Zip->commit();
       system("rm ken_all.csv");
   }
}

実行

$cake zip

みたいな感じ。