WinRoadのLaravel4初心者講座

次世代PHPフレームワークのLaravel4を初心者向けに解説して参ります。

Winroad徒然草の管理人がお届けします
Laravel4

HomesteadリポジトリのクローンとSSHキーの生成

Vagrantへboxを追加し終えたら、Homestedaリポジトリをクローンするのですが、ここから先は、Git Bashが必要になりますので、未導入の方は、WinRoad徒然草の「Windows8にGithubを導入する」を参照して、msysGitをインストールしてください。

Homesteadリポジトリのクローン

それでは、git Bushを起動したら、リポジトリをクローンします。Git Bashから下記のコマンドを入力します。

git clone https://github.com/laravel/homestead.git Homestead

C:\Users(ユーザー)\Hide(アカウント名)フォルダにHomesteadフォルダが作成されているはずです。

SSHキーの作成

リポジトリをクローンしたら、SSHキーを作成します。下記のnakada@gmail.comの部分はご自身のメールアドレスに変更してください。

ssh-keygen -t rsa -C “nakada@gmail.com”

すると、SSHキーの保存場所を訪ねてきますので、そのままエンターします。

Generating public/privata rsa key pair.
Enter file in which to save key (/c/Users/Hide/.ssh/id_rsa):

  • 尚、SSHキーの保存場所を変更したい場合は、保存場所を記述して、エンターします。※上記のHideの部分は、ユーザーアカウントです。ユーザーアカウントが漢字表記の時は、不具合が起こりますので、前もってユーザーアカウントはアルファベットにしておいてください。

パスフレーズ(パスワード)を訪ねてきますので、同じパスフレーズを2回入力します。※パスフレーズの入力内容は表示されませんので、ご注意ください。

Your identification has been saved in /c/Users/Hide/.ssh/id_rsa.
Your public key has been saved in /c/Users/Hide/.ssh/id_rsa.pub.
The key fingerprint is:
48:a8:bd:…….. nakada@gmail.com

と表示されたらSSHキーの生成は完了しました。

2014-06-09 14-51-01

SSHキーは、C:\Users\Hide\フォルダ内に、.sshフォルダが生成されているはずです。.sshフォルダをクリックすると、中に、id_rsaとid_rsa.pubファイルがあります。

2014-06-09 15-03-00

これで、SSHキーは生成されました。

VirtualBoxとVagrantのインストール

イントロダクションでも述べましたが、Homestead環境には、VirtualBoxとVagrantをインストールする必要があります。

VirtualBoxのインストール

VirtualBoxのインストールは、Windows徒然草の「Windows8にVirtualBoxのインストール」を参照してください。

※上記サイトでは、アカウントをデフォルトのユーザー(漢字名)に戻すと記述していましたが、漢字名のアカウントだといろいろな部分で、不都合が出ますので、Windowsのアカウント名はアルファベットにしておくことをお奨めします。

Vagrantのインストール

次に、下記のサイトからWindows用のVagrantをダウンロードします。

http://www.vagrantup.com/downloads.html

2014-06-06 8-31-13

ダウンロードしたvargant_1.6.3.msiファイルをダブルクリックすると、Vagrant Setupダイアログが起動しますので、Nextをクリックします。

2014-06-06 8-34-58

ライセンス契約書に目を通したら、「I accept the terms in the License Agreement」にチェックを入れ、Nextをクリックします。

インストールフォルダを選択後(デフォルトのままでよければそのまま)、Nextをクリックします。

2014-06-06 8-39-14

準備ができたら、Installをクリックします。

2014-06-06 8-40-52

インストールが完了し、Finishをクリックすると、パソコンの再起動を確認してきますので、よければ、Yesをクリックします。

2014-06-06 8-49-30

これで、Vagrantはインストールされました。

Vagrant Boxの追加

パソコンの再起動後、コマンドプロンプトを起動したら、下記のコマンドを入力します。

vagrant box add laravel/homestead

公式サイトでは、boxのダウンロードに数分かかると書いてありましたが、結構な時間がかかります。光でもダウンロード予測時間は4時間以上になっていました。

2014-06-06 9-06-19

ダウンロードにかなり時間がかかりそうなので、今日はここまでにします。

パソコンのスリープモード設定があるとダウンロードエラーになりますので、ダウンロード中はスリープモードは解除していてください。

※ダウンロードは、アクセスする時間帯と回線スピードによってかなり差が出るみたいです。早いときは、10分程度でダウンロードできます。

Homesteadのパッケージソフト

