Edited at
LaravelDay 20

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です