まさはる's Weblog

まさはる's Weblog
Macintoshとオーディオの話題
2007年9月

2007年9月26日

PHPを使ってみました(その3)

Category : Web 2 / Posted at 2007年9月26日 23:01

 PHPSQLiteを初めて使ってみたのですが、何とかデータベースの作成と編集及びデータの閲覧ができるスクリプトができたので、おぼえとして記しておきます。


1)SQLite関係
 SQLiteといっても、query() の中はSQLで書くため他のデータベースと比べて(きっと)使い方に違いはありません。問題があるとすればSQLがCOBOLやFORTRANと同じ時代に作られた言語なため、書き方が古臭くコマンドの文字列が異様に長いことと、「'」の使い方がPHPやPerlと違うためプログラムが分かりにくいってことでしょうか。書いてみて思ったのですが、表向き「SQLであることを明確にするために大文字で書く」とよく聞きますが、実は「自分のプログラムから、書き方が違う古くさい言語を排除したい」ために大文字で書いているという気がしてなりません。私は後者そのままですけどw。


require 'DB.php';
...
// データベースへの接続
$db = DB::connect("sqlite://:@localhost/パスを含むデータベースファイル名");
if (DB::isError($db)) { die("Can't connect: " . $db->getMessage()); }
...
// テーブルの作成
$q = $db->query('CREATE TABLE テーブル名 (
	id INTEGER PRIMARY KEY, フィールド名 フィールドタイプ,... )');
if (DB::isError($q)) { die('Query Error: ' . $q->getMessage()); }
...
// レコード追加
$q = $db->query("INSERT INTO テーブル名 (
	id, フィールド名,... ) VALUES ( '$id', '値',... )");
	// 値に $_POST['date'] を入れる場合は '$_POST[date]' とする
...
// プレースホルダによるレコード追加
$q = $db->query("INSERT INTO テーブル名 (
	id, フィールド名,... ) VALUES ( ?, ?,... )", array($id, 値,... ));
	// 値に $_POST['date'] を入れる場合はそのまま $_POST['date']
...
// レコード更新
$q = $db->query("UPDATE テーブル名 SET 
	date = '$date', フィールド名 = '値',... WHERE id = '$id'");
...
// プレースホルダによるレコード更新
$q = $db->query("UPDATE テーブル名 SET
	date = ?, フィールド名 = ?,... WHERE id = '$id'", array($date, 値,... ));
...
// 全フィールドのデータ取得
$q = $db->query("SELECT * FROM テーブル名 WHERE id = '$id'");
$row = $q->fetchRow();	// 配列変数$rowにフィールド順に格納
$count = $q->numrows();	// レコード数 この場合$countは1
...
// レコード削除
$q = $db->query("DELETE FROM テーブル名 WHERE id = '$id'");
...


2)Form関係
 htmlで<form>はこれまで使ったことがなく、今回初めて使いました。こんな状況なので私のプログラムは解説本を数ページめくったところにある「Hello, ?さん!」を表示するサンプルプログラムを引き延ばした状況になっていますw。したがって下記の内容は参考になりません。(きっぱり!)


...
// オートグローバル変数 $_POST['edit'] の値を使って処理する場合
if ($_POST['edit']) {
	// $_POST['edit'] はvalueの値 'id=1'
	$id = ereg_replace('id=', '', $_POST['edit']);	// $_POST['edit'] から 'id=' を削除
	...処理...
}
print "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">\n";
	print "<input type=\"submit\" name=\"edit\" value=\"id=1\" />\n";
print "</form>\n";
...
// オートグローバル変数 $_GET['id'] の値を使って処理する場合
if ($_GET['id']) {
	// $_GET['id'] は '?id=' の後に続く値 '1'
	...処理...
}
print "<a href=\"{$_SERVER['PHP_SELF']}?id=1\">一番</a>";
...


3)日本語処理関係
 日本語のWebページを作る以上、プログラム内でマルチバイト文字の処理は付きまといますが、PHPでは 'mb_' で始まる関数で処理可能で正規表現も使用できます。注意点は、PHPの内部処理エンコーディングと違うエンコーディングで処理したい場合は指定が必要で、うちのLaCoocanは内部処理が 'EUC-jp' のようなので 'UTF-8' を明示的に指定しています。なお、下記は今回作成した文字列を切り捨てる関数です。


