Page 1
いまさら! お作法入門
Modern...? PHP manners guide
pixiv SUMMER BOOT CAMP 2017東京都渋谷区千駄ヶ谷 #pixiv_BOOTCAMP
公開日:
by USAMI Kenta@tadsan
に東京都渋谷区千駄ヶ谷のピクシブ株式会社で開催された『pixiv SUMMER BOOT CAMP 2017』でレギュラーセッション(20分)として発表しました。
Modern...? PHP manners guide
pixiv SUMMER BOOT CAMP 2017東京都渋谷区千駄ヶ谷 #pixiv_BOOTCAMP
講義資料です
このスライドはWebで公開します(メモはとらなくても良いです、の意味)
おぼえてほしいこと
コードは動けばええんや
反論?
コードの美しさはユーザーに見えない
汚ないコードでも、動けばユーザーにとっては最大の価値を生み出す
コードの美しさはユーザーに見えない
汚ないコードでも、動けばユーザーにとっては最大の価値を生み出す
読めないコードはメンテできない
機能拡張しにくい
ある日とつぜん動かなくなる
仕様変更に追従困難
動けばの前提が崩れたコードは価値が大暴落
ソースコードの美醜は現在のプログラムの価値とは関係ない
ただし美しくないコードは将来の可能性を閉ざしかねない
リーダブルそのために「読める」コードの追求とお作法の共有が必要
今回は大仰な設計の話ではなく、単にコーディングルールの共有をします
PSR?
その話はあとで
<?phpからはじめよ
ファイル先頭は必ず<?phpを書きます
必要ならnamespaceとuseを書きます
include_once 必要なければ書きません
そのあとクラス定義(だけ)を書きます
ファイル最後に ?> は書きません
namespaceは必要か?
namespaceを利用すべきかは、プロジェクトごとの事情に強く依存します
pixiv-libでは原則として利用しません
テストコード(tests/)でだけ使ってる
pixiv.git内のプロジェクト単位では、利用されることもあります
もしもnamespaceがなかったら
User_Commonのような擬似名前空間
namespaceとuseの解決は少し面倒
要はクラス名とファイル名の解決ができればオートローディングできます
User_Common → User/Common.php
require/include_onceは最低限だけ
クラスローダーを登録することで、自動ローディングできる (遅延評価)
1ファイルにつき1クラスを定義する
関数定義などは基本的には初期化ファイルから読み込みます
(composer.jsonのautoload.files)
?> を書かない理由
省略可能、書くメリットが皆無
PHPは <?php 〜 ?> の範囲外に書かれた文字列を出力します不随意にコード中に変な文字が混入したとき、文法エラーにもならず出力されかねないリスクがあります
クラスの概要を一行で要約すること一行で説明が不可能なら、クラスが持つ責任は明らかに多すぎます
クラス継承は慎重に設計してください個人的な経験では継承よりも委譲やinterfaceの方がうまくいきます
/*** 概要(summary, 要約) ↓ 下は空行** 説明文(description)。クラスの説明を書きます。* ここには何行書いてもいいです。** 説明不足よりも能弁を尊べ。** @see https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/basic-syntax.html*/final class Foo_BarModel implements ModelInterface{// ...
クラスとPHPDoc
メソッドの概要を一行で要約し、引数と返り値の型をデザインします一行で説明できないメソッドはその存在の軸が容易に揺らいでいく複数の型の値を返すメソッドは機能が多すぎ、利用側が煩雑になる
メソッドとPHPDoc
http://nico.ms/kn1774
タグ名
意味
例
@param引数を定義@param int $n1
@return返り値を定義@return int[]
@var変数/プロパティを定義@var int
@propertyマジックプロパティを定義@property int $id
resource, null, true, false
https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/types.html
https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/types.html
なんでPHPなのにわざわざ型を書くの
バグるのと型書くのどっちがええねん
静的型解析器(コンパイラ)は一般に実行前(コンパイル時)に変数や関数の型を特定するPHPのVM(インタプリタ)は、変数や関数の型は基本的に特定せず、実行時に動的型解析する
PHPの多くのバグは実行時まで遅延する
要は動かさないとわからない
動かさなくてもバグを検出できるうれしみは大きい
引数一覧で型を表示するところ
型がめったくそなの叱ってくれ
ループの話をしよう
PHPのfor文は原則禁止
PHPの配列は歯抜けになる
foreachなら大丈夫
引数一覧で型を表示するところ
ループの中で補完が利かない
きちんと型をつけ直す
ループの中でも補完が利くよ
PHP Standards Recommendations
PHP標準勧告
PHP Framework Interop Group PHPフレームワーク相互運用グループ
フレームワークやCMSを開発する組織の寄合
CakePHP, Composer, concrete5, Contao Open Source CMS, Drupal, eZ Publish, Horde, IBM i Toolkit, Icicle, Jackalope, Joomla, Lithium,Magento, PEAR, Phalcon, Phing, phpBB,phpDocumentor, PHPixie, Pimcore, PPI Framework, PrestaShop, PyroCMS, ReactPHP,Revive Adserver, Sculpin, SilverStripe, Slim,Stash, Stormpath PHP SDK, SugarCRM,Symfony, Neos and Flow, Wikibase and Semantic MediaWiki, Yii framework, Zend Framework 2,Zikula
http://www.php-fig.org/members/
相互運用??
ばらばらに作ってたのを仕様化して相互に利用しやすくしようぜ!……みたいな人類の夢
みんな仲良く
クラス名とファイルを一致させる規則
ベンダー名を名前空間のトップにする
\と_をDIRECTORY_SEPARATORに置換
2014年にPSR-4に置換されて廃止
PHPコードは<?php … ?>または<?= … ?>
文字コードはUTF-8(BOMなし)
クラスや定義のファイルは分けて、副作用のある処理とは分割する
クラス名はStudlyCaps(UpperCamlCase)、メソッド名はlowerCamelCase、プロパティ名は規定しないけど一貫せよ
具体的なコーディングスタイルガイドPSRに準拠したライブラリが必ず遵守しなければいけないルールではなく、プロジェクトごとにガイドラインを決めるための叩き台↑ここ誤解してるひとが意外と多い
final class Hoge implements Fizz{function hoge($a, $b){return $a + $b;}}function foo(){
$is_hoge = hoge();if ($is_hoge) {foo();} elseif (piyo($a)) {bar();}foreach ($values as $i => $v) {$values[$i] = piyopiyo($v);}
$str = "もじれつ";$str2 = $str . "!";
$n = 2;$m = 5;return foo($n, $m) * 2;
クラス名とファイルを一致させる規則
ベンダー名を名前空間のトップにする
\と_をDIRECTORY_SEPARATORに置換
サブ名前空間とベースディレクトリの概念が導入
わしのPSRは17まであるぞ
さて
ルールは破るためにある
所詮はフレームワーク開発者どもの間の規則
プライベートなプロジェクトがPSRに厳密に従っても得られるものは乏しい
プライベートなプロジェクトがPSRに厳密に従っても得られるものは乏しい
厳密に
都合のいいところだけ持ってくればいい
規則とは理想的には自分たちの足を撃ち抜かないためにある
実態に即しない規則は改正すべし
PSR-2を魔改造カスタマイズ
インデントはスペースではなくタブ
{ の改行位置が気に入らないので統一
要はコード内で統一感があれば良い
PSR-1, PSR-2はそのまま採用
行の長さの規制だけ緩めてる
PSR-0, PSR-4は採用しない
相互運用されないアプリケーションコードなどはvendorは厳密に意識しなくても別に問題が起こらない
PSR-0, PSR-4の規約通りに配置するだけで、Composerがいい感じにロードできる
まあ文字列マッチしてるだけなので、ベンダー名とか省略しても実際動く
そもそもローダーを自作してもいい
まとめ
(これに限らず)ルールやお作法は、われわれ人類が自爆しないための鎖
ルールが作られた背景には事情があるので、それを共有していくのが重要
「どうしてこうなってるの」と感じたら質問していこう
