Skip to content

Real World PHP in pixiv改

公開日:

東京都pixiv株式会社で開催された『pixiv 2016 SPRING BOOT CAMP』で社内発表(30分)として発表しました。

Download PDF

スライドテキスト

Page 1

Real World PHP in pixiv改

pixiv 2016 SPRING BOOT CAMP

2016年3月15日

Page 2

お前誰よ

  • うさみけんた / tadsan
  • 2012年11月にピクシブ入社
  • 入社前は自宅警備しながらRuby書いてた
  • pixivのPHPもろもろやってます
  • WEB+DB PressにPHPの記事を書きました
  • 好きなリスプはイーマックスリスプです

Page 3

注意

  • 時間配分は考慮してない
  • 開発楽しい!とかじゃなく淡々と羅列するだけ
  • ゆっくり話すので、「お前何言ってんだ」と

感じたらつっこみを入れてください

  • 資料はあとで公開します

Page 4

アジェンダ

  • 現状についてだらだら話す
  • pixivのデプロイについて
  • pixivの開発環境について
  • pixivのPHPについて
  • pixivのSQLについて
  • そのほか

Page 5

GitLab (2015年10月頃)

Page 6

GitLab (2016年3月)

Page 7

pixiv.git (クラスのお友達)├ accounts.pixiv.net├ admin.pixiv.net├ api.pixiv.net├ batch├ dev-script├ embed.pixiv.net├ m.pixiv.net├ me.pixiv.net├ oauth.pixiv.net├ pixiv-lib├ public-api.pixiv.net├ rpc.pixiv.private├ sensei.pixiv.net├ source.pixiv.net├ spapi.pixiv.net├ spotlight.pics├ ssl.pixiv.net├ touch.pixiv.net├ util├ vendor├ web-test└ www.pixiv.net

Page 8

変遷

  • 以前(2013年頃まで)は、サブディレクトリ

ごとに独立したGitリポジトリで、共通部分をsubmoduleとして扱ってた

  • 共通部分の抽象化もうまくなされて居らず、

重複・細部が異なるコードが分散してた

Page 9

変遷

  • submoduleは疎結合なモジュールに適する
  • 結合度が高いモジュールのリポジトリを分

割すると、変更コストが極めて高い

  • リポジトリを統合することで凝集度を高め

るリファクタリングも断行しやすくなった

  • 細部が異なる重複コード問題も根絶

Page 10

デプロイ

  • 基本的にサーバー全台(xx台程度)にrsync
  • 以前(2013年)はPHPファイルの増減を伴った

デプロイ時には(ページにもよるが)、xxx件程度のエラーが発生してしまってた

  • 現在はBlue-GreenDeploymentの確立で、

ファイルの追加/削除も怖いものではない

Page 11

Page 12

デプロイ (pploy)

  • 汎用的なデプロイシステム
  • /.deploy ディレクトリにファイルを配置
  • bin/deploy スクリプトが実行される
  • readme.html で画面カスタマイズ可能
  • Gitに依存するので、特定のバージョンを

チェックアウトして反映することも容易

Page 13

デプロイと変遷 (ブログ記事紹介)

  • 開発・デプロイ環境の変遷 2014年春版
  • 履歴を残したまま複数のgitリポジトリを統

合する

  • pixivのデプロイを支えるpploy
  • github: edvakf/pploy
  • WEB+DB PRESS Vol. 84

Page 14

pixivの開発環境

  • DBなどの依存が多く、ローカルに環境を構

築することは容易ではない(不可能でもない)

  • 共有の環境にSSHでログインして開発
  • 端末のEmacsやVimで開発するひとも
  • rsyncでローカルと同期してPhpStormなど
  • @tadsanはTRAMPを利用してる

Page 15

pixivの開発環境

  • ApacheのVirtualHostを大胆に活用
  • /home/www/にシンボリックリンクを作成
  • 社内ネットワークでDNS名前解決できる
  • www.tadsan.example.com のような形式
  • pixiv関係なくても任意のPHPを動作可能
  • OpenStackで同じ仕様のサーバー増やせる

Page 16

pixiv-lib

  • DBの操作を抽象化する層(DAO)
  • データの入出力などをまとめて扱う層
  • 社内では「Common層」と呼ばれる
  • セッション・国際化などの基盤機能
  • その他の共通処理いろいろ!
  • むかしはextlibって呼ばれてた (懐古)

Page 17

pixivのPHPコード

  • PHP 5.5 + Apache
  • URLを見ればわかる通り、ページ=PHP
  • search.php, member_illust.php など…
  • 一部のリクエストはHHVMで捌いてる
  • ルーティングのためmod_rewriteに依存

Page 18

pixivのPHPコード

  • 既存のフレームワークに依存しない
  • 独自フレームワークを運用してる部分もある
  • 口にすると顔をしかめられがちだが、

用途に合せて設計ができるのは悪くない

  • 何を使ったとしても、サービス提供者として

