Phalcon + AngularJSで作る
動画プラットフォーム

Phalcon Night(2014年8月5日)

アシアル株式会社 宇都宮諒

自己紹介

宇都宮 諒(Utsunomiya Ryo)

  • アシアル株式会社 所属
  • PHPエンジニア
  • PHP歴3年 Phalcon歴5ヶ月
  • Phalcon ドキュメント日本語翻訳チーム レビュアー

アジェンダ

  • アプリケーション概要
  • アーキテクチャ
  • アプリケーション設計
  • Phalconを使う上での工夫・苦労

アプリケーション概要

  • B2Bのクローズドな動画プラットフォーム
    →イメージは「組織ごとに閉じたYoutube」
  • 様々な動画を会社等の組織内で共有したい
  • 動画の一部を切り出したり、プレイリストを作ったりしたい
  • 動画は、Web及びアプリで視聴したい
  • 既存システム(Zend製)を全面的に改修したい
  • 今年の8月から本番運用開始したい(サービスイン当初の顧客は1社)

アーキテクチャ

インフラ:Azure

  • 動画配信やエンコード等のサービス(Azure Media Services)を利用するために採用。
  • しかし、諸事情によりAzure Media Servicesの利用は取りやめに。
  • 結果的には、「mp4で配信」「FFmpegでエンコード」という形式に落ち着いた。
  • 現在、Azureの機能で使ってるのは仮想マシンとストレージ。

サーバ構成

  • Web+DBサーバ: 1台
  • エンコードサーバー: 複数台

今のところ負荷は大きくないので、Web+DBは1台に集約している。
エンコードはマシンパワーが必要なので、サービスイン当初から複数台構成。

システム構成

  • CentOS
  • Apache
  • MySQL
  • PHP

既存システムの構成をそのまま流用。
Nginxは検討したが、今のところ不要だと考え、既存のApacheをそのまま使用。

アプリケーション構成

  • 動画編集Web(AngularJS)
  • 動画配信Web(jQuery等)
  • 動画配信アプリ
  • バックエンドWeb API(Phalcon)

Phalconを選んだ理由

  • 動作が速い
  • アーキテクチャが割とモダン(PHP5.3+)
  • シンプルなAPI

工夫したこと(1):Viewの作り方

Viewの作り方

  1. Webでは、当初からAngularJSを使う予定だった。
  2. Phalconのテンプレートエンジン・Voltの記法は、Angularの記法とバッティングする。
    →ViewにはVoltを使用せず、生PHPをテンプレートとして使うことに。
  3. Viewの描画はほぼAngularに任せ、PHPは最低限のレイアウトのみを受け持つ。

工夫したこと(2):モデルの構成

プロジェクトの雛形

  • 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スキーマとモデルクラスの管理を行った。

  1. MySQL WorkbenchでER図作成
  2. WorkbenchのForward Engineer機能でスキーマ定義のSQL文を生成
  3. スキーマ定義SQLを使用してDBにテーブル作成
  4. 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
				

苦労したこと(1):
フレームワーク本体のバグ

Phalcon使用時に遭遇する
特徴的なエラーメッセージ

  • zend_mm_heap corrupted
  • Segmentation fault

どちらも原因は不正なメモリアクセス。
Segmentation faultはPHPコードにも原因があることが多い。
一方、zend_mm_heap corruptedはフレームワークのバグ。
経験上、モデルのプロパティ操作の際に発生しやすい。

Phalcon本体のバグの対処法

  1. 最新版のPhalconを使う。
  2. 止まっている箇所を特定する。
  3. 止まっている原因のクラス・メソッドが分かったら、GitHubにIssueが上がってないか確認する(回避策が載ってるかも)。
  4. 止まっている箇所のコードを色々変更してみる(大体これで回避できる)。
  5. 止まっているクラス・メソッドのPhalcon本体のソースコードを読んでみる(回避策が分かるかも)。

大きな変更の直後にエラーが発生すると、原因究明が大変。
こまめにコミット→テストのサイクルを走らせることで、対処しやすくなる。

不具合を検知する体制を作る

Phalconのバグによるエラーは、予測が困難。
発生したらすぐに検知できる体制を作る必要がある。

苦労したこと(2):ドキュメント

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だから特別な何かをしないといけない」ということはほとんど無い。
  • 普通に作れば普通に動く。
  • 現時点では荒削りな部分もある。

【宣伝】

アシアル株式会社で提供中のサービス

  • Monaca(HTML5モバイルアプリ開発プラットフォーム)
  • 受託開発(Webシステム・モバイルアプリ)
  • スクール(アシアル塾・企業研修)

ご清聴ありがとうございました。