Homesteadでパッケージされているソフトウエア一覧です。

  • Ubuntu 14.04
    • Debian GNU/Linuxをベースとしたオペレーティングシステム(OS)です。
  • PHP5.5
  • Nginx
    • ロシアのlgor Sysoev氏によって開発されたWebサーバーで、エンジンエックスと呼びます。
    • Webサーバーといえば、50%以上のシェアを誇るApacheが有名ですが、Nginxはハイパフォーマンスかつメモリ消費量の少なさで、近年急激にシェアを伸ばしています。
  • MySQL
    • オープンソースのリレーショナルデータベース管理システムです。
  • Postgres
    • MySQL同様、オープンソースのリレーショナルデータベース管理システムです。
  • Node(BowerとGrunt、Gulpも含む)
    • Node.jsはサーバーサイドのJavaScriptインタープリターで、軽量で効率よく多くのリクエストを処理するネットワークアプリケーションの構築が出来るプラットフォームです。
    • BowerとはTwitterr社が作ったフロントエンドのパッケージマネージャ(パッケージの管理ツール)です。
    • Gruntとは、Node.jsを使用したCUIのビルドツールで、CSSやJavascriptのminify(軽量化)などの作業をタスクを設定して、自動化します。
    • Gulpとは、Gruntに対抗して作成されたビルドツールで、Gruntのよい所を引き継ぎつつ、Gruntの短所を吸収するために開発されています。
  • Redis
    • Redisとは、「Remoto Dictionary Server」から名付けられたオープンソースのキーバリューストアでNoSQLに分類されます。
    • 全てのデータをメモリ上に保存するため処理がきわめて高速で、伝統的なリレーショナルデータベースに代わるデータ管理システムとして近年注目されています。
  • Memcached
    • Redis同様、オープンソースのキーバリューストアでNoSQLに分類されます。
  • Beanstalkd
    • AWS(Amazon Web Servicre)クラウドのアプリケーションを迅速にデプロイして管理できるツールです。
    • キュー処理のプログラムです。
  • Laravel Envoy
  • Fabric+HipChat拡張

Laravel Homesteadとは(イントロダクション)

Laravel4.2から、Laravel Homesteadの章が追加されました。そこで、Laravel Homesteadについて調べてみたいと思います。

公式サイトを読んだ限りでは、仮想マシン上に、ほんの数分で、OS、Nginx、PHP5.5、MySQL、Postgres、Redis、Memcached等のLaravelアプリケーションを開発するための環境を提供してくれるツールだと記述されています。

詳しいインストール方法は、「インストールと準備」でご紹介するとして、今日は、そのHomestead環境を起動する前に必要な、VirtualBoxとVagrantについて調べてみたいと思います。

VirtualBoxとは

VitrtualBoxとは、オープンソースの仮想化ソフトウエアの一つで、元々は、Sun Microsytems社が開発していましたが、同社がOracle社により買収されたため、現在では、Oracle社が開発元となっており、正式名称も「Oracle VM VirtualBox」となっています。

Vagrant(ベイグラント)とは

Vagrantとは、Mitchel Hashimoto氏により開発された「仮想マシンのテンプレートツール」です。つまり、VirtualBoxやVMWareのような仮想化ソフト内に、「ほんの数行書くだけで開発用の仮想マシンを構築できる」すぐれもののツールです。

また、構築するだけでなく、破棄も簡単にできるため、開発環境を「作っては、壊す」という作業が簡単にできるのです。

以下にVagantの代表的な機能について簡単にご紹介します。

  • Box
    • 環境を構築するためのテンプレート
    • このBoxの中に事前にインストールされたOS等がインストールされています。
  • Vagrantfile
    • プロジェクトごとの設定ファイル
  • vagrantコマンド
    • 端末で実行するためのコマンド
  • Synced Folder
    • ホストとゲスト間でフォルダを共有する機能
  • Networking
    • ホストとゲスト間で自由にネットワークを共有できる機能

Homesteadとは

つまり、Homesteadとは、事前にパッケージされたLaravelアプリケーション開発用の Box(テンプレート)で、現在、Vagrant1.6上で構築・テストされています。

カスタムマクロ

カスタムマクロ機能を使うとFormクラスのヘルパーを簡単に定義することができます。

Form::macroの第1引数は、マクロ名、第2引数にクロージャー(無名関数)を登録します。そして、登録したカスタムマクロは、Form::マクロ名で実行することができます。

それでは、簡単にご紹介しましょう。まず、コントローラーでカスタムマクロを登録します。

