FuelPHPの導入とVCモデルでプログラミングしてみる

f:id:watass:20141214211533p:plain

ようやくプログラマらしい記事が書けます。コーディング全然してませんでしたからね。
FuelPHPとは、超高速開発をサポートするPHPフレームワークです。

FuelPHP » A simple, flexible, community driven PHP5.3 framework.
http://fuelphp.com/

フレームワークによるプログラミングは、従来のプログラマが開発してきた様々なコンポーネントを、簡単に利用できるため、開発効率を大幅に改善することができると言われています。
PHPフレームワークでは、CakePHP、CodeIgniter、Symfonyなどが普及していますが、FuelPHPはその中のひとつで、CodeIgniterの開発者が集まって開発された、従来のフレームワークの問題を解決するフレームワークとのことです。
数々の選択肢から、私がFuelPHPを選んだ理由は、知人が利用していたから、という大変安直な理由ではありますが、できれば別のフレームワークも一度は触って比較してみたいですね。

なお、PHPフレームワークは単純なPHPプログラミングとは異なり、MVCフレームワークといった新しい概念を理解する必要がありますので、本記事ではFuelPHPの導入、単純な表示プログラムの作成までをまとめておきます。



開発環境について

お決まりですが、環境についてはこんな感じ。
基本的にはクライアントPCからAWS上のEC2にSSHで繋いで操作していきます。

OS:Amazon Linux AMI 2014.09
PHP : Version 5.3.29
FuelPHP:Version 1.7.2
Apache:Version 2.2.29


FuelPHPのインストール

最初に言っておきますと、FuelPHPの導入ってすっごいハマると思います。
諸事情があって複数回FuelPHPの導入をやったんですが、しっかりメモに残しておかないと、二回目には同じ問題で「あ〜〜、これなんだっけっかな〜〜」という感じでハマりまくっていたので、なるべく個人的にハマるポイントも同時にまとめておきます。

前置きはこのくらいにして、以下のコマンドでFuelPHPのインストール。

$ curl get.fuelphp.com/oil | sh

インストールはたったこれだけ。
次はFuelPHPでプロジェクトをホームディレクトリに作成します。

$ cd /home/watass
$ sudo oil create welcome

この時、PHPとGitがインストールされていることを確認して下さい。
インストールされていない場合には、以下のコマンドでさくっと入れてしまいましょう。

$ sudo yum install php
$ sudo yum install git

正しく動作しているならば、プロジェクトが作成されていると思います。ちなみに、

Error - date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'UTC' for 'UTC/0.0/no DST' instead in COREPATH/classes/fuel.php on line 167

こんなエラーが出ることがありますが、これはタイムゾーンを設定してないぞ、ってだけなので、とりあえず無視でOKです。
作成したプロジェクトにHTTPでアクセスするためには、ドキュメントルートにシンボリックリンクをはる必要がありますので、以下のコマンドでシンボリックリンクを作成します。

$ cd /var/www/html
$ sudo ln -s ~/welcome/public welcome

これで、/var/www/html/welcomeにアクセスすることで、~/welcome/publicへのアクセスができます。
ブラウザから確認するためには、http://IPアドレス/welcome/にアクセスすれば・・・

f:id:watass:20141214215240p:plain

ファッ!?

出ましたね。大抵エンジニアの過ちによって生まれる403エラー。
403エラーが出て嬉しい人っているんでしょうか。

解決法ですが、これはパーミッションの問題です。ユーザーのホームディレクトリ配下へのシンボリックリンクをはっていることが問題の奥底にありそうですね。
パーミッションを確認してみましょう。

$ cd /home/
$ ll
合計 4
drwx------ 4 ec2-user ec2-user 4096 1214 11:58 ec2-user

はい、ご覧の通り、ホームディレクトリが700になってますね。
上位層のパーミッションが適切でない場合、配下のwelcomeディレクトリのパーミッションが適切であったとしても、アクセスできずに403エラーになるようです。
chmodで755にして対処しましょう。

$ sudo chmod 755 /home/ec2-user/

これで、rootユーザ以外からも読み込み、実行ができるようになります。
早速アクセスしてみましょう。

f:id:watass:20141214220129p:plain

まだエラー地獄からは抜け出せないわけですよ(ゲス声)