...
// 文字列をカットする関数
function textCut($str, $len = 80) {
	// $str: カットする文字列
	// $len: カットする文字数(省略時は80)
	// 文字エンコーディングにUTF-8を指定
	mb_regex_encoding('UTF-8');
	// <div>...</div>を取り除く
	$str = mb_ereg_replace('<div.+?/div>', '', $str);
	// <...>を取り除く
	$str = mb_ereg_replace('<.+?>', '', $str);
	// 空白、改行等を取り除く
	$str = mb_ereg_replace('\s', '', $str);
	// $lenの値で文字列をカット、カット後は'...'で置き換え
	$str = mb_strimwidth($str, 0, $len, '...', 'UTF-8');
	return $str;
}
...


 今回作成したプログラムで少し特殊な部分はこの程度で、他は一般的な関数等で事足ります。とりあえずこの程度でデータベースを利用したWebページが作れるので、Webを仕事にしている人等には便利な言語なんだろうと思います。
 余談ですが、PHPのプログラムは <?php から ?> の間に書きますが、htmlの中でプログラムの場所が飛んでいても変数の値が引き継がれるのにはビックリしました。てっきり変数のスコープは範囲内だけだろうと思い込んでいたので、ブツ切り可能となると超楽チン。プログラムの見易さを考えた上で切る分には有効だと思います。

このページのトップに戻る

2007年9月23日

PHPを使ってみました(その2)

Category : Web 2 / Posted at 2007年9月23日 15:29

 海の向こうではThe Sims 2の新しい拡張パックのBon Voyageが発売され、追加された和風のアイテムや建材を使った住宅がModTheSims2にアップされ始めて羨ましい限りですが、毎度のことながらMac版は現在のところ音沙汰なしw。まぁ、バグが取れた頃に発売されるので良い面もあるんですけど...。

 話が逸れましたが、肥大化した「The Sims 2 Download」のページを、PHPSQLiteを使って改良しようという話題の続きで、今回はWebで表示するスクリプトの作成の話です。

1)表示スクリプトの作成
 SQLiteからデータを取得してリスト表示や個別表示をするPHPスクリプトは簡単なのですが、オープンにすることからユーザーの入力を受け付ける箇所は注意が必要です。うちの表示スクリプトは、まずリスト表示をして、その中のどれかを押すと詳細を記した個別表示に切り替わるという一般的なもので、ユーザーから入力を受け付ける箇所は一見無さそうなのですが...。

落とし穴
ユーザーから入力可能な箇所がこんなところに...

 上の図の75という値は、オートグローバル変数の $_GET['id'] に入っていますが、アドレスバーで他の文字を入力すればそれがそのまま入るため、query()に渡す前に変なデータは棄却する必要があります。このスクリプトの場合は、intval()とstrval()を使って整数の文字列にしてから元の値と比較し、良ければ値のデータの有無を確認してから処理するようにしています。


...
if ($_GET['id'] == strval(intval($_GET['id']))) {
	// ここは true の処理
} else {
	// ここは false の処理
}
...

 とりあえずできた。まだ使い勝手が悪いので改良が必要ですが晒しておきます。

2)PHPを使ってみて
 PHPはhtml内にそのまま書ける、オートグローバル変数が便利、関数が豊富など、かなり使い勝手の良いプログラム言語だと思います。よって、最近のWebサイトの多くがPHPで作られているのも頷けます。あえて不満を述べるなら、Perlに比べると自由度が少ないというか、遊びがなく作っていて面白みがないっていうか...。まぁ、パズルを解くというよりは作業をするという感じで、仕事で使うには向いていると思います。
 あと、PHPに限った話ではありませんが、スクリプトのソースはhtml、PHP、SQLの言語が混ざっており、それぞれ書き方が違うためソースは非常に見にくくなってしまいます。これにJava Scriptでも加えようものならもう大変w。もうちょっとどうにかならないものですかね。

このページのトップに戻る

PHPを使ってみました

