このサイトはLaravel + MongoDBで作られているが
LaravelはデフォルトでMongoDBをサポートしてないので
専用のライブラリをインストール!
このサイトの前身となるサイト(ver2 part1)を作った時に初めてMongoDBを使ってみて、RDBMSと比べてテーブルの関係性やSQL文を気にせず使えるNoSQLって凄くいいな!と感じたので今回もMongoDBを使ってみたのですが、LaravelはデフォルトでMongoDBをサポートしていないみたいだったので
https://github.com/jenssegers/laravel-mongodb
こちらのライブラリを使用してLaravelからMongoDBを使えるようにしました。
LaravelとMongoDBとの接続の部分で結構詰まってしまったので、その部分も含めてLaravelのサイトを動かすための手順をメモっていきます。
OS・ミドルウェアなどのバージョンは以下の通りです。
OS … Ubuntu 16.04
PHP … 7.2.2
Nginx … 1.12.2
MongoDB … 3.6.2
composer … 1.6.3
Laravel … 5.5.28
Vagrantで作った仮想環境でサイトを作っていきます。
Vagrantfileの中身は以下の通りです。
Vagrant.configure("2") do |config| config.vm.box = "bento/ubuntu-16.04" config.vm.network "private_network", ip: "192.168.35.10" end
以下のコマンドを打っていきます
# php 7.2系と必要な拡張機能をインストール sudo apt -y install software-properties-common sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt -y install php7.2 php7.2-dev php7.2-dom php7.2-fpm php7.2-mbstring php7.2-mongodb php-pear pkg-config libssl-dev # composer をインストール curl -sS https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer # Nginx をインストール curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add - VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list" VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb-src http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list" sudo apt update sudo apt -y install nginx # MongoDB 3.6系をインストール sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5 echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list sudo apt update sudo apt install -y mongodb-org # Laravel のプロジェクトを作成 sudo apt -y install php7.2-zip composer create-project --prefer-dist "laravel/laravel=5.5.*" test # 新しく作られたtestディレクトリ内にLaravelのコードなど一式が入っているはず
MongoDBを使うためのライブラリを入れる前に一旦素の状態のLaravelを起動させてみます。
まずはNginxでPHPを実行できるように /etc/nginx/conf.d/default.conf ファイルを変更します。
ファイルの中身は以下の通りです。
server { listen 80; server_name localhost; root /home/vagrant/test/public; location / { index index.php; try_files $uri $uri /index.php$is_args$args; } location ~ .php$ { fastcgi_pass unix:/run/php/php7.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } }
php-fpmとLaravelはデフォルトの状態だと権限周りのエラーが出てしまうので、以下のコマンドで権限を変更しNginxを起動します。
sudo chmod 666 /run/php/php7.2-fpm.sock chmod 777 ~/test/storage/logs/ chmod 777 ~/test/storage/framework/views/ sudo service nginx start
これでNginxが起動したので、ブラウザを開いてアクセスすると・・・
Laravelのデフォルトページが表示されました!
Laravelのデフォルトページが開くことが確認できたので、本題のMongoDBの部分に入っていきます。
まずは以下のコマンドでライブラリをインストールします。
cd ~/test composer require "jenssegers/mongodb=^3.3"
次に、インストールしたライブラリをLaravelから使えるようにするためにconfigディレクトリ内のファイルを編集していきます。
まずは、 ~/test/config/app.php に以下の内容を加えます。
return [ // 略 'providers' => [ // 略 Jenssegers\Mongodb\MongodbServiceProvider::class, ], 'aliases' => [ // 略 'Moloquent' => Jenssegers\Mongodb\Eloquent\Model::class, ], ];
MongoDBを使うためのクラスをLaravelのコードから呼び出せるように設定しました。
次に、 ~/test/config/database.php に以下の内容を追加します。
return [ // 略 //'default' => env('DB_CONNECTION', 'mysql'), 'default' => env('DB_CONNECTION', 'mongodb'), // 略 'connections' => [ 'mongodb' => [ 'driver' => 'mongodb', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', 27017), 'database' => env('DB_DATABASE', 'testDB'), ], ], // 略 ];
最後に、 ~/test/.env ファイルの以下の部分を変更します。
#DB_CONNECTION=mysql #DB_HOST=127.0.0.1 #DB_PORT=3306 #DB_DATABASE=homestead #DB_USERNAME=homestead #DB_PASSWORD=secret DB_CONNECTION=mongodb DB_HOST=127.0.0.1 DB_PORT=27017 DB_DATABASE=testDB
LaravelがMongoDBを使う時の設定を追加し、デフォルトの状態でDBに接続するときはMySQLではなくMongoDBを使うように変更しました。
Laravelの設定を変更した際は、Laravelが保存している過去のキャッシュのせいでエラーが出てしまうので、以下のコマンドを打っておきます。
php ~/test/artisan cache:clear
これでLaravelからMongoDBを使うための準備は全て終わったので、実際にMongoDBから値を取ってきて表示するコードを書いていきます。
まずはルーティングを作るために ~/test/routes/web.php を以下の内容に変更します。
<?php Route::get('/', 'TestController@index');
これでルートディレクトリにアクセスした際にTestControllerのindexメソッドが呼び出されるようになりました。
次はこのコントローラーを作ります。
ファイルパスは ~/test/app/Http/Controllers/TestController.php で、内容は以下の通りです。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; class TestController extends Controller { static function index() { $posts = Post::orderBy('_id', 'desc')->get(); return view('index', ['posts' => $posts]); } }
Postモデルからデータを取得してindexというviewに取得したデータをそのまま渡しています。
次はこのPostモデルを作っていきます。
ファイルパスは ~/test/app/Post.php で、内容は以下の通りです。
<?php namespace App; class Post extends \Moloquent { protected $collection = 'post'; }
使う機能は継承元のMoloquentクラスのものをそのまま使うので、postコレクションから値を取ってくるぞ!ということだけを書いておきます。
最後に実際に画面に表示するviewを作っていきます。
ファイルパスは ~/test/resources/views/index.blade.php で、内容は以下の通りです。
<div>全部で{{ count($posts) }}件</div> <ul> @foreach($posts as $post) <li>{{ $post['date'] . ' | ' . $post['body'] }}</li> @endforeach </ul>
これでコーディング部分は全て終わったので、MongoDBに実際にデータを入れて、正しく表示されるかを確認してみます。
まずは以下のコマンドでMongoDBを起動します。
sudo service mongod start
次にMongoDBにデータを入れていきます。
コマンドでぽちぽち入れていくのはしんどいのでRobo 3Tというクライアントソフトを使いました。
こんな感じでデータを入れてもう一度ブラウザでアクセスすると・・・
MongoDBのデータが反映されました!
この記事を書いてる途中でLaravel5.6がリリースされたのでそっちでも試してみたのですが、
composer require "jenssegers/mongodb=^3.3"
コマンドを打った時にエラーが出てしまった(このライブラリがLaravel5.6に対応していない?)ので断念することに・・・