とはいえ、これは簡単な話で、プロジェクト作成時に出たタイムゾーンエラーの件を後回しにした結果、ツケがここで回ってきているという話ですね。
~/welcome/fuel/app/config/config.phpのdefault_timezoneを修正します。

// 'default_timezone' => null,

となっている部分を

'default_timezone' => 'Asia/Tokyo',

と修正しましょう。
これでアクセスすると・・・?

f:id:watass:20141214220812p:plain

やっと出てきてくれたな〜〜FuelPHP〜〜
Welcome出すだけで相当苦労しました。
これでFuelPHPの導入は完了です。


MVCモデルとは何か

さて、ここからはFuelPHPでプログラミングをする上で重要となる、MVCモデルという概念について簡単に説明します。私自身、ド初心者なので、適当言っている可能性もあります。
MVCモデルとは、Model,View,Controllerという3つのコンポーネントにすべての機能を分割して、アプリケーションとしての振る舞いを実現するというモデルです。
それぞれのコンポーネントの役割については、以下で解説します。

Controllerの役割

Controllerはすべてのリクエストに対する中心を担うコンポーネントです。
例えば、ブラウザからアクセスした場合、まずControllerに処理が渡されます。
Controllerは必要に応じて、ViewやModelに処理を依頼し、その結果を返します。
その名の通り、Controllerは他コンポーネントに対する操作の「制御」を行いますので、ポイントは「Controllerにデータの処理や、表示系の操作をさせない」ことです。
基本的にオブジェクトの引き渡しや返り値を適切な場所に投げることが仕事になります。
実態はPHPのクラスをまとめたファイルになります。

Viewの役割

Viewは表示系を司るコンポーネントです。
実態はHTMLやPHPによる単純なファイルです。
変数はPHPで記述されており、値はControllerから受け渡されるイメージです。

Modelの役割

Modelは数値の操作などを司るコンポーネントです。
データベースからの数値取得や、各種計算などを行います。
実態はPHPのクラスのまとまりになります。
Controllerからの依頼を受けて、処理した値をControllerへ返します。


ざっとこんな感じです。
それぞれの役割がはっきりしていますので、管理がしやすくなりますね。


Controllerの作成

早速Controllerを作成します。
~/welcome/fuel/app/classes/controller/login.phpを以下のように書きます。

<?php

class Controller_Login extends Controller{
                public function action_index(){
                    $user = 'user';
                    $data['name'] = $user;

                    return View::forge('login_view',$data);
               }
}

?>

Controllerクラスの作成です。既に用意されているControllerクラスを拡張(extends)することで作成します。Controller_LoginのLoginの部分はアクセスする際のURLに利用されます。頭文字は大文字にしましょう。内部で定義されているaction_index関数はindex関数で、特に指定がない場合に実行されます。

基本的には(命名規則とか無視すれば)PHPのクラスと同じような書き方ですが、独特な記述は返り値の部分だと思います。これは、$dataをlogin_viewという名前のView(phpファイル)に組み込んで、Viewを作り出すという記述です。つまり、Controllerで指定した名前情報を元に、Viewが作成されるようになるわけです。

これでControllerの作成は完了です。次に、login_viewというViewを作成しましょう。


Viewの作成

Viewは単純なHTMLになります。
~/welcome/fuel/app/views/login_view.phpを以下のように書きます。

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome! <?php echo $name; ?> !</h1>
</body>
</html>

解説も不要なくらい単純な構成ですね。ポイントは$nameの扱いかと思います。
本来なら、この未定義な$nameはなにか?となるわけですが、これはControllerの返り値、$data配列の一要素である'name'が入ってきます。このように、View側はまったくControllerのことを考えずに実装できるというメリットがあります。


作成したプロジェクトへアクセスする

以上でController、Viewを用いて表示するVCモデルのプログラミングができました。
Controllerの作成でも触れましたが、Controllerのクラス名がURLになりますので、今回の場合、プロジェクト名がwelcome、クラス名がController_Loginでactionがindexなので、http://IPアドレス/welcome/login/にアクセスすることで表示することができます。

では早速アクセスしてみましょう。

f:id:watass:20141214225005p:plain

ファッ!?(2回目)

