インタラクティブなプログラムを作る

2009/03/26 | CLI

PHPはウェブのためだけの言語ではなくて、コマンドラインからも実行することができるし、Windowsのexeファイルだって作ることができる(納品したことがある)。

PHPでコマンドラインから起動するプログラムを作るのに、インタラクティブに動作するプログラムを作らないといけない案件をもった。インタラクティブなプログラムとは、プログラム中で何らかの入力を促されるような、対話形式のプログラムを指す。そういえば昔N88ベーシックでそういうのがあったなぁ、と懐かしく思い出したけれど、PHPではどうやったらできるんだっけ。でも調べたら、やっぱりできることがわかった(コマンドライン版というくらいなんだから、それくらいできないと・・・)。

ob_end_clean();
echo(‘Input your name: ‘);
$name=fgets(STDIN); 
echo(‘Your name is “‘.$name.'”‘);

ミソはSTDIN。通常はfopenする等したリソースをfgets関数の引数として与えるのだが、そこをSTDINと標準入力からの入力待ち状態にしてやるとよい。あと1行目。バッファリングをonにしていると、プログラム終了まで何も出力されない(表示=プログラム終了)ので、順次表示するようにしてやる。

すっきり。

Smartyテンプレート内でPHPスクリプトを書くときに

2009/03/16 | Smarty

すでにテンプレート内でロジックを書くということ自体がいけないのだが、それでもどうしてもやらなければいけないときがある(というかそのほうがソースがきれいになる)。

Smartyは専用タグを使うPHPのテンプレートエンジンだけど、テンプレートの中にPHPプログラムを直接書くこともできる(書かないでいいものなら書かないほうがいい)。例えばこんなふうに。

{php}
print(‘This is PHP script’);
{/php} 

そもそもこういうふうな処理をかかなければならないわけだから、何らかの変数処理というのも必要になるわけだし、変数だってテンプレートにSmarty変数として使用していたものを使いたくなるのも人情だ。そんな場合は、こういう具合に書く。

$smarty->assign(‘myText’,’This is PHP script’);

{php}
print($this->get_template_vars(‘myText’);
{/php} 

プログラム本体内でmyTextという名前でアサインされた変数を、テンプレート内のPHPスクリプトから呼び出す例だ。ミソは「get_template_vars」メソッド。Smarty関数を書くときにも時々使ったりする。これを使って呼び出せばいい。

でも、やらなくてすむのなら、やらないほうがいい。

simplexmlでどうやって値を取得するか

2009/03/12 | XML

simplexmlでいろいろお試し中。現時点では「タグにコロンが含まれていた場合」の挙動を除けば快適に使えているのだが、少しだけ困った問題が起こった。問題自体は解決できたのだが、それに気づくまでちょっと時間がかかってしまったのと、スマートなやり方でないような気がしたのでちょっとメモ。

xml内の特定のタグでくくられた「値」を取得するのに、以下のように記述した。

$xmlObj =simplexml_load_string($result);
$status=$xmlObj->Header->Status;
var_dump($status);

個人的には’Success’とか’Error’とかの文字列を期待したのだが、出力された結果はこんな感じ。

object(SimpleXMLElement)#4 (1) { [0]=> string(7) “Success” }

オブジェクトが返された。まぁ、これはこれでいいのだけれど、このときに’Success’という文字列を取得する方法がわからなくて困った。「$status->0」なんてしてもやっぱり取得できない。でも、不思議なことに「print」すると「Success」と表示される。なぜ。

結論から言うと、strval($status)とすることで文字列を取得できた。これってスマートな方法なんだろうか。他に関数とか用意されていないのかな。後述の「printすれば」というとこをは理解できた。自動的に型変換されて出力されていたわけ(自動変換はいい場合もあれば、事を複雑にする可能性もあることを実感)。

ま、とりあえず、できた。

楽天APIのジャンル検索が面倒だったので

楽天APIで遊んでいる。今は商品検索APIを試用していて、キーワード検索の機能を使っているのだが、これだとキーワードにマッチするいろんな商品がひっかかってしまう(例えば「くつ」で検索した場合、シューズはもちろん、靴乾燥機や靴下も出てくる)のでジャンルを指定することにした。しかしこれ意外と面倒。ジャンルのリストが用意されているわけではなくて、いちいちAPIを使ってジャンルを検索していかないといけないのだ。はじめのうちはちょこちょこプログラムを書いてvar_dumpしつつデータを読み取っていたけれど、なんとも面倒なので汎用ジャンル検索ができるようプログラムを作ってみた。んでもって、誰でも使えるよう公開してみることにした。

楽天ジャンルID検索ツール

プログラムは単純でジャンル検索APIに準じてRESTを投げ、取得したXMLをsimplexml関数でデコードしている。自分のデベロッパーIDを使って公開すると、検索プログラムの負荷が高まって実際の商品検索ができなくなってしまうので、各自のデベロッパーIDを入力して使えるようにしてみた。自分で使ってみて・・・正直これは便利。他の人はどうしてるんだろ。自作して公開してる人もいるのではないだろうか・・・。

varchar形をソート

2009/03/05 | MySQL

いつもよく使うMySQL。特定カラムでソートするときのTipsというか備忘録。

本来は数値で入力しておくべきカラムなのだが、わがままなクライアントが時として文字列を入力したいということがあるので、とりあえずvarchar型を採用することにしたのが、そのカラムでソートする必要が出てきてしまった。

SELECT * FROM myTable ORDER BY myColumn DESC;

普通にこんな風に描いてみたけど問題が出た。たいていの場合、そこには二桁の数字が入るのだけれど、まれに三桁の数字が入ることがある。そのときに期待通りに並ばない。例えば90と100という”文字列”が入っていたときに、上記のSQLなら100のほうが上位になってほしいのに下位になってしまうのだ。文字列で判断しているわけだから最初の文字「9」と「1」で判断して、そういう結果になるのは当たり前なのだが・・・、100のほうが上位になってほしい。

そんなときに使用する関数(MySQLの)がCASTだ。名前のとおり型変換(型のキャスト)をしてくれる関数だ。上記のSQLを以下のように書き換えてうまく動作してくれた。

SELECT * FROM myTable ORDER BY CAST(myColumn as signed) DESC;

すっきり。でもこれ、行数が多いと時間かかりそう。


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