Phalcon3 + PHP7 + MongoDBを使う


[DockerでPhalconを動かして見る](http://qiita.com/yaaah93/items/c80a677ad336194c98fb)の続きです。
ドキュメント通りとはいかなくて少し手こずりました。

手こずった理由としては、PHP7でMongoDBのドライバが変わったため。
[PHP7で新しいMongoDBのドライバを使う](http://qiita.com/_takwat/items/1d1463d22a1316a2efbe)

ここまでは良かったもののいざPhalconで使うとした際に、つまづいたので備忘録程度に。。

## チュートリアル

一応載せておきますがPhalconのチュートリアル
https://docs.phalconphp.com/en/latest/db-odm

> Please note that if you are using the Mongo driver provided by PHP 7, the ODM will not work for you. There is an incubator adapter but all the Mongo code must be rewritten (new Bson type instead of arrays, no MongoId, no MongoDate, etc.). Please ensure that you test your code before upgrading to PHP 7 and/or Phalcon 3+

（2017/8/9時点）

ここにある incubator adapterとは何だろうと調べてたらphalcon/incubatorなるものがありました。
https://github.com/phalcon/incubator

これを参考にサンプルを作ります。

## インストール

まずはComposerでインストールします。

```bash
$ composer require phalcon/incubator
```

今回のサンプルではDockerで環境を作ってためしていたので上のComposerインストールはDockerのコンテナ内で実行してやる必要があるかと思います。
このあたりは私も自身がないところですが、私は以下の手順でDocker内でインストールを行いました。（他にやり方があれば教えてください）

```bash
$ docker exec -it <コンテナ> /bin/bash
# cd /public/app
# composer require phalcon/incubator
```

## ロード

incubatorのREADMEには`Phalcon/Loader`を使用した記載があります。

```php:public/index.php
$loader->registerNamespaces([
    'Phalcon' => '../app/vendor/phalcon/incubator/Library/Phalcon'
])->register();
```

これでも動きますがcomposerでインストールしてるので普通にautoloadをロードすることで使用することもできます。

```php:public/index.php
require_once('../app/vendor/autoload.php');
```

私はせっかくPhalconなので前者の`Phalcon/Loader`を使用して動作を確認しました。

## DB接続

先にソースを書くと以下のようなかんじになります。

```php:/public/index.php
$di->set('mongo', function() {
    $mongo = new Phalcon\Db\Adapter\MongoDB\Client(
        'mongodb://examplephalcon_mongo_1'
    );
    return $mongo->selectDatabase('example');
});
$di->set('collectionManager', function() {
    $manager = new Phalcon\Mvc\Collection\Manager();
    return $manager;
});
```

新しいPHPのMongoDBドライバを使用する場合は、`Phalcon\Db\Adapter\MongoDB\Client`を使用します。
前の書き方では`Phalcon\Db\Adapter\Mongo\Client`になります。

`MongoDB`なのか`Mongo`なのか、の違いなのでわかりくいですがこれでまずインスタンスを生成します。
次にデータベースを選択しますが、ここも書き方が変わっており、前の書き方では`$mongo->selectDB('example')`と書きます。

## モデルの定義

これも先にソースを書きます。

```php:/app/models/articles.php
use Phalcon\Mvc\MongoCollection;

class Articles extends MongoCollection
{
    public $title;
    public $body;
}
```

Phalconのチュートリアルでは`Phalcon\Mvc\Collection`で掲載されていますが、ドライバ変更の影響かここでは使えません。

## コントローラとビューの実装

ここまでくればあとはフレームワークを使われてる方なら馴染みの書き方になってきます。

```php:/public/app/controllers/IndexController.php
public function indexAction()
{
	$articles = Articles::find();
	$this->view->setVar('articles', $articles');
}
```

これでモデルからデータを取得してビューに値渡しをする流れになります。テンプレートエンジンはVoltを使ってるので下記のような書き方になります。

```php:/public/app/views/index/index.volt
<ul>
{% for article in articles %}
    <li>{{ article.title }}</li>
{% endfor %}
</ul>
```

説明をするほどでもないですが、`for`でループして実際データベースから取得した値はドットでわけて`<テーブル名>.<フィールド名>`となります。

まだまだ試せてないことが多いですがこれでCRUDで操作が可能となります。

## まとめ

Phalcon3だったり、PHP7の影響で情報を集めるのに手こずった感はありますが、`Phalcon/incubator`を入れたあとはわりとすんなりいけたのかなと思います。
まだまだ情報が少ないので調べものをしないといけないときは、英文から探した方が情報量は多くありました。
これからもっと深く動きや中身などを確認してみたいと思いますが、現在使ってるいるものがあるようであればバージョンには気をつけてください。