public function getIndex(){
 Form::macro('h1',function(){
 return '<h1>';
 });
 Form::macro('h1End',function(){
 return '</h1>';
 });
 $animal=['Cats'=>['leopard'=>'Leopard'],
 'Dogs'=>['sppanies'=>'Spaniel']];
 return View::make('home.index',compact('animal'));
 }

上記は、単純にForm::h1で、h1開始タグを生成し、Fom::h1Endでh1終了タグを生成します。

ビューファイルで上記カスタムマクロを使用してみます。

@extends('layout')
 @section('content')
 {{Form::open()}}
 {{Form::h1()}}
 {{Form::select('animal',$animal)}}
 {{Form::submit('送信')}}
 {{Form::h1End()}}
 {{Form::close()}}
 @stop

下記のようにForm::h1からForm::h1Endまでの間が<h1>タグで囲まれているのがわかると思います。

2014-06-09 12-08-15

上記のように、コントローラ内でカスタムマクロを登録してもいいのですが、カスタムマクロ専用のファイルを作成して、それを読み込むようにした方が使いやすいと思います。

尚、カスタムマクロの詳細な使い方は、実践編の「フォームマクロ」をご参照ください。

ドロップダウンリストの生成

Form::selectメソッドで、ドロップダウンリストを生成することができます。

Fome::select(フィールド名,リストの配列,初期値)

Form::selectメソッドは、第1引数にフィールド名、第2引数に、リストの配列を指定します。第3引数はオプションで、選択済みの初期(デフォルト)値を指定することができます。

それでは、実例をご紹介しましょう。まず、コントローラから値をビューファイルに引き渡します。

public function getIndex(){
 $roles=Role::lists('name','id');
 return View::make('home.index',compact('roles'));
 }

ビューファイルでドロップダウンリストから選択して、データを送信します。

{{Form::open()}}
 <p>Roleを選択してください</p>
 {{Form::select('role',$roles)}}
 {{Form::submit('送信')}}
 {{Form::close()}}

2014-06-07 0-36-45

受信したデータは下記のように表示されます。

public function postIndex(){
 return var_dump(Input::all());
 }

2014-06-07 0-39-47

グループ分けしたリストを表示

データを多重配列にすることで、グループ分けのリストを生成することができます。

それでは、実例をご紹介します。まず、コントローラからデータをビューに引き渡します。

public function getIndex(){
 $animal=['Cats'=>['leopard'=>'Leopard'],
 'Dogs'=>['sppaniel'=>'Spaniel']];
 return View::make('home.index',compact('animal'));
 }

ビューファイルのリストは下記のようになります。

@extends('layout')
 @section('content')
 {{Form::open()}}
 {{Form::select('animal',$animal)}}
 {{Form::submit('送信')}}
 {{Form::close()}}
 @stop

2014-06-09 10-45-54

受信したデータは下記のようになります。

public function postIndex(){
 return var_dump(Input::all());
 }

2014-06-09 10-54-25

selectRange(フィールド名,開始数値,終了数値)

selectRangeメソッドを使用すると数値の範囲を指定して、ドロップダウンリストを生成することができます。

selectRangeメソッドの第1引数には、フィールド名、第2引数には、開始数値、第2引数には終了数値を指定します。

{{Form::open()}}
 {{Form::selectRange('number',10,20)}}
 {{Form::submit('送信')}}
 {{Form::close()}}

2014-06-09 11-04-07

尚、開始数値が、終了数値より大きければ、数値が降順で表示されます。

selectMonth(フィールド名)

selectMonthメソッドを使用すると、月名のリストを生成します。

@extends('layout')
 @section('content')
 {{Form::open()}}
 {{Form::selectMonth('month')}}
 {{Form::submit('送信')}}
 {{Form::close()}}
 @stop

2014-06-09 11-10-51

尚、受信したデータはそれぞれの月に応じた数値です。

public function postIndex(){
 return var_dump(Input::all());
 }

2014-06-09 11-14-05

※上記のようにJanuaryを選択すると、数値の1を取得しますし、Decemberを選択すると数値の12を取得します。

チェックボックスとラジオボタン

Form::checkboxでチェックボックス、Form::radioでラジオボタンを生成します。

Form::checkbox(フィールド名、値、チェック済みの有無)

Form::checkboxはチェックボックスタグを生成します。第1引数に、フィールド名、第2引数に値を指定します。第3引数は、オプションで、チェック済みの有無を指定します。チェック済みcheckboxを生成するには、第3引数にtrueを指定します。

それでは、実際にチェックボックスを作成してデータを送信してみましょう。

{{Form::open()}}
 <p>あなたの趣味にチェックを入れてください</p>
 {{Form::label('読書')}}
 {{Form::checkbox('hobby[]','読書')}}
 {{Form::label('映画')}}
 {{Form::checkbox('hobby[]','映画')}}
 {{Form::submit('送信')}}
 {{Form::close()}}

