数値に関するデフォルトの挙動が、バージョン 1.1.0 で変わりました。 ほとんどのプログラマは、この変更によって ドライバの数値処理がよりスムーズかつ自然に行えるようになるでしょう。 しかし、動作させるためにはアプリケーションのコードに変更が必要になるかもしれません。
整数値のシリアライズやデシリアライズに関して、 以前との互換性を損なう変更がありました。 この変更が自分のコードに影響を及ぼすかどうかを調べるには、.ini の設定を変更してみましょう。 mongo.native_int と mongo.long_as_object のデフォルトが TRUE になります。
シリアライズ: 1.1.0 より前のバージョンのデフォルトでは、 PHP の整数値はすべて 32 ビット整数値に変換されていました。 たとえ 64 ビットマシン上で動かしたとしてもです。 つまり、大きな数値は黙って切り詰められてしまうことになります。 1.1.0 からは、64 ビットマシン上ではデフォルトで 64 ビット整数値として扱うようになりました。 32 ビットマシンでは、これまでと同じように 32 ビット整数値となります (MongoInt32 クラスや MongoInt64 クラスを使えば、 64 ビットマシンで 32 ビット整数値を扱ったりその逆を行ったりすることができます)。
デシリアライズ: 1.1.0 より前のバージョンのデフォルトでは、 64 ビット整数値は double に復元されていました。 これは完全なマッピングではありません。この値を再度保存しようとすると間違った型になってしまいます (64 ビット整数ではなく double として保存されてしまいます)。 1.1.0 では、64 ビット整数値は 32 ビットマシン上では MongoInt64 として返されます。
MongoDB では、PHP のすべての基本データ型や複合型 (配列、連想配列 そしてオブジェクト) を保存したり問い合わせたりすることができます。 それ以外にも、MongoDB PHP ドライバには (正規表現や 日付、その他さまざまな用途に特化した) クラスが用意されています。
組み込みの型は次のとおりです。
型 | 説明 | MongoDB 内でのサイズ (バイト) |
---|---|---|
NULL | その名のとおり | 0 |
boolean | TRUE および FALSE | 1 |
int | 整数値 | 4 |
float | 浮動小数点値 | 8 |
string | UTF-8 文字列 | 文字列の長さ + 1 |
配列やオブジェクトもデータベースに格納することができます。 数値添字の配列は配列として、 それ以外のものはすべてオブジェクトとして格納されます。
<?php
// $scores は配列として格納されます
$scores = array(98, 100, 73, 85);
$collection->insert(array("scores" => $scores));
// $scores はオブジェクトとして格納されます
$scores = array("quiz1" => 98, "midterm" => 100, "quiz2" => 73, "final" => 85);
$collection->insert(array("scores" => $scores));
?>
データベースのシェルからこれらのオブジェクトを問い合わせると、このようになります。
> db.students.find() { "_id" : ObjectId("4b06beada9ad6390dab17c43"), "scores" : [ 98, 100, 73, 85 ] } { "_id" : ObjectId("4b06bebea9ad6390dab17c44"), "scores" : { "quiz1" : 98, "midterm" : 100, "quiz2" : 73, "final" : 85 } }
任意の PHP オブジェクトもデータベースに格納することができます (返されるときは連想配列となります)。 フィールドは キー/値 のペアに使います。 たとえば、blogへの投稿を表す次のようなオブジェクトを考えましょう。
<?php
// blog投稿クラス
class Post {
var $author;
var $content;
var $comments = array();
var $date;
public function __construct($author, $content) {
$this->author = $author;
$this->content = $content;
$this->date = new MongoDate();
}
public function setTitle($title) {
$this->title = $title;
}
}
// 単純なblog投稿を作り、データベースに追加します
$post1 = new Post("Adam", "This is a blog post");
$blog->insert($post1);
// "author" フィールドの型には何も制約がないので、
// オブジェクトをネストさせることができます
$author = array("name" => "Fred", "karma" => 42);
$post2 = new Post($author, "This is another blog post.");
// タイトルを設定して、別のフィールドを追加することができます
$post2->setTitle("Second Post");
$blog->insert($post2);
?>
データベースのシェルからは、次のように見えます。
> db.blog.find() { "_id" : ObjectId("4b06c263edb87a281e09dad8"), "author" : "Adam", "content" : "This is a blog post", "comments" : [ ], "date" : "Fri Nov 20 2009 11:22:59 GMT-0500 (EST)" } { "_id" : ObjectId("4b06c282edb87a281e09dad9"), "author" : { "name" : "Fred", "karma" : 42 }, "content" : "This is a blog post", "comments" : [ ], "date" : "Fri Nov 20 2009 11:23:30 GMT-0500 (EST)", "title" : "Second Post" }
このドライバは、配列やオブジェクトの循環参照を検出することができません。 たとえば、これは致命的なエラーとなります。
<?php
$collection->insert($GLOBALS);
?>
Fatal error: Nesting level too deep - recursive dependency?
Mongo PHP ドライバでは、データベースで使える新しい型もいくつか用意しています。 詳細や仕様例は、各クラスのドキュメントを参照ください。
型 | 説明 | MongoDB 内でのサイズ (バイト) |
---|---|---|
MongoBinData | バイナリデータ | バイナリデータのバイト数 + 5 |
MongoCode | JavaScript のコード | コードの文字列長 + スコープのオブジェクトサイズ |
MongoDate | エポックからの経過ミリ秒数で表した日付・時刻 | 8 |
MongoId | 一意なドキュメント id:
|
12 |
MongoMinKey | 他の何よりも小さい値 | |
MongoMaxKey | 他の何よりも大きい値 | |
MongoRegex | 正規表現 | 正規表現内の文字数 + フラグの数 |
MongoTimestamp | レプリケーションのタイムスタンプ | 8 |
MongoDB は "BSON" という格納フォーマットを使います。 これは Binary Serializable Object Notation の略で、 JSON と似ていますがよりコンパクトでさまざまな型を表現できます。 以下に、各型の正確なバイト数 (あるいは可変長の型の場合は サイズを算出するために必要な情報) をまとめました。 このサイズにはフィールド名は含まれていないことに注意しましょう。 オブジェクトのサイズは手動で算出することもできますが、プログラマなら bson_encode() 関数の返す文字列の長さを調べるほうが簡単でしょう。 string.
array("x" => null, "y" => 40) を保存するオブジェクトの BSON サイズを手動で算出する例です。
4 バイト (オブジェクトのサイズ) 1 バイト ("x" フィールドの型) 2 バイト ("x" および "\0") 0 バイト (null) 1 バイト ("y" フィールドの型) 2 バイト ("y" および "\0") 4 バイト (整数値) 1 バイト (オブジェクトの終端バイト) ----------------------- 15 バイト