ランサーズ Advent Calendar 2017第二弾、12/2は上野が担当させてもらいます。
はじめに
今年はLancers Topの開発を通じて、CakePHP1.3の世界から3.4, 3.5の世界に飛び出し、CakePHP3.5の移行ガイドの翻訳にチャレンジするなどしてみて、アクセスがめんどくさい情報をわかりやすく伝えることはOSSに機能を一つ追加することよりもむしろ価値があるのではないかと、コミュニティーに対する還元の考え方が変わった1年でした。
そこで去年度の「githubのissue, pull request 検索をハックする!」に引き続きハックシリーズで「php_cs_fixerのオプションをハックする」と称してphpのコーディング規則を揃え自動修正してくれるphp_cs_fixer
でどのような修正が可能か、実行時のdiffも含めご紹介します。
本題の前の準備系(基本割愛しています)
そもそもphp_cs_fixerってなに?
PHPのコーディングスタイルを揃えて自動で修正してくれるlibraryです。
- メンバーの好みや癖で同じリポジトリで記述が異なるようなことを防いでくれます。
- レビューでする側も受ける側もストレスなコーディング規約に関する指摘がなくなります
- 宗教戦争が収まり平和な世界の中でで大事なビジネスロジックに集中した開発ができます
PHPには他にPHP CodeSniffer
があります
インストールと実行コマンド
幾つか記事が出ているので省略します。
## 例1) composerで導入
$ composer require friendsofphp/php-cs-fixer
$ vi .php_cs
$ ./vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix --config=./.php_cs
## 例1) homebrewで導入
$ brew install homebrew/php/php-cs-fixer
$ vi .php_cs
$ php-cs-fixer fix --config=./.php_cs
.php_csのオプション紹介(本題)
.php_csの記述サンプル
対象のフォルダとルールを設定します。
$finder = PhpCsFixer\Finder::create()
->notName('README.md')
->notName('.php_cs')
->notName('composer.*')
->notName('phpunit.xml*')
->notName('*.xml')
->exclude('tests') // ここから除外フォルダー
->exclude('config/Seeds')
->exclude('vendor')
->exclude('plugin')
->exclude('tmp')
->in(__DIR__);
return PhpCsFixer\Config::create()
->setRules([
'@PSR2' => true,
'@PHP71Migration' => true,
'array_syntax' => ['syntax' => 'short'],
'ereg_to_preg' => true,
'function_typehint_space' => true,
'no_unused_imports' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_whitespace_before_comma_in_array' => true,
// 'ordered_imports' => true,
'return_type_declaration' => true,
'ternary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
'psr4' => true,
])
->setUsingCache(false)
->setFinder($finder);
以後は利用できるルールの各種オプションを本家よりわかりやすい説明を目指して、変換前後のdiffつきで紹介します。
お好みのコーディング規約に沿って組み合わせて使ってください。
array_syntax
arrayの記述方法を短縮系にするか
'array_syntax' => ['syntax' => 'short'],
'array_syntax' => array('syntax' => 'long'),
short | long |
---|---|
binary_operator_spaces
= や => などの演算子を揃えるかを設定できます
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true,
],
align_equals | align_double_arrow |
---|---|
blank_line_after_namespace
ネームスペースの後ろに一行改行を入れます。
-
@PSR-2
,@Symfony
でデフォルトtrue
です。
'blank_line_after_namespace' => true
blank_line_after_opening_tag
PHPの開始タグの後に一行改行を入れます
-
@Symfony
でデフォルトtrue
で指定されます
'blank_line_after_opening_tag' => true,
blank_line_before_return
returnの前に一行改行を入れます
'blank_line_before_return' => true,
blank_line_before_statement
特定の記述の前に一行改行を入れる
-
@Symfony
ではデフォルトでいかが設定されている
'blank_line_before_statement' => [
'statements' => [
'break',
'continue',
'declare',
'return',
'throw',
'try'
]
],
braces
各構造体は、中括弧で囲んで適切にインデントさせる必要があるためフォーマットを統一する
-
@PSR-2
,@Symfony
で以下のデフォルト指定がされている。
'braces' => [
'allow_single_line_closure' => false,
'position_after_anonymous_constructs' => 'same'
'position_after_control_structures' => 'same'
'position_after_functions_and_oop_constructs' => 'next'
],
allow_single_line_closure
クロージャーを1行で書くことを許容する
'braces' => [
'allow_single_line_closure' => false,
],
position_after_anonymous_constructs
クロージャや無名クラスの中括弧開始の位置を指定
- same: 同じ行、 next: 次の行 が指定できる
'braces' => [
'position_after_anonymous_constructs' => 'next'
],
position_after_control_structures
if
,else
,for
,foreach
,try
などの制御構造の中括弧開始位置を指定
- same: 同じ行、 next: 次の行 が指定できる
'braces' => [
'position_after_control_structures' => 'next'
],
position_after_functions_and_oop_constructs
class, function などの宣言の後で用いる中括弧開始位置を指定
- same: 同じ行、 next: 次の行 が指定できる
'braces' => [
'position_after_functions_and_oop_constructs' => 'same'
],
cast_spaces
キャストをした時に後ろにスペースを開けるか。
-
@Symfony
のときのデフォルトはsingle
- single: 半角空白を空ける 、none: 空白を入れない
'cast_spaces' => [
'space' => 'single'
],
class_keyword_remove
::class
のキーワードを絶対パスの名前に置き換える
'class_keyword_remove' => true,
combine_consecutive_issets, combine_consecutive_unsets
isset(X) && isset(Y) && ...
の記述を isset(X,Y,...)
に置き換える
unset(x)
が続く記述を unset(x,y,...)
に置き換える
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
compact_nullable_typehint
nullを許容する型宣言で余計な空白を削除する
'compact_nullable_typehint' => true,
concat_space
結合演算子の前後に空ける空白の指定
- Symfonyでは
none
がデフォルト指定されます
'concat_space' => [
'spacing' => 'single'
],
declare_strict_types (PHP>=7.0)
型を厳密に判断する strict モードを強制する
-
@PHP70Migration:risky
,@PHP71Migration:risky
で利用できます
'declare_strict_types' => true,
dir_constant
dirname(__FILE__)
を __DIR__
に書き換えます。
-
dirname()
をオーバライドしているときはリスクを伴います
'dir_constant' => true,
elseif
空白のあるelse if
の代わりに elseif
を使うようにします
-
@PSR2
,@Symfony
でデフォルトtrue
です
'elseif' => true,
encoding
PHPコードの文字コードをBOMでなくUTF-8にします
-
@PSR1
,@PSR2
,@Symfony
でデフォルトtrue
です
'encoding' => true,
ereg_to_preg
非推奨になっている ereg系
の処理を preg
に変換します
-
ereg
関数をオーバーライドしている場合リスクを伴います -
@Symfony:risky
の場合にデフォルトture
です
'ereg_to_preg' => true,
full_opening_tag
ロングタグ(<?php
) と echo
を伴うショートタグ(<?=
) 以外を使用禁止にします
@PSR1
,@PSR2
, @Symfony
でデフォルトtrue
です
'full_opening_tag' => true,
function_declaration
関数宣言後のスペース設定
-
@PSR2
,@Symfony
でデフォルトで以下が設定されています
'function_declaration' => [
'closure_function_spacing' => 'one', // クロージャーのfunctionの後ろのスペース
],
function_to_constant
特定の関数を定数に置き換えます。
-
@Symfony:risk
ではデフォルトで以下が設定されています。 - 各関数をオーバライドしていたときにはリスクを伴います。
'function_to_constant' => [
'functions' => ['get_class', 'php_sapi_name', 'phpversion', 'pi']
],
function_typehint_space
関数の返り値の型宣言にスペースが抜けていると補完する
'function_typehint_space' => true,
general_phpdoc_annotation_remove
特定のアノテーションを削除します
- デフォルトは
[]
です
'general_phpdoc_annotation_remove' => [
'annotations' => [
'todo'
]
],
header_comment
ヘッダーコメントを追加、削除、変更します
- デフォルトで以下が設定されています。headerは必須項目なので必ず指定が必要です
'header_comment' => [
'commentType' => 'comment',
'header' => '', // <== デフォルト指定なし指定必須項目
'location' => 'after_declare_strict',
'separate' => 'both',
]
commentType
comment(default) | PHPDoc |
---|---|
location
after_declare_strict(default) | after_open |
---|---|
separate
both(default) | bottom | none | top |
---|---|---|---|
heredoc_to_nowdoc
heredoc
のうち変換可能なものを nowdoc
に変換する
'heredoc_to_nowdoc' => true,
include
include
, require
, ファイルパスは、単一のスペースで区切る必要があります。ファイルパスをカッコの中に入れないでください
'include' => true,
increment_style
可能であれば、インクリメントおよびデクリメント演算子はpre
,post
で統一してを使用する必要があります。
-
pre
,post
を指定できます。 - デフォルトは
pre
です
'increment_style' => [
'style' => 'post'
],
indentation_type
コードインデントに定められたインデントを使用しなければいけない
-
@PSR2
,@Symfony
でデフォルトでtrue
が設定されます。
'indentation_type' => true,
is_null
is_null($hoge)
を null === $hoge
に置き換える
-
is_null()
をオーバーライドしている場合リスクを伴います - 後述する
use_yoda_style
がtrue
の場合はデフォルトがtrue
で設定されます
'is_null' => true,
line_ending
全てのPHPファイルで同じ改行コードを使わなくてはいけない
-
@PSR2
,@Symfony
でデフォルトでtrue
が設定されます。
'line_ending' => true,
linebreak_after_opening_tag
開始タグの後ろに改行を入れて開始タグの行には記述がないようにする
'linebreak_after_opening_tag' => true,
list_syntax (PHP >= 7.1)
listで使用する構造を統一します。
- デフォルトは
long
です
'list_syntax' => [
'syntax' => 'long'
],
long(default) | short |
---|---|
lowercase_cast, lowercase_constants, lowercase_keywords
特定の記述を小文字で記述することを強制する
'lowercase_cast' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
lowercase_cast | lowercase_constants | lowercase_keywords | |
---|---|---|---|
@PSR2 |
--- | true | true |
@Symfony |
true | true | true |
画像 |
mb_str_functions
マルチバイト非対応関数をマルチバイト対応関数(mb_xxxx)に置き換える
- 該当の関数をオーバライドしていたときにリスクを伴います
'mb_str_functions' => true,
method_argument_space
メソッドの引数とメソッド呼び出しで、各カンマの前にスペースを禁止して、各カンマの後にスペースを求めます。
- 2つのオプションを持ち
@PSR2
,@Symfony
でデフォルトでいかが指定されています
'method_argument_space' => [
'ensure_fully_multiline' => false,
'keep_multiple_spaces_after_comma' => false,
],
標準
前方にはカンマを入れない | 後方にカンマを入れる |
---|---|
ensure_fully_multiline
複数行に渡るときには1行に引数一つとする
'method_argument_space' => [
'ensure_fully_multiline' => true,
],
複数のスペースを許容する(falseで複数スペースを単一にする)
'method_argument_space' => [
'keep_multiple_spaces_after_comma' => false,
],
method_separation
メソッドの前後の分割は一行改行を強制する
-
@Symfony
でデフォルトtrue
が指定されます
'method_separation' => true,
modernize_types_casting
intval
,floatval
,doubleval
,strval
,boolval
の関数をキャストに置き換えます
-
@Symfony:risky
でデフォルトtrue
です - 各関数をオーバライドしていたときはリスクを伴います
'modernize_types_casting' => true,
native_function_invocation
名前解決の速度を上げるために内部関数の前に\
を付与する
- あらゆる関数をオーバライドしていたときにリスクを伴います
'native_function_invocation' => [
'exclude' => [],
],
new_with_braces
newを用いて生成したインスタンスには後方に丸括弧を必要とします
'new_with_braces' => true,
no_alias_functions
エイリアス関数の代わりに元の関数を使うように置き換えます
- エイリアス関数をオーバライドしていたときにリスクを伴います
'no_alias_functions' => true,
no_blank_xxxxxx
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_blank_lines_before_namespace' => true,
'no_break_comment' => true,
no_blank_lines_after_class_opening | no_blank_lines_after_phpdoc | no_blank_lines_before_namespace | no_break_comment | |
---|---|---|---|---|
@Symfony |
true | true | true | |
@PSR2 |
true | |||
画像 |
no_closing_tag
phpのとじタグ?>
はファイルの最後尾から削除します
-
@PRS2
,@Symfony
でデフォルトtrue
です
no_empty_comment, no_empty_phpdoc, no_empty_statement
空のコメントやphpdoc、ステートメントを削除します
-
@Symfony
でデフォルトtrue
です
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
no_empty_comment | no_empty_phpdoc | no_empty_statement |
---|---|---|
no_extra_consecutive_blank_lines
余計な改行を削除します
-
@Symfony
でデフォルトで以下が指定されます
'no_extra_consecutive_blank_lines' => [
'tokens' => ['extra']
],
no_leading_import_slash
use
宣言先頭のバックスラッシュを削除します
-
@Symfony
でデフォルトtrue
です
'no_leading_import_slash' => true,
no_leading_namespace_whitespace
namespaceの前にスペースがあったとき削除します
-
@Symfony
でデフォルトtrue
です
'no_leading_namespace_whitespace' => true,
no_mixed_echo_print
echo
と``print`のどちらかに記述を統一します
-
@Symfony
でデフォルトecho
が指定されます
'no_mixed_echo_print' => [
'use' => 'echo'
],//
no_multiline_whitespace_around_double_arrow
=>
の前後で複数行になるスペースを禁止します
-
@Symfony
でデフォルトtrue
です
'no_multiline_whitespace_around_double_arrow' => true,
no_multiline_whitespace_before_semicolons, no_singleline_whitespace_before_semicolons
セミコロンの前で複数行になるスペースを禁止します
no_singleline_whitespace_before_semicolons
は1行でもセミコロンの前にスペースを置くことを禁止します
-
@Symfony
でデフォルトtrue
です
'no_multiline_whitespace_before_semicolons' => true,
'no_singleline_whitespace_before_semicolons' => true,
no_multiline_whitespace_before_semicolons | no_singleline_whitespace_before_semicolons |
---|---|
no_php4_constructor
PHP4での形式の__construct
を書き換えます
'no_php4_constructor' => true,
no_short_bool_cast
二重感嘆符を使ったbool
キャストを禁止します
-
@Symfony
でデフォルトtrue
です
no_short_echo_tag
<?=
の代わりにロングタグの<?php echo
に置き換えます
no_spaces_after_function_name
メソッド名の宣言後にメソッド名とカッコの間にスペースを入れてることを禁止します
-
@PRS2
,@Symfony
でデフォルトtrue
です
'no_spaces_after_function_name' => true
no_spaces_inside_parenthesis
開始カッコの後と閉じカッコの前のスペースを削除します
-
@PRS2
,@Symfony
でデフォルトで以下が指定されます
'no_spaces_inside_parenthesis' => true,
no_superfluous_elseif,
no_useless_else
(例えばreturnしている場合など)不要なelseif
をif
に置き換えます
不要なelse
を削除します
'no_superfluous_elseif' => true,
'no_useless_else' => true,
no_superfluous_elseif | no_useless_else |
---|---|
no_trailing_comma_in_list_call
リスト関数で余計なカンマを削除します
-
@Symfony
でデフォルトtrue
です
'no_superfluous_elseif' => true,
no_trailing_comma_in_singleline_array
単一行で記述する配列で余計なカンマを削除します
-
@Symfony
でデフォルトtrue
です
'no_trailing_comma_in_singleline_array' => true,
no_trailing_whitespace
末尾の空白行を削除する
-
@PRS2
,@Symfony
でデフォルトtrue
です
'no_trailing_whitespace' => true,
no_trailing_whitespace_in_comment
コメントとphpdoc内の余計な空白を削除する
-
@PRS2
,@Symfony
でデフォルトtrue
です
'no_trailing_whitespace_in_comment' => true,
no_unneeded_control_parentheses
制御構造の周囲にある余計な( )
を削除します
-
@Symfony
でデフォルトで以下が指定されます
'no_unneeded_control_parentheses' => [
'statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield']
],
no_unneeded_curly_braces
コントール制御以外の不要な{ }
を削除します。
-
@Symfony
でデフォルトtrue
です
'no_unneeded_curly_braces' => true,
no_unneeded_final_method
final
宣言されているクラス内でfinal
宣言された関数からfinal
を削除します
-
@Symfony
でデフォルトtrue
です
'no_unneeded_curly_braces' => true,
no_unreachable_default_argument_value
デフォルト値が後続の引数で指定されていない場合は引数のデフォルト値を削除する
- 関数のシグネチャを変更します。したがって、それらに依存するシステム(例えば、リフレクションを通して)を使用している場合(Symfonyの一部のコンポーネントなど)ではリスクを伴います。
'no_unreachable_default_argument_value' => true,
no_unused_imports
使っていないuse宣言を削除します。
-
@Symfony
でデフォルトtrue
です
'no_unused_imports' => true,
no_useless_return
メソッド末尾で何も返さないreturn
を削除します
'no_useless_return' => true,
no_whitespace_before_comma_in_array
配列内で、カンマの前にスペースを禁止します
-
@Symfony
でデフォルトtrue
です
'no_whitespace_before_comma_in_array' => true,
no_whitespace_in_blank_line
空白行でスペースを禁止します
-
@Symfony
でデフォルトtrue
です
'no_whitespace_in_blank_line' => true,
non_printable_character ~ yoda_style
comming soon!!!
始めてみたら相当な量があり、想像以上のボリュームになってしまいました。
やりだしたら徹底的にやりたい性格なので12/2までに最後まで到達できませんでしたが、一番わかり易いリファレンスになるように最後は気合と意地で随時追記をしていきます。
ランサーズのアドベントカレンダーはエンジニアブログを中心に引き続き各メンバーが公開していきます。
明日の担当は平成元年生まれの同い年で、ランサーズが誇るReactおじさん @numanomanu さんです!! お楽しみに