2014-06-06 15-14-38

上記のビューファイルからデータを受信すると下記のようになります。

2014-06-06 15-17-44

チェックボックスのフィールド名は配列にしてください。下記のようにフィールド名を配列にしなければ、最後にチェックした値しか送信されません。

{{Form::open()}}
 <p>あなたの趣味にチェックを入れてください</p>
 {{Form::label('読書')}}
 {{Form::checkbox('hobby','読書')}}
 {{Form::label('映画')}}
 {{Form::checkbox('hobby','映画')}}
 {{Form::submit('送信')}}
 {{Form::close()}}

上記の場合は、両方にチェックを入ても、下記のように最後にチェックした値(映画)しか送信されません。※なお、すべてのチェックボックスのフィールド名を別々に指定する方法はありますが。

2014-06-06 15-25-28

Form::radio(フィールド名、値、チェック済みの有無)

Form::radioはチェックボックスタグを生成します。第1引数に、フィールド名、第2引数に値を指定します。第3引数は、オプションで、チェック済みの有無を指定します。チェック済みラジオボタンを生成するには、第3引数にtrueを指定します。

それでは、実際にラジオボタンを作成してデータを送信してみましょう。

<p>性別をチェックしてください</p>
 {{Form::label('男性')}}
 {{Form::radio('sex','男性',true)}}
 {{Form::label('女性')}}
 {{Form::radio('sex','女性')}}
 {{Form::submit('送信')}}
 {{Form::close()}}

2014-06-06 15-44-05

複数の選択肢の中から一つだけを選択してもらう場合にラジオボタンを使用しますので、ラジオボタンの場合は、どちらかしかチェックできません。

上記のビューファイルからデータを受信すると下記のようになります。

2014-06-06 15-44-35

Formのテキストフィールド等の生成

Form::textメソッドで、テキストフィールドを生成します。同様なフィールドを生成するメソッドに、Form::textarea、Form::password、Form::email、Form::hidden、Form::file等があります。

Form::text(フィールド名,デフォルト値、属性)

Form::textメソッドは、第1引数に、フィールド名、第2、第3引数にはオプションで、第2引数には、デフォルト値、第3引数には属性を配列で指定します。

{{Form::text(‘title’,’WinRoad徒然草’,[‘class’=>’top_title’])}}

上記は、下記のようなタグを生成します。

<input class=”top_titlename=”titletype=”textvalue=”WinRoad徒然草“>

Form::textarea(フィールド名、デフォルト値、属性)

Form::textareaメソッドは、第1引数に、フィールド名、第2、第3引数にはオプションで、第2引数には、デフォルト値、第3引数には属性を配列で指定します。

{{Form::textarea(‘body’,”,[‘placeholder’=>’ここに本文を入力してください’])}}

上記は下記のようなタグを生成します。

<textarea placeholder=”ここに本文を入力してくださいname=”bodycols=”50rows=”10“></textarea>

Form::password(フィールド名)

Form::passwordメソッドは、第1引数にフィールド名を指定します。第2引数は、デフォルト値ではなく、属性の配列を指定します。

{{Form::password(‘password’,[‘placeholder’=>’パスワードを入力してください’])}}

上記は下記のようなタグを生成します。

<input placeholder=”パスワードを入力してくださいname=”passwordtype=”passwordvalue=”“>

 Form::email(フィールド名、デフォルト値、属性)

Form::emailメソッドは、第1引数にフィールド名を指定します。第2引数はオプションでデフォルト値、第3引数もオプションで属性の配列を指定します。

{{Form::email(‘email’,”,[‘placeholder’=>’Eメール’])}}

上記は、下記のようなタグを生成します。

<input placeholder=”Eメールname=”emailtype=”emailvalue=”“>

Form::hidden(フィールド名、デフォルト値、属性)

Form::hiddenメソッドは、第1引数にフィールド名、第2引数にオプションでデフォルト値、第3引数もオプションで属性の配列を指定します。

{{Form::hidden(‘my_id’,’123′)}}

上記は、下記のようなタグを生成します。

<input name=”my_idtype=”hiddenvalue=”123“>

Form::file(フィールド名、属性)

Form::fileメソッドは、第1引数にフィールド名、第2引数はオプションで属性の配列を指定します。

