この記事はcloudpackあら便利カレンダーの9日目の記事です。

先日行われたPHPカンファレンス福岡2017に参加してきましたので、
参加メモですがここに残します。

PHP7で堅牢なコードを書く

DB情報が変更されるとエラーでるよね

不具合の発見が遅れれば遅れるほど傷は深くなる

  • 要件定義の段階で発見できれば傷は浅い

予防的プログラミング

  • 間違った予防法
    is_null() やら is_array() やら array_key_exists() やら
  • 正しい予防法
    インタフェース設計をする: 誤った使い方をすることが困難
    == そもそも間違った使い方ができない

タイプヒントで int stringで縛ればそもそも is_int() とかは不要
Enumつかってとりうる値を制御するのもアリ
PHPで列挙型を作る@hiraku

  • 責務を増やしすぎない
    • DIで責務をバランシングする
    • 作る人: new PDO()
    • 設計する人: DI
    • 利用する人: $pdo->execute()

    予防にまさる防御なし

攻撃的プラグラミング

fail fast

早めにクラッシュさせること
疑いがあればすぐに停止させるべき

正当性と堅牢性

  • 正当性 不正確な結果を返すくらいなら何も返さない方がマシ 個々のクラスで担保
  • 堅牢性 多少なんかあってもソフトウェアの実行が継続するようにする アーキ・FWで担保

戻り値ではなく例外を使う

PDO::ERRMODE_EXCEPTION: 何かしくるとErrorになる(その前はWarningくらい)

表明プログラミング

怒るはずがない をコードで表す == assertion
assert(評価式)
このままだと警告出すだけで落ちない
php.iniで assert.exception = 1によって表明違反でおちる is 最高
zend.assertionsで実行時の挙動を変更できる

暗黙の前提を明示的なコードにすることで読み手が理解しやすくなる

例外と表明の使い分け

例外は起こり得るものに
表明は起こり得ないものに
それぞれつかう

契約プログラミング

誰の責務化はっきりさせる契約による設計

  • 事前条件違反は呼び出し側に問題がある
  • 事後条件違反は供給者側に問題がある

AssertionError/LogicExceptionはcatchするのはまちがい
はやめに落としてなおしにいくべき

Exceptionの第三引数はstacktraceをつなげる役目がある

try{

} catch (\PDOException $e) {
  throw new LogicException($e->getMessage(), $e->getCode(), $e);
}

ADR

Request -> BusinessLogic -> View

MVCとほぼおなじ

Controller Action
Model Domain
View Responder

Action

  • レスポンスを返却する責務がない
  • 1つのClassで1つのリクエストを担当(GETならGETのClassを作る)
  • Domain と Responderを接続する
  • Closureや__invoke()で実行すべき
  • Middlewareでよくつかう手法

Domain

  • DDDのDomainを例に解説

Responder

  • Actionに対するResponderを個別に用意
  • ヘッダの設定とかも
  • テンプレートを組み込んでもおk

ADRは何を目指すか

小さく、最小単位に
単一責任の原則

依存を逆転してもアプリケーションは動かないといけない

サービス要件とシステム要件をちゃんとわけて考えられているか

Specification Pattern

  • 仕様パターン このRepositoryには何を与えればいいかを定義

Domain Service Class

  • バルク時の割引はEntityで表現できないよね〜みたいなときにつかう

1Action, 1Domain

1,800Req/s

就職活動支援系アプリのAPIの話

  • 構成
  • EC2: m4.xlarge x 2
  • RDS: m3.xlarge
  • ミドルウェア
    • Ubuntu
    • PHP
    • cakephp
    • apache
  1. 負荷を想定
  2. 仮構成を作成
  3. 負荷試験 + 調整
  • やばかったら?
    • C2はスケールアウトで対応
    • DBはスケールアップ

PV -> APIコールの変換

  • ユーザシナリオ
  • シナリオの各ステップでのAPIコールをリストアップ
  • その時のPVとAPIコールの比率をとる

3000PV/sec -> 1800call/sec

負荷テストで死んだ

APIコールのシナリオを見直す

  • 静的化できるもの(config系)は積極的にキャッシュ: PHPを使わずApacheだけで完結させる
  • m4.4xlarge x 16台構成に変更

本番稼働

  • APIの静的化でDBコネクションの張り付きを逃れる

PHP-ML

いろんなアルゴリズムが実装されてる
でも対応状況はまだまだ

Pythonでは

  • scikit-learn
  • madplot-libで描画してる

機械学習

各種紹介にとどまる

元記事はこちら

PHPカンファレンス福岡2017に参加してきました。