セキュリティの責任は変らない!

Page 19

pixivのPHPコード

  • 動的な言語機能は必要ない限り利用しない
  • コードの把握しやすさ、
  • クラスの静的メソッドを多用する
  • 継承は排除する方向
  • トレイトもあまり利用しない
  • リファレンスは原則排除する
  • PhpStormを使ってもつらいものはつらい

Page 20

pixivのPHPコード (昨年10月)

  • include_onceってたくさん書いてた!!
  • オートローディングの利用は限定的
  • pixiv-libでは現状は利用不可 (改善してた)
  • リポジトリ内に混在する都合上、

Composerのautoloadは利用しにくい

  • 一部ではphpabで生成してinclude

Page 21

pixivのPHPコード (現在)

  • include_onceを撲滅した!!
  • オートローディングを大幅導入
  • pixiv-libでは完全移行が完了
  • シンプルなクラスローダを手書き
  • 一部ではphpabで生成してincludeしてる

Page 22

pixivのPHPコード

  • コミットログやコード内コメントは、

英語または日本語で各人の得意な方で

  • 意識高く「全部英語で」など拘らない
  • 必要な文章は論理的に誤りがないように
  • コミットのルールは厳格に定めない
  • 各人のやりかたを尊重する
  • 典型的な Github Flow で運用

Page 23

loadset.php

  • 各プロジェクトの初期化ファイル
  • エラーハンドラーの設定
  • 必要なライブラリのロード
  • 定数(define)の定義
  • loadsetのみrequire_onceで読み込む
  • そのほかは全部 include_once で

Page 24

pixivのSQL

  • MySQL 5.5
  • 文字列結合によるSQL組立つらすぎ…
  • ORマッパー/自動クエリビルダーは利用せず
  • 2015年の初旬からSQLに型をつけて安全に

書けるライブラリを社内で運用

  • 脆弱性対策の文脈で生まれたが書きやすい

Page 25

Page 26

pixivのSQL

  • Q: なぜ自動クエリビルダー利用しないの?
  • いままでが文字列結合で組み立ててたから
  • クエリが単純ではないパターンも多い
  • 例: ブックマークなど

Page 27

pixivのWebAPI

  • いろんな試行錯誤をしてきた
  • 一部で有名なCSVのAPI (最初期)
  • ActiveResourceで利用するためのAPI
  • 提携企業向けRESTful API
  • 社内向けのシンプルなAPI (RPC)
  • スマートフォン用API (not REST)

Page 28

pixivのWebAPI

  • なぜRESTfulか? なぜRESTじゃないのか?
  • 慎重に判断する必要がある
  • API(RPC)から実行したい処理の粒度と

REST/CRUDの概念が馴染むとは限らない

  • 外部公開するのでなければ、

綺麗なURLの価値はあまり高くない

Page 29

pixivのWebAPI 設計

  • モバイルアプリはRESTを捨てる(採用しない)

決断をした

  • HTTP Methodも全てPOSTで受ける
  • 社内API(RPC)は Apache Thrift を採用した
  • どんなAPIが最適かは時と場合による

Page 30

パッケージ管理

  • Composerを利用
  • composer.pharはpixiv.gitに同梱
  • 社内ネットワーク内でSatisを運用
  • Jenkinsで定期的に更新
  • GitHubの障害があっても支障なし
  • 手動でパッケージ更新もできる

Page 31

pixivのテスト

  • 基本的にPHPUnitでテストを書く
  • 2013年頃にテストを書く文化が定着した
  • GitlabのMRにpushしたら自動テスト走る
  • うっかりmasterにpushされたら即座に

idobataに通知される

Page 32

pixivのレビュー体制

  • 毎週pixiv.gitに携る各チームのレビュアーで

設計方針や最新の情報などを共有・相談

  • レビュアーが各チームに持ち帰る
  • 各自メンバーに説明したり、レビュー過程

で指摘することで全体のコード品質を保つ

  • ガイドラインや推奨スタイルの確立

Page 33

そのほか

  • pixivのデプロイ回数は一日およそ40回
  • ディレクターが文言変更をすることが多い
  • Jenkinsをいっぱい使ってる
  • cronの代替として
  • スクリプトのWebUIとしても利用できる
  • 各種エディタの勢力は均衡してる

Page 34

ふろく (WEB+DB PHP連載)

  • 特におもしろい記事
  • Vol.81: テストしにくいコード対策
  • Vol.83: 安全なコーディングスタイル
  • Vol.84: デプロイ・Composer運用
  • Vol.87: PHPDoc記法で型注釈
  • Vol.88: HHVMの運用
  • Vol.91: 名前空間とオートローディング

Page 35

続きはWebで

  • https://github.com/pixiv
  • http://inside.pixiv.net/
  • GitHub (tadsan個人で公開してるもの)
  • BaguettePHP/simple-routing
  • BaguettePHP/http-accept-language
  • BaguettePHP/TetoSQL