Help us understand the problem. What is going on with this article?

laravel4を使ったアプリケーション配布時の工夫

More than 5 years have passed since last update.

再び3回目の登場です。

ぼちぼち日本語情報も多くなってきましたので、
laravel4を採用して構築している企業や個人の方も多いのではないでしょうか?(すてき!)

アプリケーションをパッケージにして配布したい時に、
是非組込みたいものがあります。

migrate

laravel4はDBのセットアップも全てフレームワークがやってくれます。
それをコマンドから実行ではなく、
アプリケーションの中にセットアップ項目として取り込みます、というサンプルです。
ただし、先にDBとユーザー名、パスワードは作ってください! (4.1で追加された機能でできたりするのかな?)

まずmigrationsを作っていきます
ファイル名はテーブル名になります。
configuresという設定用テーブルを作るとします

app/database/migrations/YYYY_MM_DD_123456_configures.php
use Illuminate\Database\Migrations\Migration;

class Configures extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
        //create
        Schema::create('configures', function($table)
        {
            $table->increments('configure_id');
            $table->string('configure_name', 255);
            $table->text('configure_value');
            $table->timestamps();
            $table->index('configure_name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}

定義は上記の様に指定したとします。
routesも作ってしまいます

app/routes.php
Route::get('/setup', 'SetUpController@getSetup');
Route::get('/setup/start', 'SetUpController@getSetupStart');

セットアップ確認画面とセットアップ実行的なものをつくっておきましょう
最初はもちろんテーブル自体が存在しない為エラーになります。
とりあえずexception extendsします

適当なところ/DatabaseConfigException.php
class DatabaseConfigException extends \Exception{}

それではいざ実装!
大体みなさんDBだと思いますが、色んなパターンがあり得るでしょう!
より実務的にinterfaceから実装していきます。
場所はどこでも構いません。
例えばロジックはmodelsにまとめるのであれば・・

interface

app/models/Interfaces/DatastoreInterface.php
namespace Model\Interfaces;
interface DatastoreInterface {

    public function get();
}

model

app/models/DbMigrate.php
namespace Model;
use Illuminate\Support\Facades\DB;

class DbMigrate implements Interfaces\DatastoreInterface
{
    public function get()
    {
        try{
            // 
            return DB::connection()->table('configures')->get();

        }catch(\Exception $e){
            // configureテーブルが見つからない場合にthrow
            if(strpos($e->getMessage(), 'SQLSTATE[42S02]') !== false)
            {
                throw new \Extensions\DatabaseConfigException('configures data not found', 900);
            }
        }
    }
}

configuresテーブルが無ければ、アプリケーションに必要なテーブルが無い!
と扱います。

とりあえずmysql向けにしましたが、
アプリケーション利用者が必ずしもmysqlとは限らないはずなので、
他のdbの場合はimplementsして同じ様に実装してもらえればいいでしょう

controller実装

SetupController.php
use Illuminate\Support\Facades\Artisan;
class SetupController extends BaseController {

    private $_datastore;

    public function __construct(Model\Interfaces\DatastoreInterface $data)
    {
        $this->_datastore = $data;
    }

    public function getSetup()
    {
        try { 
            $this->_datastore->get();

        }catch(\Extensions\DatabaseConfigException $e){

            $configure = Config::get('database');
            $data = [
                'default' => $configure['default'],
                'connections' => $configure['connections'][$configure['default']]
            ];
            var_dump($data);
            var_dump(app_path() ."/config/". app()->environment() . "/database.php");
        }
    }

    /**
     * 
     */
    public function getSetupStart()
    {
        Artisan::call('migrate');

    }
}

DBが存在しない場合は、exceptionを投げてきますので、
catchして現在の環境を表示してみました。
database 1台環境のソースですので
databaseを複数使用されている場合は、driverとdefaultから見つけてあげましょう
環境ファイルのパスは恐らくそこにあるでしょう、ということで
利用者にそこのファイル内容を変更してくださいと促してみましょう。

完了後に/setup/startに遷移すれば、migrateが実行される様にしました。
コマンドが苦手なユーザーも、これで安心です

もちろん、このままではエラーですので、
App::bind('Model\Interfaces\DatastoreInterface', 'Model\DbMigrate');
を忘れずに!

という実装は如何でしょうか?\
明日は、websocket+redis pub/sub + laravel4です

ytake
著: Laravelリファレンス(インプレス) Laravelエキスパート養成読本(技術評論社) PHPフレームワーク Laravel Webアプリケーション開発 バージョン 5.5 LTS対応(ソシム)
https://blog.ytake.jp.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした