いまさら!PHPお作法入門

公開日:

Download PDF

スライドテキスト

Page 1

まさら!  お作法入門

Modern...? PHP manners guide

pixiv SUMMER BOOT CAMP 2017

#pixiv_BOOTCAMP

東京都渋谷区千駄ヶ谷

Page 2

Page 3

講義資料です

Page 4

このスライドは
Webで公開します (メモはとらなくても良いです、の意味)

Page 5

お前誰よ
うさみけんた (@tadsan) / Zonu.EXE

  • GitHub/Packagistでは id: zonuexe
    • 2012年11月にピクシブ株式会社に入社
  • Emacs Lisper, PHPer
  • 入社前は自宅警備をしながらRuby書いてた
    • Qiitaに記事を書いたり変なコメントしてるよ

Page 6

おぼえて
ほしいこと

Page 7

コードは動けばええんや
😄

Page 8

反論?

Page 9

最高のコードは動くコード

コードの美しさはユーザーに見えない

汚ないコードでも、動けばユーザーに
とっては最大の価値を生み出す

Page 10

最高のコードは動くコード

コードの美しさはユーザーに見えない

汚ないコードでも、動けばユーザーに
とっては最大の価値を生み出す

Page 11

全ての物事には一長一短がある

読めないコードはメンテできない

機能拡張しにくい

ある日とつぜん動かなくなる

仕様変更に追従困難

Page 12

動けばの前提が崩れた コードは価値が大暴落

Page 13

まとめると

ソースコードの美醜は現在の プログラムの価値とは関係ない

ただし美しくないコードは
将来の可能性を閉ざしかねない

Page 14

リーダブル

そのために「読める」

コードの追求と
お作法の共有が必要

Page 15

今回は大仰な設計の話で はなく、単にコーディン グルールの共有をします

Page 16

PSR?

Page 17

その話はあとで

Page 18

<?php

からはじめよ

<?php

ファイル先頭は必ず を書きます

namespace use
必要なら と を書きます

include_once

必要なければ書きません

そのあとクラス定義 を書きます

(だけ)

?>
ファイル最後に は書きません

Page 19

namespace

は必要か?

namespace

を利用すべきかは、
プロジェクトごとの事情に強く依存します

pixiv-libでは原則として利用しません

テストコード でだけ使ってる

tests/
( )

pixiv.git内のプロジェクト単位では、
利用されることもあります

Page 20

namespace

もしも がなかったら

User_Common

のような擬似名前空間

namespace use

と の解決は少し面倒

要はクラス名とファイル名の解決が できればオートローディングできます

User_Common User/Common.php

Page 21

require/include_once

は最低限だけ

クラスローダーを登録することで、 自動ローディングできる (遅延評価)

1ファイルにつき1クラスを定義する

関数定義などは基本的には

初期化ファイルから読み込みます

composer.json autoload.files
( の )

Page 22

?>

を書かない理由

省略可能、書くメリットが皆無

<?php 〜 ?>
PHPは の範囲外に
書かれた文字列を出力します

不随意にコード中に変な文字が混入し

たとき、文法エラーにもならず
出力されかねないリスクがあります

Page 23

クラス定義

クラスの概要を一行で要約すること

一行で説明が不可能なら、クラスが
持つ責任は明らかに多すぎます

クラス継承は慎重に設計してください

個人的な経験では継承よりも委譲

interface

の方がうまくいきます

Page 24

PHPDocの構造

/**

* 概要(summary, 要約) ↓ 下は空行

*

* 説明文(description)。クラスの説明を書きます。

* ここには何行書いてもいいです。

*

* 説明不足よりも能弁を尊べ。

*

*

@see

https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/basic-syntax.html

*/
final class Foo_BarModel implements ModelInterface

{

// ...

Page 25

クラスとPHPDoc

Page 26

メソッド定義

メソッドの概要を一行で要約し、 引数と返り値の型をデザインします

一行で説明できないメソッド
その存在の軸が容易に揺らいでいく

複数の型の値を返すメソッド
機能が多すぎ、利用側が煩雑になる

Page 27

メソッドとPHPDoc

Page 28

http://nico.ms/kn1774

Page 29

これだけ覚えて帰ってね

タグ名 意味 例

@param 引数を定義

@param int $n1

@return 返り値を定義

@return int[]

@var 変数/プロパティを定義

@var int

@property マジックプロパティを定義

@property int $id

Page 30

PHPDocの型

「PHPの型」か「クラス名」を書く

  • 基本的な型
  • string int bool float array

, , , , ,

  • resource null true false

, , ,

擬似型

  • callable void

,

  • (返り値を返さない)

https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/types.html

Page 31

PHPDocの型

複合型

