第8回 保存先の変更 その2 - OOP講座
がる先生のOOP講座
Lecutures on PHP
第8回 保存先の変更 その2 (その1)
保存先の変更 その2
DBの使い方が何となくわかったところで実装に入…る前に。
まずは「テーブル」をざっくりと切っていきましょう。
筆者の個人的感想ですが。テーブルを切るのとクラスを切るのには、非常に似たようなところがあります。
クラスが「1インスタンスの意味」に対して厳密に切るのと同様に、テーブルは「1レコードの意味」をしっかりと念頭に置いておくと、比較的きれいに切れるように思います。
今回切る唯一にしてメインのテーブルは、当然ながら「1レコード == 1つの発言」になります。
具体的なテーブルレイアウトは後ほど考えるとして、まずは「1レコードが1発言を意味するテーブルがある」事を念頭に、一端先に進めてみましょう。
まずは相変わらずのざっくりした「日本語ソースコード」です。
readとwriteについてそれぞれ確認をしてみましょう。
list 1
readの処理
1
// 表示したい発言のnoを取得する
2 // DBにconnect、DBハンドルを取得する
3 // 必要なSQL文を作成する
4 // SQL文を発行する
5 // データを読み取る
6 // 出力する(テンプレートエンジンに変数を設定する)
7 // DBハンドルをcloseする
list 2
writeの処理
1
// 入力されたデータを取得する
2 // DBにconnect、DBハンドルを取得する
3 // 必要なSQL文を作成する
4 // SQL文を発行する
5 // DBハンドルをcloseする
当然といえば当然なのですが。DBに関連する処理ですから、なんか明らかに「コピペしただろ」ってくらいに似ている(クリソツ、という単語は死語なんでしょうか?)部分がありますので切り出していきましょう。
何よりも似ているのがここです。
list 3
1
// DBにconnect、DBハンドルを取得する
2 // DBハンドルをcloseする
開けて閉める。通信用のsocketからファイルから、このあたりのお作法にはなんも変化はありませんので、DBでも同様のお作法でございます。
同じお作法というからには「プロセスが終了したらOSが自動で閉じてくれる」ってのもまたもちろん同様だったりはするのですが、そのあたりは「丁寧に」いきましょう。FCGIとか使ってる時に下手にCloseされると困るのですが、それはまた別のお話。
ではDBハンドルを開けます………さて、今回のシステムはMySQLだったでしょうか? PostgreSQLだったでしょうか?
OracleやDB2とは想像しにくいのですし、sybaseだったりFirebirdもしないとは思うのですが、、こういう時に悩んでわかるのは予言者くらいなもんです。
悩む前に、とっとと決定権を持っている上司にお伺いを立てましょう。というわけで速やかに質問mailを送ります。
.....
...
返事が返ってきました。どれどれ…
<<メール>>
まだ協議中だから、どれになっても問題ないようにしてくれ。
どーしたもんでしょうかねぇ。とりあえず、砥石で鉈でも研ぎましょうか? 完全な計画のほうが先ですかねぇ?
………とかいう本音は一端棚の上に上げておきまして。
いやまぁあんまり冗談でもなく。RDBのプロダクトが不安定になる瞬間というのは、時々存在します。時々です、高頻度ではありません。
とはいえ…納品一週間前くらいのタイミングで「あっさりとプロダクトの変更をされた」経験が筆者にもございますしねぇ。…こういうのを「あんまり知りたくない世界」とか言ったり言わなかったり。。
まじめなところに話を戻しまして。
「RDBのプロダクトに固有な処理」をあんまり孕んでしまうと後々面倒だったりもするので、ここはよいチャンスだと思って「ある程度汎用的な書き方」を模索していきましょう。
とはいえ、PHPのマニュアルで接続する関数を調べても…困ったくらいに多種多様です、っていうかプロダクト毎にバランバランです。
とりあえず、ざっくりとDBとのconnectを行う関数を列挙してみましょう。
sybase_connect (http://www.phppro.jp/phpmanual/php/function.sybase-connect.html)
resource sybase_connect ([ string $servername [, string $username [, string $password [, string $charset [, string $appname [, bool $new = false ]]]]]] )
ibase_connect (http://www.phppro.jp/phpmanual/php/function.ibase-connect.html)
resource ibase_connect ([ string $database [, string $username [, string $password [, string $charset [, int $buffers [, int $dialect [, string $role [, int $sync ]]]]]]]] )
db2_connect (http://www.phppro.jp/phpmanual/php/function.db2-connect.html)
resource db2_connect ( string $database , string $username , string $password [, array $options ] )
mysql_connect (http://www.phppro.jp/phpmanual/php/function.mysql-connect.html)
resource mysql_connect ([ string $server = ini_get("mysql.default_host") [, string $username = ini_get("mysql.default_user") [, string $password = ini_get("mysql.default_password") [, bool $new_link = false [, int $client_flags = 0 ]]]]] )
mysqli::__construct (http://www.phppro.jp/phpmanual/php/mysqli.connect.html)
mysqli::__construct ([ string $host = ini_get("mysqli.default_host") [, string $username = ini_get("mysqli.default_user") [, string $passwd = ini_get("mysqli.default_pw") [, string $dbname = "" [, int $port = ini_get("mysqli.default_port") [, string $socket = ini_get("mysqli.default_socket") ]]]]]] )
oci_connect (http://www.phppro.jp/phpmanual/php/function.oci-connect.html)
resource oci_connect ( string $username , string $password [, string $connection_string [, string $character_set [, int $session_mode ]]] )
pg_connect (http://www.phppro.jp/phpmanual/php/function.pg-connect.html)
resource pg_connect ( string $connection_string [, int $connect_type ] )
…大抵「どんだけ~」ってな種類があります。
こんだけ多種多様だとあきらめる…には少々早すぎるので。もう少しざっくりと見てみます。
全体的に、引数に少し注目をしてみましょう。
そうすると、ふと、ある事に気づきます。
どのDBハンドルを取得するときも、大抵
- 接続アカウント名
- パスワード
- 接続database名
- 接続ホスト名
- 接続ポート番号
という引数の群れがあります。
ここで「なんか共通化できるんぢゃね?」と発想するのがエンジニアってぇもんです。
えと…ちょっと雑に考えてみましょう。
まず、接続用の情報をぶち込むようの「なにか」を用意します。
list 4
1
$obj = new なにか();
2 $obj->set_user_id(接続アカウント名);
3 $obj->set_password(パスワード);
4 $obj->set_database_name(接続database名);
5 $obj->set_host_name(接続ホスト名);
6 $obj->set_port_num(接続ポート番号);
そうして、例えばこのobjをつかって、こんな風にDBハンドルを取れたら、なんか楽そうじゃないでしょうか?
list 5
1
// パラメタつくって
2 $obj = new なにか();
3 $obj->set_user_id(接続アカウント名);
4 $obj->set_password(パスワード);
5 $obj->set_database_name(接続database名);
6 $obj->set_host_name(接続ホスト名);
7 $obj->set_port_num(接続ポート番号);
8
9 // DBハンドルをもらう
10 $dbh = DBハンドル作る君::ハンドル作って下さい('MySQL', $obj);
これだと、MySQLがPostgreSQLになろうがFirebirdになろうが、ある程度まで対応ができそうな気がします。
PostgreSQLになったら、多分
list 6
1
// パラメタつくって
2 $obj = new なにか();
3 $obj->set_user_id(接続アカウント名);
4 $obj->set_password(パスワード);
5 $obj->set_database_name(接続database名);
6 $obj->set_host_name(接続ホスト名);
7 $obj->set_port_num(接続ポート番号);
8
9 // DBハンドルをもらう
10 $dbh = DBハンドル作る君::ハンドル作って下さい('PostgreSQL', $obj);
とかで完了です。
しかも、接続情報って大抵、外だしのconfigファイルに書いてありますよね?
だとすると、
list 7
1
// DBハンドルをもらう
2 $dbh = DBハンドル作る君::ハンドル作って下さい( configファイル名 );
でいけちゃうんんじゃないでしょうか?
っていうかこれでいけると嬉しいですよね?
で、実際問題これでいけちゃうんです。
これは、業界的専門用語で格好よく言うと
「GoFのFactoryパターンを使っている」
と言います。テストに出るからちゃんとメモしておいてください(なんのテストだ)。
- 1
- 2





ページのトップへ


kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。