FAQ

  • 一般
    • Jargon とは?
  • Creole
    • Creole はラージオブジェクト(LOB)をサポートしますか?
    • なぜ quote() 関数がないのでしょう?
    • Creole は自動インクリメント/シーケンスをサポートしますか?

一般

Jargon とは?

Jargon は Creole に対する拡張機能です。 基本的にはコアの Creole クラスを使ったクラスの集合体なのですが、 これに PEAR::DB(および MDB)といったライブラリからデータを アクセスするための非常に便利な関数群や、(Java の)Working-Dogs Village から借用した DataSet のような概念を追加したものです。 まだ稼動やテストの実績が十分でないという理由から、 Jargon は現在のリリースには含まれていません。

Creole

Creole はラージオブジェクト(LOB)をサポートしますか?

はい。creole.util.Blob と creole.util.Lob クラスを使えば LOB 値を更新したり呼び出したりできます。 さまざまなデータベースにおける LOB のサポートは、 特に最大パケットサイズなどを制御するような異なった変数を追加した場合、 トリッキーになりがちです。Creole で CLOB/BLOB サポートに関する問題に 直面したら、dev メーリングリスト [1] にメッセージを送ってください。

なぜ quote() 関数がないのでしょう?

PHP から SQL に対して値を insert する際は、決まった方法として PreparedStatement クラスと setter/mutator メソッドを使うべきです。 これは SQL をより読みやすくするだけでなく、 SQL インジェクション攻撃からあなたを守ってくれます。 また単独の quote() 関数は、たとえば BLOB/CLOB カラムのような特殊な処理を 必要とする値の面倒までは見てくれません。多くのネイティブ API には これらに備えて(pg_escape_bytea() のような)特別の関数が用意されています。 練習として PreparedStatement の setter メソッドを使ってみるということは、 自ずとポータブルなコードを書くことにもつながるのです。 たとえば set メソッドは、MySQL ならTRUE を 1 に、PostgreSQL なら 't' に 翻訳してくれます。

自分のコードがいかにたやすく SQL インジェクションの影響を受けやすいか という事実に気づいていない開発者がたくさんいます。 すべての値が注意深くクォートされエスケープされていれば、 SQL インジェクションは問題になりません。 しかしながら、ある変数の型に関して PHP の中で多くの仮定がなされているというのもまた事実なのです。 これらを仮定すると、どうしても以下のようなやり方になりがちです。

間違ったやり方:

$sql = "UPDATE mytable SET strcol = '".addslashes($strval)."' WHERE id = ".$intval;
$con->executeUpdate($sql);

悪意を持ったユーザが(URL などで指定することで) $intval を "1 OR 1 = 1" といった値にセットするだけで、 データベースのテーブル全体が変わってしまいます。 ここでは $intval を整数(integer)だと想定しているわけですが、 これは明示的に integer でキャストしない限り、単なる想定に過ぎません。

正しいやり方:

$sql = "UPDATE mystable SET strcol = ? WHERE id = ?";
$stmt = $con->prepareStatement($sql);
$stmt->executeUpdate($sql, array($strval, $intval));
// または:
// $stmt->setString(1, $strval);
// $stmt->setInt(2, $intval);
// $stmt->executeUpdate();

PreparedStatement の setter メソッドを使えば、値が適切にクォートまたは エスケープされたり、(たとえば数値であれば) insert に先立って数値型にキャストされます。

Creole は自動インクリメント/シーケンスをサポートしますか?

はい。ただし PEAR DB や MDB と同じ方法ではありません。 Creole は PEAR パッケージのようなシーケンスのエミュレートは行いません。 Creole には各データベースごとに IdGenerator クラスがあります。 このクラスは、シーケンスの次の id もしくは最後に insert された id を取得するための有用な情報を返します。 これは、あなたはアプリケーション開発者としてちょっとした作業をする 必要があることを意味しているのですが、 その代わりエミュレータされたものではない、 データベースネイティブの id 生成方法を使うことができます。

$idgen = $conn->getIdGenerator();
// id をゲットするのは insert を実行する前か後か?
if($idgen->isBeforeInsert()) {
   $id = $idgen->getId($seqname);
   // その SQL への ID を追加して INSERT を実行する
   $conn->executeUpdate("INSERT .... ");
} else { // isAfterInsert()
   // まず INSERT を実行する
   $conn->executeUpdate("INSERT .... ");
   $id = $idgen->getId($seqname);
}



Driven by coWiki 0.3.3 web collaboration tool.