宇都宮 諒(Utsunomiya Ryo)
- アシアル株式会社 所属
- PHPエンジニア
- PHP歴3年 Phalcon歴5ヶ月
- Phalcon ドキュメント日本語翻訳チーム レビュアー
アジェンダ
- アプリケーション概要
- アーキテクチャ
- アプリケーション設計
- Phalconを使う上での工夫・苦労
アプリケーション概要
- B2Bのクローズドな動画プラットフォーム
→イメージは「組織ごとに閉じたYoutube」
- 様々な動画を会社等の組織内で共有したい
- 動画の一部を切り出したり、プレイリストを作ったりしたい
- 動画は、Web及びアプリで視聴したい
- 既存システム(Zend製)を全面的に改修したい
- 今年の8月から本番運用開始したい(サービスイン当初の顧客は1社)
- 動画配信やエンコード等のサービス(Azure Media Services)を利用するために採用。
- しかし、諸事情によりAzure Media Servicesの利用は取りやめに。
- 結果的には、「mp4で配信」「FFmpegでエンコード」という形式に落ち着いた。
- 現在、Azureの機能で使ってるのは仮想マシンとストレージ。
サーバ構成
- Web+DBサーバ: 1台
- エンコードサーバー: 複数台
今のところ負荷は大きくないので、Web+DBは1台に集約している。
エンコードはマシンパワーが必要なので、サービスイン当初から複数台構成。
システム構成
既存システムの構成をそのまま流用。
Nginxは検討したが、今のところ不要だと考え、既存のApacheをそのまま使用。
アプリケーション構成
- 動画編集Web(AngularJS)
- 動画配信Web(jQuery等)
- 動画配信アプリ
- バックエンドWeb API(Phalcon)
Phalconを選んだ理由
- 動作が速い
- アーキテクチャが割とモダン(PHP5.3+)
- シンプルなAPI
Viewの作り方
- Webでは、当初からAngularJSを使う予定だった。
- Phalconのテンプレートエンジン・Voltの記法は、Angularの記法とバッティングする。
→ViewにはVoltを使用せず、生PHPをテンプレートとして使うことに。
- Viewの描画はほぼAngularに任せ、PHPは最低限のレイアウトのみを受け持つ。
プロジェクトの雛形
- Phalcon DevToolsで生成できる。
- micro / simple / modules の3タイプがある。
- 今回のアプリでは、modules構成を使用。
$ phalcon project PROJECT_NAME --type=modules
ディレクトリ構成
├── apps
│ ├── editor
│ │ ├── config
│ │ ├── controllers
│ │ ├── models
│ │ └── views
│ └── viewer (中の構成はeditorと同様)
├── config
├── models
│ └── Base
├── public
├── tasks
├── tests
└── vendor
コマンドによる生成直後のmodules構成は、モデルがモジュールごとに分かれているが、共通モデルはアプリケーションルート直下のmodelsにまとめた。
各モジュールのmodelsにはフォーム等、モジュール固有のクラスを入れてある。
DBスキーマ
以下の手順でDBスキーマとモデルクラスの管理を行った。
- MySQL WorkbenchでER図作成
- WorkbenchのForward Engineer機能でスキーマ定義のSQL文を生成
- スキーマ定義SQLを使用してDBにテーブル作成
- DBに存在するテーブルを元に、phalcon modelコマンドでBaseモデルを生成
Baseモデルとは?
- DBスキーマを更新したら、Baseモデルも全て作り直す。
- Baseモデルは自動生成を行う。開発者はBaseモデルには触らない。
- モデルに共通で持たせたい処理(ビヘイビア等)はBaseモデルの親(AbstractModel)に実装する。
- AbstractModelは、Phalcon\Mvc\Model を継承する。
- アプリケーション内で使用するモデルは、Baseモデルを継承する。
- Baseモデルの生成は以下のようなコマンドで行う。
$ phalcon model \
--namespace=App\\Models\\Base \
--extends=\\App\\Models\\AbstractModel \
--output=app/models/Base \
--name=TABLE_NAME
Phalcon使用時に遭遇する
特徴的なエラーメッセージ
- zend_mm_heap corrupted
- Segmentation fault
どちらも原因は不正なメモリアクセス。
Segmentation faultはPHPコードにも原因があることが多い。
一方、zend_mm_heap corruptedはフレームワークのバグ。
経験上、モデルのプロパティ操作の際に発生しやすい。
Phalcon本体のバグの対処法
- 最新版のPhalconを使う。
- 止まっている箇所を特定する。
- 止まっている原因のクラス・メソッドが分かったら、GitHubにIssueが上がってないか確認する(回避策が載ってるかも)。
- 止まっている箇所のコードを色々変更してみる(大体これで回避できる)。
- 止まっているクラス・メソッドのPhalcon本体のソースコードを読んでみる(回避策が分かるかも)。
大きな変更の直後にエラーが発生すると、原因究明が大変。
こまめにコミット→テストのサイクルを走らせることで、対処しやすくなる。
不具合を検知する体制を作る
Phalconのバグによるエラーは、予測が困難。
発生したらすぐに検知できる体制を作る必要がある。
Phalconのドキュメントの弱点(1):
APIリファレンス
- PhalconのAPIリファレンスは、ソースコードから自動生成している。
→ソースコードのコメントが誤っていると、APIリファレンスまでおかしくなる。
- 自動生成スクリプトにバグがあり、正常にパラメータを取れていないことがある。
- 例:Phalcon\Http\Request::getJsonRawBody()の第1引数は、ソースのDocコメントには載っているが、APIリファレンスには載っていない。
Phalconのドキュメントの弱点(2): 翻訳
- Phalconのドキュメントで日本語になっているのは、全体の10%程度。
- 実は、20%ほど翻訳は進んでいるのだけど、リリースされていない。。。
- 翻訳に興味の有る方いらっしゃれば是非。
貢献方法:CONTRIBUTING.md
これから苦労しそうなこと:
バージョンアップ
- Phalconの現行バージョン(1.3.2)はまだ不安定な部分があるので、継続して開発していく上で、より安定したバージョンに差し替えたい。
- Phalcon 2では、PHP拡張のビルドにZephirという中間言語を挟むようになるが、まだ不安定で、環境によってはZephirコンパイラのビルドにこける…
- Phalcon 2の初期バージョンは、1系とのAPI互換性が保証されてるので、その点は割と安心。
まとめ
- 「Phalconだから特別な何かをしないといけない」ということはほとんど無い。
- 普通に作れば普通に動く。
- 現時点では荒削りな部分もある。