WinRoadのLaravel4初心者講座

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

Winroad徒然草の管理人がお届けします
逆引き辞典

スマホと携帯を振り分けるには

スマートフォンが普及したとはいえ、未だに携帯(ガラケー)ユーザーは健在です。ですので、携帯ユーザーのためには、携帯専用のサイトを提供したいので、スマートフォンと携帯の振り分け方法について調べてみたいと思います。

いろいろな振り分け方法があるとは思いますが、今回はフィルターとブレードレイアウトを利用して振り分ける方法を調べてみたいと思います。

まず最初に考えた手順は、

  1. フィルターのApp::beforeメソッドで、ユーザーエージェントを取得します。
  2. 次に、取得したユーザーエージェントごとに、layout名のセッションを作成します。
  3. そして、ブレードテンプレートのextendsメソッドで、そのセッションを読み込む

という方法です。

それでは実際に作業してみましょう。

app/filter.php

App::before(function($request)
 {
 //ユーザーエージェントの取得
 $ua = $_SERVER['HTTP_USER_AGENT'];
if ((strpos($ua, 'Android') !== false) &&
 (strpos($ua, 'Mobile') !== false) ||
 (strpos($ua, 'iPhone') !== false) ||
 (strpos($ua, 'Windows Phone') !== false)) {
 // スマートフォンからアクセスされた場合
 Session::put('layout','jqm');
} elseif ((strpos($ua, 'Android') !== false) ||
 (strpos($ua, 'iPad') !== false)) {
 // タブレットからアクセスされた場合
 Session::put('layout','f5');
} elseif ((strpos($ua, 'DoCoMo') !== false) ||
 (strpos($ua, 'KDDI') !== false) ||
 (strpos($ua, 'SoftBank') !== false) ||
 (strpos($ua, 'Vodafone') !== false) ||
 (strpos($ua, 'J-PHONE') !== false)) {
 // 携帯からアクセスされた場合
 Session::put('layout','mobile');
} else {
 // その他(PC)からアクセスされた場合
 Session::put('layout','tbs');
 }
});
  • 4行目:まず最初にユーザーエージェントを取得します。
  • 5-26行目:そして、取得したユーザーエージェントの文字列からアクセスしてきた端末の種類を判別します。
  • 5-6行目:Androidのスマートフォンには、Androidという文字列とMobileという文字列が含まれているのが一般的ですので、この2つの文字列が含まれていたら、Androidスマートフォンと判断します。
  • 7-8行目:iPhoneとWindowsフォンの場合は、それぞれの文字が含まれていますので、それで判断します。
  • 10行目:そして、スマートフォンからアクセスされた場合は、セッションlayoutにjqmという文字列を登録します。
  • この文字列を、ブレードテンプレートの@extends(Session::get(‘layout))で、指定すれば、スマートフォンの時には、app/viewsフォルダにあるjqm.blade.phpファイルをブレードレイアウトとして、読み込みます。
  • 以下、タブレット、携帯、PCの場合も同様です。
  • 上記では、例として、スマートフォン用にjquerymobileを使用したCSSを用意し、タブレット用にはfoundation5を使用したCSS、携帯には携帯用のCSS、それ以外には、twitter Bootstrapを使用したCSSを用意するつもりです。
    • スマートフォン用
      app/views/jqm.blade.php
    • タブレット用
      app/views/f5.blade.php
    • 携帯用
      app/views/mobile.blade.php
    • PC用
      app/views/tbs.blade.php

この方法は、ユーザーエージェントにより、元になるブレードテンプレートを変更し、それぞれのスタイルシートでスマートフォン用、タブレット用、携帯用、PC用と変更します。

次に各デバイス用のテンプレートページを作成します。

(例)app/views/jqm.blade.php

<!DOCTYPE html>
<html lang="ja">
 <head>
 <title>Builwing</title>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
{{HTML::style('//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.css')}}
{{HTML::script('//code.jquery.com/jquery-2.1.0.min.js')}}
{{HTML::script('//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js')}}
</head>
<body>
<div data-role="page" id="page1">
 <div data-role="header">
 <h1>Builwing</h1>
 </div><!-- /header -->
 <div role="main" class="ui-content">
 @yield('content')
 </div><!-- /main -->
 <div data-role="footer">
 <h4>Page Footer</h4>
 </div><!-- /footer -->
