dari88's diary

これから趣味にするプログラミング/PHP/javascript/kohana/CMS/web design/

kohana データベースのまとめ・・・セキュリティほか

 今日は kohana のデータベース操作についてちょっとまとめます。

 

SQLインジェクション対策

 テスト4のサンプルコードで使った DB::query を使う記述法の場合、SQL文に変数を埋め込む形で kohana に渡すとエスケープしてくれません。kohana はテキストで渡された SQL文を解析してまでエスケープしてくれるわけではないようです。

 従って、DB::query を使う場合は ->bind() を使ってプリペアード・ステートメント方式で記述する事をルール化しなければいけません。プリペアード・ステートメント方式はクエリをループで使い回す時などに便利なので、これでいいんじゃないでしょうか。

 一方 Query Builder を使う第2の記述法の場合、プリペアード・ステートメントを使わなくてもパラメータは自動的にエスケープ処理されるようです。パラメータは配列なり引数で渡されるのでエスケープ処理が簡単だということなのでしょう。

 

どちらの記述法を使うべきなのか

 Query Builder を使う記述法の場合、SQL文の知識が無くても書けるので一見良さそうに思えます。しかし、そもそも SQL で何が出来るのかを知らなくては話にならないわけで、SQL の勉強をするんだと思います。せっかく SQL の勉強をしたのなら、わざわざ重ねて Query Builderの勉強までする必要はないですね。

 従って DB::query を使っとけばいいんじゃないかと思います。テスト5くらいの簡単な操作の場合は、Query Builder を使った方がさらに簡単なので、これもありだと思うわけです。要は使っているうちに自分のスタイルが決まってくるということでしょうか。

 

コンフィグファイルを利用する

 18日の日記に書きましたが、kohana をインストールした時に
  kohana/modules¥database¥config¥database.php
というコンフィグファイルを書き換えています。ユーザーガイドを読むと、このファイルを
  kohana/application/config/database.php
にコピーして、これにデータベースの定義を書けと言っています。

 例えばこんな感じです。

<?php defined('SYSPATH') or die('No direct access allowed.');

return array
(
        'kohana' => array
        (
                'type'       => 'mysql',
                'connection' => array(
                        'hostname'   => 'localhost',
                        'database'   => 'kohana',
                        'username'   => 'root',
                        'password'   => '********',
                        'persistent' => FALSE,
                ),
                'table_prefix' => '',
                'charset'      => 'utf8',
                'caching'      => FALSE,
                'profiling'    => TRUE,
        ),

);

  先頭の'kohana'はデータベース定義の名前です。データベースはローカルのものリモートのものをいくつ定義しても構わないので、次のような使い方ができます。

$query->execute('konana');
$query->execute('hatena');
for ($n=1 ; $n<= 5 ; $n++){
    $query->execute("hatena$n");
}

  要するに、データベースをいくつも操作できるということですね。大規模なシステムではこんなことが必要なんでしょうが、小生には当面必要が無さそうです。

 kohana はカスケーディング・ファイルシステムを採用しているとかで、コンフィグファイルの場合は下位階層のファイルから読んでいき、上位階層のファイルをマージして定義を完成させるそうです。

 

クエリの実行結果のオブジェクトについて

  当初クエリの実行結果である $result は、単なるデータの配列かオブジェクトだと思っていたのですが、実際はメソッドを持っているオブジェクトです。これは小生の想像を超えたスグレモノで、foreache 回せばデータを出してくれるし、何と後付で操作できたりします。例えば次のような感じです。

$results = $query->execute();
$users = $results->as_array('id');
$names = $results->as_array('id','name');

  これで id をキーにしたデータの配列を返してくれます。

 データベースの検討はこれくらいにして、そろそろ次の課題の検討に移りたいと思います。