Category : Web 2 / Posted at 2007年9月23日 02:05

 今回は、トップページの右側に貼ってある「The Sims 2 Download」っていう自前のページについての話題です。

 このページ、The Sims 2というゲームで使用できる自作住宅を紹介しているページなのですが、住宅が増える度にhtmlをコピーして追加してきたため、現時点で住宅数75、htmlファイルは2,151行、貼付けてある画像ファイルは261個と、Webページの1ページに納めるには非常識な状態になっています。自分でhtmlを書いているためずいぶん前から認識はしていたのですが、ここ最近、いくらなんでもこのままではヤバいと思うようになり、9月の連休も手伝って重い腰を上げることにしました。

 そこで、どうするかということですが、この手のページは表示する項目が決まっており、いわゆるネットショッピングの商品選択ページのようなものであるため、データベースを利用するのが向いています。また、htmlが重複する部分が多いため、データベースを読んで表示するCGIを作ってしまえば以降手間がかかりません。ってことで、データベースには1つのデータベースファイルで済み、バックアップが容易なSQLiteを、CGIの方は流行りのPHPを使ってページを改良することにしました。

1)データベースを作成しようと...
 あ〜、長い前置きだったw。で、データベースを手軽に作成しようと、Macでも使えるSQLiteのツールをsqlite - Management Toolsで探してみました。
 結論から言うと、色々と試してみましたが良いのが無かったという状況です。というのは、文字や数字は問題ないのですが、htmlのタグを含んだ文字列をそのままデータベースに入れようとするとWebページのように表示され、文字列として修正できない状況になるためです。
 と、いうことで、結局データベースを作るツールからPHPで書く羽目に...。

2)データベース追加・編集ツールの作成
 あ〜辛気くさいw。便利なツールが自由に使える状態になっているかと思っていたら、こんなものから自分で作ることになるとは...。なんだかんだ言いつつ苦労しながらも何とか作れたので、作成時のポイント等を紹介します。なお、LaCoocanのレンタルサーバーはPHP5になっています。
 参考:PHP マニュアル SQLite/SQL Syntax

a)データベース作成スクリプト
 データベースは1つのテーブルに次のフィールドを設定しました。

