公式ドキュメント:
http://fuelphp.jp/
PHPバージョン
1.8.0ではPHP7.2までサポート、1.8.2ではPHP7.3まで
公式:https://fuelphp.com/blogs/2019/06/fuel-releases-1-8-2
1.8.2のchangelog:https://github.com/fuel/core/wiki/Changelog-v1.8.2
docker環境の構築
下記を利用させていただきました。
https://github.com/nemui-fujiu/docker_fuelphp
修正箇所
PHPのDockerfile内
PHPバージョン
現状(2020/03/06)、「php:7-fpm」だとPHP7.4がインストールされてしまうので「php:7.3-fpm」に修正する
FuelPHP1.8.2においても、PHP7.3の対応までの為。
mysql-client
debianでは「mysql-client」がなくなったのでエラー→default-mysql-clientに変更
https://yourmystar-engineer.hatenablog.jp/entry/2019/07/15/140644
mcrypt
mcryptでもエラーが起きたので削除
※PHP7.3からはmcryptでなくてOpenSSLで実装する事が推奨されているようです。
error: /usr/src/php/ext/mcrypt does not exist
https://blog.websandbag.com/entry/2018/12/15/024508
プロジェクトの作成
docker内で、composerのインストール、FuelPHPのクイックインストーラのインストールまで進んでいる為
下記実行し、FuelPHPのプロジェクトを作成する
※先に「app」コンテナ内に入ります。
# docker-compose exec app bash
# oil create fuel_server
※生成するプロジェクト名を変更したい場合は、nginxの設定ファイルも修正する必要があります。
ログディレクトリに権限がなくエラーになる為、下記ディレクトリに対して「その他のユーザ」に対して書き込み・実行権限をつける
※さぼって777にしてますが、権限は絞った方がいいです。
# chmod 777 /var/www/fuel_server/fuel/app/logs/
上記まで終わったら、下記にアクセスして正常に表示されればOKです。
http://localhost:9080/
mysqlが何故か動かず試行錯誤したときに、下記で全削除してから再度docker-compose buildを行いました。(キャッシュを使わない)
# docker-compose down --rmi all --volumes
# docker-compose build --no-cache
コーディングガイドライン
コーディングガイドラインがあるので、これに従ってコーディングを行います。
http://fuelphp.jp/docs/1.8/general/coding_standards.html
FuelPHPの特徴
- 移植性が高く、多くのサーバで動く
- 規約より設定を重視して設計されている
- フレームワークのルールに縛られない
- 複雑な設定ファイルに悩まされない
- MVCフレームワークだが、ViewModel(Presenter)という表示用のデータを作成して渡す機能がある→コントローラの肥大化を防ぐ役割か(いわゆるファットコントローラを防ぐ)
- クラス名の命名について:アンダースコアはオートロードの際にディレクトリの区切り記号に変換する(ここ結構特殊かな...)
- ビュー
- テンプレートエンジンを使っているわけではないので、親・子とビューファイルだけで継承させるのは素のFuelPHPでは出来ない
- https://qiita.com/assa/items/4fef2f3abd95248ed626
- 参考
MVCP
- モデル
- データを取得・操作する
- SQLクエリを記述
- ビュー
- ブラウザにデータを提供するファイル
- ビューはhtml、javascriptあるいはcss(コントローラから渡される変数を含む)
- 処理を含めない(かんたんな条件分岐等のみ)
- コントローラ
- URL を通じてアクセス可能なクラス(リクエストを処理)
- ントローラはモデルや他のクラスを呼び出して情報を取得→出力用にビューにすべてを渡す
- プレゼンター
- ビューの生成に必要なロジックを含む
- コントローラがユーザ入力を処理し、必要なアクションを処理すると、 プレゼンタにビューに必要なデータを取得するように処理を引き継ぐ
- プレゼンタはデータの操作を一切すべきではない
- データベースの呼び出しや他のデータの取得、 ビューの生成に必要な準備の操作を含む
設定
DB
- 本番環境:fuel/app/config/production/db.php
- テスト環境:fuel/app/config/development/db.php
- 本番・テスト共通の設定:config/db.php
- デフォルト環境は development(テスト環境) になっている
- 環境変数($_SERVER[‘FUEL_ENV’])や bootstrap.php から環境を変更できる
http://fuelphp.jp/docs/1.8/classes/database/introduction.html
https://runble1.com/fuelphp-db-connection/
マイグレーション
ルーティング
- ルート設定は、fuel/app/config/routes.php
- http://fuelphp.jp/docs/1.8/general/routing.html
- 「article/:id」の場合、「:id」は数値や文字列等何でも取得できてしまう→数値だけ取得する場合は、「article/(?P<id>\d+)」と指定できる。
- ルーティングでHTTPメソッドを指定することは出来ず、コントローラ側でHTTPメソッドアクションを指定する
- PUT/DELETEの場合、どのように指定すればいい?(わからない)
コントローラ
- fuel/app/classes/controller ディレクトリに置く
- ルーティングとコントローラの紐付け
- 'root' => 'article/index' -> パス指定ない場合、Controller_Articleクラスのaction_indexメソッドを実行
- 'article/create' => 'article/create' -> article/createへのアクセスの場合、Controller_Articleクラスのaction_createメソッドを実行
- メソッド名
- URLを通じてリクエストされたメソッドは、"action_" というプレフィックスを付ける(このメソッドは他のクラスからも使用できますが、ルーティングできない)
- HTTP メソッド名をアクション名の前につけることもできる(get_index,post_index等)
- before/afterメソッド
ビュー
View::forge
ブラウザに出力するビューを割り当てる
指定した変数($data)は、app/config/config.phpに設定されているoutput_filterのフィルタを通る
(output_filterはデフォルトで「Security::htmlentities」が指定されているので、必ずhtmlentities()が変数に対して実行される)
View::forge('home/index', $data);
親子ビューを作成する
レイアウトビューファイルを作成する
<html>
<head>
<?php echo $head; ?>
</head>
<body>
<?php echo $header; ?>
<?php echo $content; ?>
<?php echo $footer; ?>
</body>
</html>
変数としてheadやheader,content等を指定する(コントローラで設定する必要がある)
コントローラとビューが密に癒着する・ビュー全体の見通しがしづらそうな感じがする。
- XSSは塞げるが、ビューが生PHPになる為処理が見づらくなる(テンプレートエンジンでも、条件分岐は見づらくなりがちではありますが)
- ビューとコントローラの分離が完全に出来ない為、フロントエンドとサーバサイドでの役割分担がしづらそう
class Controller_Home extends Controller
{
public function action_index()
{
// レイアウトビューを作成する
$view = View::forge('layout');
// グローバル変数(すべてのビューがアクセスできる)を割り当てる
$view->set_global('username', 'Joe14');
$view->set_global('title', 'Home');
$view->set_global('site_title', 'My Website');
//変数としてビューを割り当てる、遅延レンダリング
$view->head = View::forge('head');
$view->header = View::forge('header');
$view->content = View::forge('content');
$view->footer = View::forge('footer');
// ビューオブジェクトをリクエストに返す
return $view;
}
}