  • int int|string
    「 または文字列」
    • 値が並んだ配列
  • int int[]
    「 が並んだ配列」
    • https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/types.html

Page 32

なんでPHPなのに
わざわざ型を書くの

Page 33

バグるのと型書くの
どっちがええねん
😎

Page 34

PHPは動的プログラミング言語

静的型解析器(コンパイラ)は

一般に実行前(コンパイル時)に
変数や関数の型を特定する

PHPのVM(インタプリタ)は、

変数や関数の型は基本的に特定せず、
実行時に動的型解析する

Page 35

PHPの多くのバグは 実行時まで遅延する

Page 36

要は動かさないと
わからない

Page 37

動かさなくても

バグを検出できる うれしみは大きい

Page 38

引数一覧で型を表示するところ

Page 39

型がめったくそなの叱ってくれ

Page 40

ループの
話をしよう

Page 41

PHPのfor文は原則禁止

#

Page 42

PHPの配列は歯抜けになる

#

Page 43

foreachなら大丈夫

$

Page 44

引数一覧で型を表示するところ

Page 45

ループの中で補完が利かない

Page 46

きちんと型をつけ直す

Page 47

ループの中でも補完が利くよ

Page 48

PSR
PHP Standards Recommendations
PHP標準勧告

Page 49

PHP-FIG
PHP Framework Interop Group
PHPフレームワーク相互運用グループ

Page 50

フレームワークや

CMSを開発する
組織の寄合

Page 51

2017年8月現在のメンバー

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/

Page 52

相互運用??

Page 53

Page 54

Page 55

Page 56

ばらばらに作ってたのを

仕様化して相互に
利用しやすくしようぜ!
……みたいな人類の夢

Page 57

みんな仲良く %&’

Page 58

PSR-0 Autoloading Standard

クラス名ファイルを一致させる規則

ベンダー名を名前空間のトップにする

\ _ DIRECTORY_SEPARATOR
とを に置換

2014年にPSR-4に置換されて廃止

Page 59

PSR-1 Basic Coding Standard

PHPコードは または

<?php … ?> <?= … ?>

文字コードはUTF-8(BOMなし)

クラスや定義のファイルは分けて、
副作用のある処理とは分割する

クラス名はStudlyCaps(UpperCamlCase)、

メソッド名はlowerCamelCase、
プロパティ名は規定しないけど一貫せよ

Page 60

PSR-2 Coding Style Guide

具体的なコーディングスタイルガイド

PSRに準拠したライブラリが必ず遵守 しなければいけないルールではなく

プロジェクトごとにガイドラインを
決めるための叩き台

↑ここ誤解してるひとが意外と多い

Page 61

{

クラスや関数など定義の は改行

final class Hoge implements Fizz

{

function hoge($a, $b)

{

return $a + $b;

}

}

function foo()

{

Page 62

{
そのほかの文の は改行しない

$is_hoge = hoge();
if ($is_hoge) {

foo();

} elseif (piyo($a)) {

bar();

}

foreach ($values as $i => $v) {

$values[$i] = piyopiyo($v);

}

Page 63

演算子などは、きっちり空白

$str = "もじれつ"; $str2 = $str . "!";

$n = 2; $m = 5;
return foo($n, $m) * 2;

Page 64

PSR-4 Autoloading Standard

クラス名ファイルを一致させる規則

ベンダー名を名前空間のトップにする

\ _ DIRECTORY_SEPARATOR
とを に置換

サブ名前空間ベースディレクトリ
概念が導入

Page 65

わしのPSRは17まで
あるぞ

Page 66

さて

Page 67

ルールは破るためにある
😎

Page 68

所詮はフレームワーク 開発者どもの間の規則
😎

Page 69

プライベートなプロ

ジェクトがPSRに
厳密に従っても得ら
れるものは乏しい

Page 70

プライベートなプロ

ジェクトがPSRに
厳密に従っても得ら
れるものは乏しい

Page 71

厳密に

Page 72

都合のいいところだけ
持ってくればいい
😊

Page 73

規則とは理想的には 自分たちの足を撃ち 抜かないためにある

Page 74

実態に即しない規則
は改正すべし

Page 75

よく聞く例

PSR-2を魔改造カスタマイズ

インデントはスペースではなくタブ

{ の改行位置が気に入らないので統一

要はコード内で統一感があれば良い

Page 76

pixivの例

PSR-1, PSR-2はそのまま採用

行の長さの規制だけ緩めてる

PSR-0, PSR-4は採用しない

相互運用されないアプリケーション コードなどはvendorは厳密に意識し
なくても別に問題が起こらない

Page 77

クラスのオートロード

PSR-0, PSR-4の規約通りに配置する だけで、Composerがいい感じにロー
ドできる

まあ文字列マッチしてるだけなので、 ベンダー名とか省略しても実際動く

そもそもローダーを自作してもいい

Page 78

まとめ

Page 79

まとめ

ルールやお作法は、

(これに限らず)
われわれ人類が自爆しないための鎖

ルールが作られた背景には事情がある ので、それを共有していくのが重要

「どうしてこうなってるの」と感じた
ら質問していこう