Skip to content

はじめてのPHPDocと型

公開日:

東京都pixiv株式会社で開催された『ピクシブ社内勉強会』で社内勉強会(30分)として発表しました。

Download PDF

スライドテキスト

Page 1

はじめてのPHPDocと型

My first PHPDoc and Type

2016-09-09 ピクシブ社内勉強会

Page 2

型とは何か

Page 3

型… 型…

  • 一言で誤解を恐れずに表現すると

プログラミング言語が1 + [] (数字と配列のたしざん)みたいなのを叱れるようにする基盤

  • コンパイルするときに型を付けるか

動かすとき(runtime)に調べるかが、静的型付きと動的型検査の大きな差

Page 4

動的型検査

  • プログラムを動かしながら

手さぐりで型を調べる

  • 「$aの型はintだな、$bの型はstring…

だけど数字だから足しざんできるね!」みたいな茶番を毎回やってる

Page 5

静的検査

Page 6

動かす前に把握する

  • 実際に動かさなくても人間は整合性

をとりながらPHPを書ける

  • 人間がわかるってことは、機械にも

やってれないことはない

Page 7

型を推測してみよう(型推論)

// 絶対int返すマンfunction x() { return 1; }// 絶対array返すマンfunction y() { return []; }// たしざん// $n1, $n2 は数字っぽい値が欲しいfunction add($n1, $n2) { return $n1 + $2; }$a = x(); // x()がintを返すからたぶんintのはず$b = y(); // y()がarrayを返すからたぶんarrayのはず$c = add($a, $b);// 数字っぽい値以外を渡すとエラーが発生することは// 理窟の上では動かさなくても明らか

Page 8

型がない関数の問題

  • 引数に何渡せばいいの… 何返ってくるの
  • 時間は有限なので、既存コードを読む

時間は最小限にできるとウレシイ

  • ほんとに「見ればわかる」シンプルさなら

いいけど、現実は甘くない

  • 型が特定できないことも多い

Page 9

適当なコメント(Before)

// 絶対int返すマンfunction x() { return 1; }// 絶対array返すマンfunction y() { return []; }// たしざん// $n1, $n2 は数字っぽい値が欲しいfunction add($n1, $n2) { return $n1 + $2; }$a = x(); // x()がintを返すからたぶんintのはず$b = y(); // y()がarrayを返すからたぶんarrayのはず$c = add($a, $b);// 数字っぽい値以外を渡すとエラーが発生することは// 理窟の上では動かさなくても明らか

Page 10

PHPDocで型を付ける(After)

/** @return int */function x() { return 1; }/** @return array */function y() { return []; }/*** @param int $n1* @param int $n2*/function add($n1, $n2) { return $n1 + $2; }

Page 11

PHPDoc

Page 12

DocComment

  • PHPのリフレクションで実行時に

取得できる特別な形式のコメント

  • メソッドとかクラスの定義に

/** 〜 */ って書くと文字列になる

  • 開始記号は必ず /** にすること

(/* では無効なので注意!!!!)

Page 13

DocCommentを取得する

<?php/** こんにちは〜〜〜〜 */function hello() { throw new \Exception(); }$ref = new \ReflectionFunction('hello');echo $ref->getDocComment(), PHP_EOL;exit;

Page 14

APIドキュメントを生成する

  • ソースコード中のコメントを基に、

HTMLドキュメントを生成できる

  • JavaDocにインスパイヤされた

PHPDocって形式がある

  • phpDocumentorプロジェクトが

デファクト https://phpdoc.org/docs/latest/index.html

Page 15

PHPDocの型

  • 基本はPHPの型かクラス名を書く
  • 複合型
  • 「intまたは文字列」 int|string
  • 値が並んだ配列
  • 「intが並んだ配列」 int[]
  • https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/

types.html

Page 16

これだけ覚えて帰ってね

タグ名

意味

@param引数を定義@param int $n1

@return返り値を定義@return int[]

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

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

Page 17

型: arrayについて

  • array と mixed[] は意味が同じなのでは
  • PHPのarrayは

リストでもあり連想配列でもある

  • 標準化された用例ではないが、

tadsanは連想配列をarrayと書く

  • 0はじまりの連番の配列は

mixed[] とか User[] みたいに書く

Page 18

標準化について

  • 前述の通り、デファクトは

phpDocumentor2の仕様 (phpdoc.org)

  • 日本語 https://zonuexe.github.io/phpDocumentor2-ja/
  • 使ってるツールはいろいろある
  • PhpStorm, Phan, ApiGen, phpDox…
  • PSR-5で提案されてるけど… どうなる?

Page 19

PHPの型宣言

Page 20

タイプヒント改め「型宣言」

  • PHP5では「タイプヒント」と呼ばれ、

引数に特定のキーワードかクラス名を書くことができた

  • function getWorksByUser(UserModel $user)

みたいな

  • array, callable, resource
  • PHP7では「型宣言」になって返り値の型が

書ける

Page 21

型宣言の難しさ

  • PHP5はstringとかintとか書けなかった
  • そんなの簡単だろさっさと実装しろや…

みたいな単純な問題ではない

  • function hoge(int $n) を hoge("12")

で呼び出したときにどうするの…?

  • パンドラの箱を開けてしまった感
  • declare(strict_types=1) って書く

Page 22

キャストの難しさ

<?php declare(strict_types=0);function myint(int $v) { return $v;}myint(1.1); // => 1 myint(true); // => 1 myint("1"); // => 1 myint(floatval(PHP_INT_MAX - 512)); // int(9223372036854774784)myint(12345678901234567890.0);// PHP Fatal error: Uncaught TypeError: Argument 1// passed to myint() must be of the type integer, float given myint("12345678901234567890");// PHP Fatal error: Uncaught TypeError: Argument 1// passed to myint() must be of the type integer, string given

Page 23

Phan

Page 24

etsy/phan (次回豫告)

  • 静的解析ツール
  • PHPDocの定義を手がかりに、

型が違ってるところを指摘してくれる

  • 11/3にPHPカンファレンスで

詳しくしゃべってきます (30分枠)