ここまできて、なぜ表示されないのか・・・正直かなりハマりました。
ポイントはFuelPHPの404エラーではなく、Apacheの404エラーであるということ。
つまり、mod_rewriteがうまく機能していない可能性があるのでは・・・?

というわけで、/etc/httpd/conf/httpd.confの以下の部分

<Directory "/var/www/html">
    /* 省略 */
    AllowOverride None
    /* 省略 */
</Directory>

このAllowOverrideをAllにしておきましょう。これでOKです。
なお、Apacheの設定ファイルの編集なので、Apacheの再起動を忘れないようにしましょう。

# /etc/init.d/httpd restart

これでアクセスしてみると・・・?

f:id:watass:20141214225754p:plain

いいですね。ちゃんとControllerで操作した値が表示されています。
まだまだ不足感がありますが、とりあえず疲れたのでこの辺で〜


と言いたいところですが忘れないでStrictModes

ここで終わりにして、サーバからログアウトすると次回顔真っ青になります(経験談)。
こんな感じ。

$ ssh -i key.pem ec2-user@255.255.255.255
Permission denied (publickey).

ファッ!?(3回目)

今まで何も思考せずにログインできていたのに、唐突なログイン不可。
色々ググってみると、ログインユーザのホームディレクトリのパーミッションを変更すると、SSHでログインできなくなることがある、ということが判明。
これ・・・詰んでない・・・?どうしろと・・・・?

対処法としては、EBSだけデタッチして別のEC2にアタッチするとか、そもそもイメージ使って復旧しろよとかあるわけですが、今回は幸いなことに対象のインスタンスはそこまで弄っていなかったので思い切って破棄しました。
とはいえ、これが本番環境だったらぞっとするな〜

しかし、ホームディレクトリのパーミッションを変更しないと、ホームディレクトリ配下にFuelPHPのプロジェクトが配置できませんので、なんとか解決したいところ。
対処法としては、ログインユーザの/etc/ssh/sshd_configにあるStrictModesをNoにすることで対処できるようです。

StrictModes no

これでOK。ちゃんとSSHで接続できます。
ただし、これはsshdに搭載されている、ホームディレクトリのパーミッション確認が実施されなくなる、ということを意味しますので、設定反映は気をつけてください。

いやー、これは焦ったね。割りとマジで。


まとめ


やりたいことはまだまだあります

結構今回の記事のネタは大変だったんですが、成果自体は小さく感じますね。
正直、まだまだFuelPHPで開発をする上ではやらなきゃいけないことがたくさんあります。
例えば、

  • Modelを用いたDBへのアクセス
  • PDOやORMを用いたDBへのアクセス
  • GitによるFuelPHPプロジェクトのバージョン管理
  • パスワードなどをハードコーディングしないための工夫
  • AWSとの連携

とりあえずこんなところでしょうか。
今までプログラミングをサボっていたツケが回ってきた感じがするなー・・・

あ、来週はAWSのソリューションアソシエイト試験があるので、その合格報告がしたいです。
そのためにも、今からホワイトペーパーをがっつり読んできます・・・


参考にした記事

ココロ踊るフレームワーク FuelPHP 導入してみます – WP-E(仮)Web Professional Education
# FuelPHPの導入で一番最初に参考にさせてもらいました。わかりやすくておすすめです。
apacheでシンボリックリンクが参照できない - プログラムTips - ソフトウェア開発 アイエスシーエス
# シンボリックリンク問題によって403だった件の解決につながりました。ありがとうございます。
FuelPHPでのタイムゾーン設定 - Qiita
# FuelPHPタイムゾーン設定はここで参考にさせてもらいました。
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
# FuelPHP初心者はこれ読んどけってくらい秀逸なまとめです。激推しです。
堂々巡り: FuelPHP 環境準備
# 404エラー問題の解決につながりました。ありがとうございます。
SSHのバカヤロ〜 - 諸行無常を楽しむ -LaManchaの日記-
# SSHログインできなくてハマっていたときに衝撃の事実を突きつけられました。バカヤローって感じです。
ssh鍵認証ログイン時のホームディレクトリパーミッション制限を緩める - teketeke_55の日記
# SSH問題の解決につながりました。ありがとうございます。