{{Form::file(‘photo’,[‘accept’=>’image/*’])}}

上記は、下記のようなタグを生成します。

<input accept=”image/*name=”phototype=”file“>

※なお、ファイルをアップするには、Form::openのfilesオプションをtrueにセットする必要があります。

{{Form::open(['files'=>true])}}
{{From::file('photo')}}
{{Form::submit('送信')}}
{{Form::close()}}

Formのラベル生成

Form::labelメソッドで、ラベル要素を生成することができます。

Form::label(‘ラベル名’,’ラベル表示名’)

Form::labelメソッドは、第1引数にラベル名、第2引数にラベル表示名、第3引数にオプションでパラメーターの配列を指定します。

※ラベルとフォーム要素(フィールド)名を同じにすれば、自動的にラベル名のIDが生成されます。

下記で比較してみます。まず、ラベル名とフィールド名を別々で記述してみます。

{{Form::open()}}
 {{From::label('simei','名前')}}
 {{Form::text('name')}}
 {{Form::submit('送信')}}
 {{Form::close()}}

上記は、下記のようなタグを生成します。

<form method=”POSTaction=”http://localhost:8000accept-charset=”UTF-8“>
<input name=”_tokentype=”hiddenvalue=”prGbeGRDKipmWpH66AD4tCyORxWQdwzOhXnSmN7N“>
<label for=”simei“>名前</label>
<input name=”nametype=”text“>
<input type=”submitvalue=”送信“>
</form>

これに対して、ラベル名を下記のように同じにしてみます。

{{Form::open()}}
 {{Form::label('name','名前')}}
 {{Form::text('name')}}
 {{Form::submit('送信')}}
 {{Form::close()}}

上記は、下記のようなタグを生成します。

<form method=”POSTaction=”http://localhost:8000accept-charset=”UTF-8“>
<input name=”_tokentype=”hiddenvalue=”prGbeGRDKipmWpH66AD4tCyORxWQdwzOhXnSmN7N“>
<label for=”name“>名前</label>
<input name=”nametype=”textid=”name“>
<input type=”submitvalue=”送信“>
</form>

  • ‘id’=’name’が生成されています。

Formとモデルの結合

Form::openの代わりに、Form::modelメソッドを使うと、Formの要素にモデルのプロパティ(テーブルのフィールド)を紐付けることが出来るようになります。

Form::modelメソッドの第1引数には、モデルのオブジェクト、第2引数には、オプションでパラメーターを配列で指定します。

(例)それでは、実例を挙げてみましょう。

  1. コントローラから下記のようにデータをビューファイルに引き渡します。
  2. <?php
     class UserController extends BaseController{
     public function getUpdate($id){
     $user=user::find($id);
     return View::make('user.update',compact('user'));
     }
     }
  3. そして、ビューファイル(app/views/user/update.blade.php)のフォームとモデルを結合します。
  4. @extends('layout')
     @section('content')
     {{Form::model($user)}}
     {{Form::text('username')}}
     {{Form::text('email')}}
     {{Form::hidden('id')}}
     {{Form::submit('更新')}}
     {{Form::close()}}
     @stop
  5. Form::modelでフォームとモデルを結合すると、Form::textの第2引数に、デフォルト値を指定しなくても、フォームのフィールドに、$user->usernameや$user->emailの値を表示します。つまり、上記は、下記と同じになります。
  6. @extends('layout')
     @section('content')
     {{Form::open()}}
     {{Form::text('username',$user->username)}}
     {{Form::text('email,$user->email)}}
     {{Form::hidden('id',$user->id)}}
     {{From::submit('更新')}}
     {{Form::close()}}
  7. Form::modelメソッドの便利なところは、これだけでは、ありません。セッションのフラッシュデータがある場合(バリデーションエラーで元のページへ戻された場合)には、デフォルト値が、直前の入力値(フラッシュデータ)に置き換わります。
  8. public function postUpdate(){
     $inputs=Input::except('_token');
     $rules=['username'=>'require','email'=>'require|emai'];
     $val=Validator::make($inputs,$rules);
     if($val->fails()){
     return Redirect::back()->withInput();
     }
     }
  9. つまり、上記のような場合は、フォームのデフォルト値は、直前値に変わります。ですので、実際に、Form::modelメソッドをForm::openメソッドで記述すると、下記のようになります。
  10. @extends('layout')
     @section('content')
     {{Form::open()}}
     {{Form::text('name',Session::get('username',$user->username))}}
     {{Form::text('email',Session::get('email',$user->email))}}
     {{Form::hidden('id',$user->id)}}
     {{Form::submit('更新')}}
     {{Form::close()}}
     @stop

尚、Form::modelメソッドで、フォームを開始した場合、かならずForm::closeメソッドで終了するようにしてください。