ColumnTypeComment
idINTEGER PRIMARY KEY主キー
dateDATE作成日
typeTEXT住居/公共の別
widthINTEGER区画の幅
depthINTEGER区画の奥行き
priceINTEGER価格
titleTEXT名称(「'」及び「"」有り)
textTEXT本文(「'」及びhtmlのタグ内に「"」有り)
noteTEXT注記(「'」及びhtmlのタグ内に「"」有り)
file_nameTEXTファイル名
file_urlTEXTファイルのURL
pict_urlTEXTサムネイルのURL
ep01BOOLEAN拡張パック使用の有無
ep02BOOLEAN
ep03BOOLEAN
......

 PHPからデータベースファイルとそのテーブルを作るのは簡単です。DB::connect()でデータベースに接続し(ファイルがなければ作成される)、query()でSQLコマンドを発行すると作成されます。


require 'DB.php';
$db = DB::connect('sqlite://:@localhost/データベースファイル名');
if (DB::isError($db)) { die("Can't connect: " . $db->getMessage()); }
$q = $db->query('CREATE TABLE lot (
	id INTEGER PRIMARY KEY,
	date DATE,
	type TEXT,
	width INTEGER,
	depth INTEGER,
	price INTEGER,
	title TEXT,
	text TEXT,
	note TEXT,
	file_name TEXT,
	file_url TEXT,
	pict_url TEXT,
	ep01 BOOLEAN,
	ep02 BOOLEAN,
	ep03 BOOLEAN,
	... )');
if (DB::isError($q)) { die('Query Error: ' . $q->getMessage()); }

b)データベース編集スクリプト
 こっちは上ほど簡単ではありません。リスト表示、新規作成、編集、削除の機能を持つスクリプトを書くのですが、前述のhtmlのタグを含む文字列をそのまま入れようとする箇所(正確には「'」及び「"」のデータが入る箇所)で見事に引っかかりました。テキストフィールドに「'」や「"」があると、保存時に「\」で自動的にクォーティングされるのですが、編集を繰り返す度に重ねてクォーティングされて「\」だらけになってしまうというものです。
 クォーティングはSQLの実行時に必要で自動的に行われるのはいいのですが、解説本にはhtmlをフォームで編集してデータベースに保存するということを前提にしていないため対処方法が載ってない(よく読んでないせいかもしれんがw)。結局、いろいろと試行錯誤をした結果、編集フォームに出す前に前回クォーティングされた「\」をstripslashes()で取り除いて、編集フォームに表示することで解決しました。


...
$q = $db->query("SELECT * FROM lot WHERE id = $id");
if (DB::isError($q)) { die('Query Error: ' . $q->getMessage()); }
$row = $q->fetchRow();
...
$title = stripslashes($row[6]);
$text = stripslashes($row[7]);
$note = stripslashes($row[8]);
...
print "<input name=\"title\" value=\"$title\" />\n";
print "<textarea name=\"text\">$text</textarea>\n";
print "<textarea name=\"note\">$note</textarea>\n";
...

 あと、データベースへ書き込む時に、データ内に「'」が含まれているとエラーなるため、プレースホルダを使っています。これはquery()の値を入れたいところに「?」を書いて、2番目の引数で値を渡します。後はデータベースがうまく(何を?w)やってくれるそうです。


...
$q = $db->query("INSERT INTO lot (
	id, date, type,
	width, depth, price,
	title, text, note,
	file_name, ...
	) VALUES (
	'$id', '$_POST[date]', '$_POST[type]',
	'$_POST[width]', '$_POST[depth]', '$_POST[price]',
	?, ?, ?,
	$_POST[file_name]', ...
	)", array($_POST['title'], $_POST['text'], $_POST['note']));
if (DB::isError($q)) { die('Query Error: ' . $q->getMessage()); }
...

 次回は、Webで表示するスクリプトの作成です。

このページのトップに戻る

2007年9月15日

Movable Type 4へのアップグレード

Category : Web 2 / Posted at 2007年9月15日 18:31

 1ヶ月ほど前にシックス・アパートからMovable Type 4が出荷されましたが、ダウンロードだけして放置していたので、3.32-jaからアップグレードしてみました。

編集画面
Movable Type 4の編集画面

 3.32-jaからのアップグレードの手順は以下のとおりです。なお、うちはLaCoocanのレンタルサーバーで、そこで説明されているインストール方法のとおりMovable Typeがインストールされている状態になっています。また、データベースにはSQLiteを使用しています。

1)Movable Type 4のindex.htmlの中にあるマニュアル「既存環境からのアップグレード」を穴があくほど読む。
2)サーバーにあるMovable Typeフォルダ内のファイルを全てバックアップ。
3)Movable Type 3.2以降は mt-config.cgi がそのまま使用できるので、Movable Typeフォルダ内の mt-config.cgi とデーターベースファイル(.dbの拡張子の付いたファイル)を残して全て削除。
4)Movable Type 4のファイルを全てアップロード。
5)Movable Typeフォルダ内の.cgiの拡張子が付いたファイルのパーミッションを700に設定。
6)これまでと同様にログインすると、自動的にアップグレード。

 あら、簡単w。FTPソフトでファイルを置き換えてパーミッションを直しただけですが、ちゃんとアップグレードできたようです。
 ちなみに、何が変わったのかというと...もともと基本的な機能しか使っていないため、よく分かりませんw。外見はずいぶんと今風に変わりましたが...。

このページのトップに戻る

2007年9月 9日

The Sims 2 Seasons Expansion Pack(その3)

Category : Game 3 / Posted at 2007年9月 9日 01:03

 またまた、Seasonsの話題です。

雪
雪が積もっています

 この拡張パックでは、これまでに紹介した季節の追加、家庭菜園及び釣りの他には、冒険家などの職業が6種類、植物シム、建築材料、アイテム、ペンギンのキャラクター等が追加されています。また、シムに暑い・寒いという温度の概念が加わり、寒い時期に外に長くいるとカゼをひいたり、ホットタブに長く入りすぎていると火事になるなどのアクションも追加されています。

ペンギン
雪だるまに話しかけているようです

 これまでに無かった季節の追加や家庭菜園ができるようになったことなど、この拡張パックはけっこうお勧めです。

 話変わって、最近作った木造5階建ての住宅などを。入口のハデハデさと多くのちょうちんが怪しさを醸し出している、「千と千尋の神隠し」に出てくる「油屋」と同じ業種向けの住宅です。地味な町に潤いを与えてくれることでしょうw。ダウンロードはこちら

遊郭正面
正面入口

遊郭裏側
裏側
このページのトップに戻る