</div><!--page-->
</body>
</html>
  • 上記は、jquerymobileのCDNを利用して作成しています。

(例)app/views/tbs.blade.php

<!DOCTYPE html>
<html lang="ja">
 <head>
 <title>Builwing</title>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <!-- Bootstrap -->
 {{HTML::style('tbs/css/bootstrap.min.css')}}
 {{HTML::style('tbs/css/mystyle.css')}}
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
 <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
 <!--[if lt IE 9]>
 <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
 <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
 <![endif]-->
 </head>
 <body>
 <div class="content">
 <div class="container">
 @yield("content")
 </div>
 </div>
 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
 <script src="https://code.jquery.com/jquery.js"></script>
 <!-- Include all compiled plugins (below), or include individual files as needed -->
 {{ HTML::script('tbs/js/bootstrap.min.js') }}
 </body>
</html>
  • 上記は、ダウンロードしてきたTwitter Bootstrapをapp/public/tbsフォルダ内に保存しているものとして作成しています。

そして、最後にコンテンツページでブレードテンプレートを指定すれば完成です。

(例)app/views/user/index.blade.php

@extends(Session::get('layout'))
@section('content')
<h2>ユーザーページ</h2>
ここにコンテンツを入力します。
@stop

この方法だと同じコントローラでデバイスごとのページを作成することができますが、きちんと携帯用のサイトを作成したい方は、Session::put()の場所を、return redirect::to()で移動したいページ(コントローラ)を指定してください。

Twitter BootstrapやFoundation5等のCSSフレームワークがレスポンシブWebデザインを主流として台頭していますが、それは、あくまでもスマートフォン以上のデバイスが中心です。今でもかなりの数を占めている携帯にはやはり携帯用のサイトが依然として必要な状況には変わりありません。

ですので、携帯(ガラケー)には、携帯用のサイトを作成するのも大切だと思います。とりあえず、ガラケー専用のサイトを作成しなくてもCSSのみでもある程度は対応できるはずです。

他にもいい振り分け方や携帯サイトの簡単な作成方法があればご伝授ください。

リストに項目を追加するには

データベーステーブルからリストを取得するには、listsメソッドを使用します。

lists(値,キーカラム)

listsメソッドは、第1引数にリストの値、オプションで第2引数にリストのキーカラムを指定します。

(例)

$user=User::where(‘role_id’,’>=’,70)->lists(‘name’,’id’);
return View::make(‘tanto/create’,compact(‘user’));

  • 上記の例では、role_idが70以上のユーザーを$userリストとして、ビューに引き渡しています。
  • そして下記のビューでユーザー名からユーザーIDを取得することができます。

{{Form::open()}}
{{Form::select(‘user_id’,$user)}}
{{Form::submit()}}

  • ただ、上記の場合は、データベーステーブルからのユーザーIDしか取得することができません。
  • しかし、たまに、データベーステーブル以外の値も追加したいときが発生します。
  • そんなときは、下記のarray_addヘルパー関数を使います。

array_add($配列,キー,値);

array_add関数は、第1引数に、元になる配列を指定します。この配列に、第2引数と第3引数で指定したキーと値を追加します。

それでは、実践してみましょう。

