ファイルをアーカイブしてダウンロードさせる

2010/02/13 | その他PEAR全般

複数のファイルを一括してダウンロードしたいというリクエストを頂いた。当然httpでは、例えばFTPのようにサーバのディレクトリをそのまままるごとダウンロードさせるようなことはできない。これを実現するための方法は、ダウンロードしたいファイル群を圧縮して一つのファイルとし、それをダウンロードさせる方法だ。調べてみると、大きく分けて二つの方法(ライブラリ)がありそうだ。一つはPear::File_Archiveを使用する方法、もう一つはphpMyAdminの中に含まれるスクリプトを流用する方法だ。後者はデータベースのダンプを圧縮ダウンロードするためのライブラリだ。後者のライブラリに関する記述を見る限りはかなりスマートに記述出来そうなイメージを持ったが、ライセンスがわからないので使用を控えることにした(クライアントに納品するものだしね)。

前者はもちろんライセンス的には難の問題もない。ただ、個人的に見て記述方法がスマートではないように見える。それがちょっと嫌(でも仕方ない)。スクリプトは以下のように記述した。

require_once “File/Archive.php”;
$obj = File_Archive::toArchive(date(YmdHis).’.zip’, File_Archive::toOutput());
foreach($borings as $boring){
$path=(ファイルのパス);
if($body=@file_get_contents($path)){
$obj->newFile(ファイル名);
$obj->writeData($body);
}
}
$obj->close();

とりあえず、これでダウンロードは出来ることを確認した。ただし一つ問題。lhacaなどのアーカイバではなんの問題もなく解凍できるが、エクスプローラで内容を確認しようとすると「無効です」と怒られてしまった。きっとファイルとして体をなすための許容の範疇ではあるけれども、ちょっとだけファイルが壊れているのだと想像した。なんとなく原因もわかっているけれど。

回避する方法はまた別の機会にでも記述することにする。

ini_set(’include_path’,ini_get(’include_path’).’:’.dirname(__FILE__).’/../../pear/PEAR’);
require_once “File/Archive.php”;
$obj = File_Archive::toArchive(date(YmdHis).’.zip’, File_Archive::toOutput());
foreach($borings as $boring){
$path =dirname(__FILE__).’/../../data/’.substr($boring,0,2).’/DATA/BED’.$boring.’.XML’;
if($body=@file_get_contents($path)){
$obj->newFile(’BED’.$boring.’.XML’);
$obj->writeData($body);
}
}
$obj->close()

Cache_Liteのバグか

2010/01/25 | Cache_Lite

PEARのCache_Liteはいつもよく使っているのだが、これってバグじゃないか、と思える症状に出くわした。

if(!$lines=$cacheObj->get($cacheId)){
$lines=hoge();
$cacheObj->save($lines,$cacheId);
$this->cached[$cacheId]=$lines;
}

上記の処理は、キャッシュIDを指定してキャッシュされているかどうかチェックし、キャッシュがなければhoge()関数を使ってデータを取り出して、改めてキャッシュに保存する、という処理を書いている。

この処理自体はなんの問題もなく動作する。しかしこの処理を、ひとつのスクリプト内で2回呼び出すとエラーになる。「そもそも1回取得しているデータなんだから2回も呼び出すことはないだろ」と言われるかもしれないが、例えばスクリプトをクラス化し、共通のデータをそれぞれ別の処理で使用するようなとき、2回呼び出したほうが記述がスマートな場合もある。

回避方法としては、結局データを一時的に格納する変数を作成し、そこもチェックするようスクリプトに手を加えることで対応した。これってバグだと思う。というか、もしかしたら、Cache_Liteそのものに回避方法があるのだろうか。

といっても最新版ではなくて、1.51の話(2008年6月のリリース)。現時点での最新版は2009年7月の1.7.8。新しいバージョンでチェックしてみなきゃ。っていうか、新しいバージョンを使わなきゃ・・・。

PEARを久々に使う

2009/09/15 | その他PEAR全般

久々にPEARを使うことになった(というより使わなければいけない羽目になった)。もちろんPEAR自体はとてもよくできていていいのだが、個々のライブラリ間の依存度合いが非常に強く、トータルで使わなければその実用性が発揮できないからだ(いや、本当はそんなことないけど、個人的に依存度合いの強いものを使いたくないだけ)。

文句ばかりでもしょうがないので、久々にインストール作業をすることになる。インストール対象はCentOS5。PEARをインストールするときは、いつも専用のディレクトリを作って、そこにまとめてインストールしていた。しかし今回はサーバのデフォルトの場所にインストールすることにした。

pear install (パッケージ名)

rootになってこのコマンドで一発インストールできるのだが、早速依存関係で怒られる。で、依存関係も解消してくれるよう以下のコマンドを実行する。

pear install –alldeps (パッケージ名)

はい、できあがり。これで一応使えるようになった(と思う)。あとはパスが通っているかどうかチェックするだけ。でもまぁ、あんまり乗り気ではない。

addGroupの代替「fieldset」

2008/04/28 | HTML_QuickForm2

HTML_QuickForm2は、現在のアルファ版では、HTML_QuickFormで用意されていたaddGroupメソッドがない。addGroupは複数の要素を一括して取り扱うことができるので便利なメソッドだった。例えばラジオボタンやチェックボックスを複数作成しておいてそれをグループ化し、作成したグループに対して妥当性チェック(Validation)をかけることができた。
その代わりかどうかはわからないが、HTML_QuickForm2ではaddElementする際に、通常の「text」や「textarea」等以外に「fieldset」なるものが追加されていて、こんな感じで使用する。

$field=$form->addElement(’fieldset’);

サンプルをみると、複数の要素を一くくりにして扱うための要素のように見える。HTML_QuickFormと同等の処理がしたいのだが、このfieldsetとして作成された要素$fieldに対してaddRuleとかできるのだろうか。
デフォルトで用意されていなくても、createRuleして使えるのであればとても便利なのだが・・・。識者の方がご覧になられることがあれば、ぜひご教示いただきたい部分。どうぞよろしくお願いします。

チェックボックスを配列指定した場合の初期値

2008/04/26 | HTML_QuickForm2

HTML_QuickForm2でも前バージョンと同様に、チェックボックスで送られてくる際のvalue値は1だ。これは「一つのチェックボックスが一つの設問を構成する」という前提で作られているためだと思う(例えば「○○が必要な場合にはチェック」というような感じ)。「当てはまるものすべてにチェックしてください」みたいな設問への配慮がないのはなぜだろう。いつも疑問に思う。

いわゆる「多岐選択」でチェックボックスを使うときはこんな具合に指定する。

$element[]=$myForm->addElement(’checkbox’,'q1[a]‘,NULL,array(’content’=>’a'));
$element[]=$myForm->addElement(’checkbox’,'q1[b]‘,NULL,array(’content’=>’b'));
$element[]=$myForm->addElement(’checkbox’,'q1[c]‘,NULL,array(’content’=>’c'));

name属性が入るべきところにq1[a]という具合に配列っぽく記載する。もちろんこの記述でフォームからデータが送られてくると、値は配列となって送られてくる。

上記のような場合のデフォルト値の設定は配列として与えてやることになる。

$myForm->addDataSource(
  new HTML_QuickForm2_DataSource_Array(
    array(
      ’q1′=>array(’a'=>1,’b'=>1),
      )
    )
  );

少し、慣れてきたかな。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net