Codeigniter(v3)を使って社内用のイベント管理システムを作ってみた感想
はじめに
CodeIgniter Advent Calendar 2015の18日目の記事になります! いつもAdvent Calendarは見る専門で参加するのは初めて。(なぜか緊張してます) 本投稿は「Codeigniterのコアな部分」には触れません。また、「Codeigniter入門」でもありませんので、ご了承ください。
初めてのCodeigniter
現在の職場で一番使われているPHP
のフレームワークがCodeigniter
なのだが、自分はこのフレームワークを使ったことがない。
先輩社員からは、「軽い・速い・CodeIgniter ユーザガイド 日本語版がとてもしっかりしていて分かりやすい*1・学習コストも低い、だからすぐに使えるようになるから勉強してみて!」と言われ、また
「何かわからなかったらググれ(ドヤァ」とのありがたいお言葉もいただいた。
というわけで、とにもかくにも使ってみないことには分からないので、これを使って一つ開発してみた。 開発中は、以下の「『Codeigniter徹底入門』サンプルアプリケーション」のソースコードを、めっさ参考にさせていただきました。かなり勉強になりました。 本当にありがとうございました。
作ったもの
実際に作ったものは、社内用のイベント参加者管理システム。もっぱら飲み会参加者が誰なのかを管理・把握するために利用する想定。 まぁ、ちょうど忘年会の時期でもあるので、あったら便利だと思い作った。(調整さんで良いじゃん、と自分でも思ったが、そこは勉強のため知らなかった体でww)機能仕様してはこんな感じ。
- イベント作成(タイトル、作成者メールアドレス、日付)
- 開催前の登録イベント一覧表示
- 各イベントの出欠登録(名前、参加者メールアドレス、出欠、備考の入力)
- 各出欠情報の編集
- 終了イベントの非表示
- 終了イベントの論理削除バッチ
とりあえず作ってみて社内では公開中。実際に社内で使うかは検討中。また機能仕様についても検討中。
実装記録
Codeigniter
の書き方やMVCの分離などについては素晴らしい記事が既にたくさんあるので割愛。ここではCodeigniter
でwebアプリを開発していく中で不可欠な設定や、私自身がいろいろ躓いたことについて備忘録的に一つずつ書いていく。
■開発環境
開発環境は以下。基本的には、yum
でインストールできるもので開発したが、PHP
だけバージョンを上げた。
- Vagrant 1.7.4
- VirtualBox 4.3.2
- CentOS 6.6(i386)
- Apache 2.2.15
- PHP 5.5.30
- Codeigniter 3.0.2
- Smarty 3.1.27
- MySQL 5.6.27
■index.phpのリダイレクト
Codeigniter
利用者なら必ず通るURLのindex.php
リダイレクト処理。.htaccess
でやってもよかったのだが、
ここは書き換えることはそうそうないと思ったので、apache
の方で設定した。
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_URI} !\.(css|pdf|png|jpe?g|gif|js|swf|txt|ico|s?html?)$ RewriteRule ^(.*)$ /index.php/$1 [L] </IfModule>
■データベース接続設定
何はともあれデータベース(以下DB)の接続設定が必要。DBの作成は行っている前提で書く。*2
設定はapplication/config/database.php
にて設定する。
<?php // 主に設定する項目のみ 'hostname' => 'localhost', 'username' => 'hogeuser', 'password' => 'hogepass', 'database' => 'hogedb', 'dbdriver' => 'mysqli', // PHPのバージョンによって適宜mysqlに変更
■バリデーションの追加
Codeigniter
に標準で実装されているバリデーションを確認(対象ファイルはsystem/libraries/Form_validation.php
)したら、「日付」「時間」に関するものがなかったので追加した。※直接ネイティブライブラリのファイルを触るのではなく、ネイティブライブラリの拡張にてapplication/libraries/my_form_validation.php
を作成。今回はyyyy/mm/dd H:i
形式で日時データがPOSTされるので、「日付」と「時間」で分離し、それぞれの正確性をチェックするようにした。
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Form_validation extends CI_Form_validation { public function __construct() { parent::__construct(); } /** * Valid DateTime * * @param string * @return bool */ public function valid_datetime($str) { // 日付と時間を分離 $datetimes = explode(' ', trim($str)); $dateData = $datetimes[0]; $timeData = $datetimes[1]; // 日付を年月日で分離 $ymd = explode('/', $dateData); // 日付の正確性チェック if (!checkdate($ymd[1], $ymd[2], $ymd[0])) { return FALSE; } // 時間を時と分で分離 $hourmin = explode(':', $timeData); // 時間の正確性チェック if (0 > $hourmin[0] || $hourmin[0] > 24 || 0 > $hourmin[1] || $hourmin[1] > 59) { return FALSE; } return TRUE; } }
■マイグレーション
ある意味で一番躓いたのがマイグレーションかもしれない。日本語のドキュメントが存在せず、以下の記事に大変助けていただきました。
細かいことは割愛するが、dbforge
クラスと組み合わせて利用する仕様となっている。
やったことを列挙すると、
application/migrations
ディレクトリの作成- 作成したディレクトリにてマイグレーションファイルの作成 ※ファイル名は「001_at_hoge_table.php」のように頭に3桁0埋めにする。以下作成例
<?php class Migration_Add_hoge_table extends CI_Migration { public function __construct() { parent::__construct(); } public function up() { $this->dbforge->add_field(array( 'event_id' => array( 'type' => 'INT', 'constraint' => 8, 'unsigned' => TRUE, 'auto_increment' => TRUE, 'comment' => 'イベントID' ), 'event_title' => array( 'type' => 'VARCHAR', 'constraint' => '255', 'comment' => 'イベントタイトル' ), 'create_date' => array( 'type' => 'DATETIME', 'null' => TRUE, 'comment' => '作成日' ), 'update_date' => array( 'type' => 'DATETIME', 'comment' => '更新日' ), 'event_date' => array( 'type' => 'DATETIME', 'comment' => 'イベント日' ), 'email' => array( 'type' => 'VARCHAR', 'constraint' => '255', 'comment' => '作成者メールアドレス' ), 'del_flg' => array( 'type' => 'TINYINT', 'constraint' => '3', 'default' => 0, 'unsigned' => TRUE, 'null' => TRUE, 'comment' => '削除フラグ' ), )); $this->dbforge->add_key('event_id', true); $this->dbforge->create_table('hoge_table'); } public function down() { $this->dbforge->drop_table('hoge_table'); } }
application/config/migration.php
にてマイグレーションを有効化・バージョンの指定
<?php $config['migration_enabled'] = TRUE; $config['migration_version'] = 1;
- コマンドラインから実行するため
applications/controller/migrate.php
の作成 以下作成例
<?php class Migrate extends CI_Controller { function __construct() { parent::__construct(); // コマンドラインから実行されていることを確認 if(!$this->input->is_cli_request()) { log_message('error', 'Request from HTTP is not allowed.'); return FALSE; } $this->load->library('migration'); } function current() { if ($this->migration->current()) { log_message('debug', 'Migration Success.'); } else { log_message('error', $this->migration->error_string()); } } function rollback($version = 0) { $this->migration->version($version); } }
# 実行 $ php index.php migrate current # 戻す $ php index.php migrate rollback
今回はデータベースの作成については先に行い、テーブルの作成・削除のマイグレーションのみ行った。本来の仕様だと画面から実行するそうだが、参考ページや以前使っていたYii
フレームワークでもコマンドラインから行っていたため、コマンドラインから実行できるように実装。また、テーブルにコメントを付けたかったが分からず…。どなたかご存知の方ご教示いただけますと幸いです。(nanndemoiikaraさんにコメントにてやり方を教えていただきました!)
■Smartyの導入
View側には、私が使い慣れているSmarty
テンプレートエンジンを導入。導入の際にはこちらの記事を参考にさせていただき、またかなり助けていただきました。
結構いろんなことやらないといけないので、参考記事がなければと思うと…((( ;゚Д゚)))フガクブル
- Githubや公式サイトから圧縮されたソースをダウンロード
- 解凍、
application/third_party/
に配置 - ディレクトリ名、ファイル名の変更
Smary-x.x.x
⇒smarty
smarty/libs
⇒smarty/libraries
smarty/libraries/Smarty.class.php
⇒smarty/libraries/Smarty.php
- テンプレートキャッシュディレクトリ
application/cache/templates_c/
の作成(※作成場所は任意) application/config/autoload.php
にて自動読み込みの設定(※コントローラ毎に読み込む場合は不要)
<?php $autoload['packages'] = array(APPPATH . 'third_party/smarty'); $autoload['libraries'] = array('smarty', 'database'); // ←その他追加するものがあれば適宜追記
<?php /** * My_Controller * Smarty on CodeIgniter */ class My_Controller extends CI_Controller { protected $template; public function __construct() { parent::__construct(); $this->smarty->template_dir = APPPATH . 'views/templates'; $this->smarty->compile_dir = APPPATH . 'cache/templates_c'; $this->smarty->left_delimiter = '<!--{'; $this->smarty->right_delimiter = '}-->'; $this->template = null; } public function _view($template) { $this->template = $template; } public function _output($output) { if (strlen($output) > 0) { echo $output; } else { $this->smarty->display($this->template); } } public function _assign($key, $value) { $this->smarty->assign($key, $value); } }
■ユニットテスト
これは調べたところ主に以下の3パターンの方法がある。以下参考にした記事。
- Codeigniter標準のユニットテストクラスを使う
⇒ 主に画面からテストを行うもののようで、結果は見やすいがあまりイケてない。。。ので却下!
- 素の
PHPUnit
を使う(参考記事多数のため割愛)
⇒ これは悪くないが、Codeigniter
に沿ったテストを書きたかったので、今回は見送り。
kenjis
さん作成のツールci-phpunit-test
を利用 ※PHPUnit
のインストールが必要
⇒ 今回はこちらの方法でテストを書いた。本投稿では環境用意までを書き残す。
# ci_phpunit_testのダウンロード $ composer require kenjis/ci-phpunit-test --dev # ci_phpunit_testのインストール $ php vendor/kenjis/ci-phpunit-test/install.php
テストの書き方については、上記記事を参照。
■jQueryrプラグイン
Codeigniter
とは関係ないが、今回開発したシステムにてイベント作成の際に日時を設定するため、日付と時間をGUIで選択できるjQueryプラグインdatetimepickerを利用した。これは特に躓きポイントはない。
- 公式サイトよりソースをダウンロード、解凍
jquery.datetimepicker.full.min.js
とjquery.datetimepicker.css
をアプリ内に配置- 利用する対象画面のテンプレートの
head
タグ内に以下を追記 ※初期設定は適宜変更
<link rel="stylesheet" type="text/css" href="/css/jquery.datetimepicker.css"> <script src="/js/jquery.js"></script> <script src="/js/jquery.datetimepicker.full.min.js"></script> <script> $(function() { $.datetimepicker.setLocale('ja'); $( "#datetimepicker" ).datetimepicker({ format: 'Y/m/d H:i', step: 30 }); }); </script>
- 同テンプレートのinputタグに
id=datetimepicker
を追記
<input type="text" name="eventDate" id="datetimepicker" placeholder="2015/12/18 10:30" />
今後の課題
まだ実装していない機能として、
- 作成者のみイベントの削除ボタン表示
- イベント前日、出席者へのアラートメール配信
- 開催前のイベント削除時、出席者へのメール配信
- 出欠表CSV出力
などがあるが、とりあえず社内で使うことが決まったら、別途仕様の相談をした上で実装仕様と思う。
また、開発したもののデモ環境を後ほど用意する(なにぶん会社用に作っているので、修正点がある)。何とか今年中に用意したいが…
※2015/01/06 Githubにソースコードアップしました。デザイン周りは現在も対応中です。
使った感想
公式サイトでうたってあった、
- 軽量
- 高速
- 拡張性
- MVC分離性
については、納得できるものだった。また、学習コストもかなり低く、ユーザガイド眺めながらコーディングしていけば自然と身に付いた。 とにかく使いやすいので、迷ったらとりあえず使ってみよう、くらいの感覚で選択しても良いと思う。
しかし、軽量・拡張性の高さのゆえコーディングする人の書き方による部分も多く(素のPHP
を書くことが多い)、コーディング規約を決めるなどしないと可読性は上がらない。
また、「テンプレートエンジンを必要としない」とあるが、個人的には必要だと思う。そもそも高速なフレームワークなのだから、多少パフォーマンスを犠牲にしたとしても、気にならない程度だろうし、
書く側としてはテンプレート使ったほうが簡単に書けるのだから、総合的には利用した方が利点はあるかと。
Yiiフレームワークとの比較
なぜYii
なのかと言うと、私が使ったことがあるPHP
のフレームワークはYii
しかないため。速度に関する比較は2015年最新PHPフレームワーク(9つ)のベンチマークがとても参考になるので、ご参照ください。書きやすさについてはCodeigniter
に軍配。ただ可読性はYii
の方が高い。まぁこの二つについてはトレードオフだな。総合的にCodeigniter
の方が気に入ったし、おすすめ。
以上!(たぶん随時修正すると思う…)