$user=User::where(‘role_id’,’>=’,70)->lists(‘name’,’id’);
$user=array_add($user,”,’無し’);
return View::make(‘tanto/create’,compact(‘user’);

  • 上記の場合は、$userリストに、usersテーブル以外の値を追加することができます。
  • 今回の例では、キーが空白で、値(リストの表示名)が無しのリストを追加することができました。

上記の例では、ビューファイルでのリストの表示は、「無し」が表示されますが、送信されるデータ(Input::get(‘user_id))は空白です。

NULL値を代入したい場合

普通にInput::getで受信した値をデータベースに書き戻した場合、上記のように空白を指定した場合、データベーステーブルには空白値や0が代入されます。

(例)

$tanto=Tanto::find($id);
$tanto->user_id=Input::get(‘user_id’);
$tanto->save();

そこで、下記のように三項演算子を使用すれば、データベーステーブルにNULL値を代入することができます。

$tanto=Tanto::find($id);
$tanto->user_id=Input::get(‘user_id’) ? : null;
$tanto->save();

この三項演算子を使用しなければ、下記のように書かなくてはいけなくなります。

$tanto=Tanto::find($id);
if(Input::has(‘user_id’)):
$tanto->user_id=Input::get(‘user_id’);
else:
$tanto->user_id=null;
endif;
$tanto->save();

三項演算子は使い慣れるとかなり便利ですので、皆さんも多用してください。

フォームから値を取得するには

フォームから値を取得するには、基本的に一つの値を取得するには、Input::get()メソッド、全ての値(キーと値の連想配列)を取得するには、Input::all()メソッドを使用します。下記にフォームからのデータの取得方法を記述しておきます。

Input::get(‘キー’)

第1引数で指定したキー(フィールド名)の値を取得します。POSTで送られたデータもGETで送られたデータも同じように取得することができます。オプションで、第2引数に入力値が存在しない場合のデフォルト値を指定することができます。
(例)Input::get(‘name’,’Sally’);

Input::all();

リクエストの全入力値のキーと値の連想配列を取得します。

Input::only(‘key’,’key’,….);

引数で、指定したキーのキーと配列の連想配列を取得します。

Input::except(‘key’,’key’,….);

引数で指定したキー以外のキーと値の連想配列を取得します。

フィルターを適用するには

フィルターを適用するには、大きく分けて、ルーターで指定する場合と、コントローラーで指定する場合があります。

ルーターでフィルターを指定

ルーターでフィルターを指定するには、第2引数に配列で指定します。

Route::get(‘URI’,array(‘before’=>フィルター名,function(){
//ロジック
}));

フィルターパラメーターの指定

上記のルーターでフィルターにパラメーターを指定することもできます。

基本例
Route::get('user', array('before' => 'age:200', function(){
 return 'Hello World';
 }));

コントローラーでフィルターを指定

コントローラでフィルターを指定するには、基本的にコンストラクター内で指定します。

$this->beforeFilter(フィルター名);

beforeFilterメソッドや、afterFilterメソッドで、フィルターを指定します。第2引数は、オプションで、フィルターの適用条件を指定します。

適用条件
  • on
    POSTやGET、DELETE等のHTTPメソッドを指定して適用条件とします。
  • only
    適用するコントローラアクションを限定します。
  • except
    適用するコントローラアクションを除外します。
基本例
<?php
 class UserController extends BaseController{
 /*
 |----------------------------------------
 | コンストラクター
 |----------------------------------------
 */
 public function __construct(){
 //authフィルター
 $this->beforeFilter('auth',array(
 //フィルター適用の指定
 'only'=>array('getIndex')));
 //全POSTにcsrfフィルターの適用
 $this->beforeFilter('csrf',array('on'=>'post'));
 }
 }

環境設定を調べるには

Laravelの環境設定ファイルは、app/configフォルダ内に設置されています。この環境ファイルの内容を調べるには、Confing::get()メソッドを使用します。

環境設定値へアクセス

Config::get(‘ファイル名.キー’);

Config::getメソッドは、環境設定ファイルへアクセスすることができます。第1引数は、app/configフォルダ以下のファイル名とキーをドット(.)でつないで指定します。第2引数は、オプションで、環境ファイルが存在しないときの、デフォルト値を指定することができます。

基本例

Route::get(‘/’, function(){
return var_dump(Config::get(‘mail.host’));
});

http://localhost/laravel/publicで、下記のように表示します。

string(14) “smtp.gmail.com”

環境設定値をセット

Config::set(‘ファイル名.キー’,’値’);

環境設定値をセットするには、setメソッドを使用します。第1引数には、app/configフォルダ以下のファイル名とキーをドットでつないで、指定します。第2引数には、セットする値を指定します。

基本例

Route::get(‘/’, function(){
echo Config::get(‘app.timezone’).”<br>”;
Config::set(‘app.timezone’, ‘UTC’);
echo Config::get(‘app.timezone’);
});

http://localhost/laravel/publicで、下記のように表示します。

Asia/Tokyo
UTC

実行環境の設定値

上記のConfig::getやConfig::setメソッドは、アプリケーションを実行している設定値を指定しています。つまり、ローカル環境で実行していれば、app/config/localフォルダ内のファイル名.キーにアクセスしていますし、レンタルサーバー環境で実行していれば、app/config/lolipopフォルダ内のファイル名.キーにアクセスしていますので、ご注意ください。

この実行環境の設定値は、「Laravelの初期設定」でも述べていますが、bootstrap/start.phpファイル内の$app->detectEnvironmentの呼び出し名に対応しています。