はじめに
PHP Advent Calendar 2016 20日目の記事です。
PHP7で堅牢なコードを書くの記事が、だいぶ話題になりました。スライドしか見ていないのですが、共感するところが凄く多かったです。それにあやかって、普段のphpでの開発の際に注意していること・やっていることを整理してみました。
もともとはJavaの経験が長く、IntelliJ IDEAを使っていたので、同じところが出しているPhpStormを使って開発しています。その機能を使っていくと、ある程度はJavaと近い感覚でコードを書けるというお話です。
変数がどの型なのかを指定するドキュメンテーションコメント
symfonyのコンテナーから取り出した場合、型がわからなくて、どのメソッドがわからなくて困る、といったことがあります。そういったときは、下記のようにしてローカル変数に対してコメントをつけると、その変数の型をPhpStormが認識して、メソッドの補完などをよろしくやってくれます。
http://symfony.com/doc/current/service_container.html からの引用ですが、下記のままだと $mailer
のsendメソッドは補完ででてきません。
class HelloController extends Controller
{
// ...
public function sendEmailAction()
{
$mailer = $this->get('app.mailer');
$mailer->send('ryan@foobar.net', ...); ← 型がわからないのでPhpStormならwarnが出る
}
}
次のようにすれば、warnがでなくなり、 $mailer
にMailerクラスのメソッドが補完候補に出てくるようになります。
/* @var $mailer AppBundle\Mailer */
$mailer = $this->get('app.mailer');
PhpStormで型を指定した配列のドキュメンテーションコメントの付け方
例えば、returnされるもので、「文字列のarray」、「自分がつくったクラスの配列」など、型を指定した配列をphpdocに記述したいとき。Javaをやってきた人なら欲しくなるやつです。
* @return string[]
* @return Sample[]
という風に、 XXX[]
とすればOKです。
Find usagesでメソッドが使用されてる箇所を一覧表示
あるメソッドがどこで呼び出されているかは、Alt + F7(右クリックメニューのFind usages)で検索して一覧表示してくれます。メソッドを直した場合の影響範囲や、どのような使われ方を知ているのかを調べるのに便利です。
public function isXXX() {...} ← メソッド名にフォーカスあてて、Alt + F7 or 右クリック
注意
twigなどのテンプレート上で使用される場合や、PhpStormが型が判定できない形での使い方(symfonyのservice containerでgetした場合など)は検索結果にあがってきません。そういうケースはプロジェクト内の文字列検索で拾ってくるしかないです。Ctrl+Shift+Fでそのダイアログが表示されます。
@see
や@deprecated
などのドキュメンテーションコメントを活用する
機能改修や追加の際、工数や仕様の都合上(ex:古いルーティングは残して新しいURLへリダイレクトさせる)、新旧のクラスが共存するケースがあります。その際に、新旧がわかりやすくするのに、 @deprecated
をつけるというのがひとつの解決策です。さらに、 @see
で新しいクラスへ参照させるルートを作れます。 @see
にクラス名にフォーカスしてCtl + B(宣言箇所の呼び出しのショートカット) で該当クラスを開いてくれます
@deprecated 古いファクトリクラスです
@see NewFactory 新しいファクトリクラス
public class OldFactory {
}
@deprecated
はメソッドにもつけられるので、場当たり的でやむなく作ったが、他では使って欲しくないのをアピールするのにも使えそうです。
@deprecated 副作用がありすぎてこれ以上使うとやばいので新規開発では使わないでください
public function dirty_method() {...}
ただ、いずれにしてもチーム内でこれらをどのように使うか、どういったコメントを残していくかの認識のすりあわせができているのが大前提です。
git blameやコミット履歴の閲覧
blameやhistoryを見たいファイルを開いて、右クリック>Git>Annnotate でgit blame、 Show Historyでこれまでのコミット履歴の一覧が表示されます。
どのチケットで入った処理なのか、なんのための処理かをコミットコメントからも情報を得たい場合や、誰が書いたものかなどを見るのに重宝します。
GitHubのように、blameから該当コミットのdiffにいくということもできるので、gitのリポジトリブラウザがなかったり、ちょっとしたものをみたい場合にも便利です。
PhpStormでPECLのメソッドを補完させる
https://github.com/JetBrains/phpstorm-stubs をダウンロードし、standardディレクトリを、Preferences | Languages & Frameworks | PHP | Include path
に追加。
一部、もとからあるのと競合するせいでwarnが出るが、気にしなければなんとか。
比較の問題
使い古されたネタですが、自分もこれ関連で何度も罠にはまったので、整理もかねて。
==
によるゆるい比較をするせいで思わぬ結果がでるという話です。PhpStormのデフォルトだと、==
で比較しているとwarnがでてくるので、ある程度は気づきやすいですが、はまるときははまるので、問題のパターンを知っておくと出くわしたときに原因にたどり着きやすいです。
2a問題
超がつくほど有名らしいです。
$a = '2a';
$b = 2;
print ($a == $b);
// => true
以上のように、文字列の2a
と数字の2
が同じになる現象です。
===
で、型を含めての厳密な比較をすれば回避できます。
0e問題
md5のハッシュ値の比較で有名のようです。
- http://stackoverflow.com/questions/22140204/why-md5240610708-is-equal-to-md5qnkcdzo
- http://peccu.hatenablog.com/entry/2015/05/23/000000
- https://twitter.com/sc00bzt/status/440759501973495808
$a = '0e678342453'
$b = '0e123435465'
print ($a == $b);
// => true
全然違う文字列に見えるのに、同じなってしまう現象です。
何が起きているかというと、eがあるせいで、指数表記と解釈されるのが原因です。
0^673 = 0 = 0^123
ということで、両方とも0になるから、ゆるい比較だと同じになるということ。
これも===
で比較すれば回避できます。
switch文
switch文のcaseでの比較は==
なので、上記のような問題にはまりやすいです。
下記の記事がよくまとまっているので、こちらを参考にしてもらえればと。
PHPerが知るべきswitch文の6つのこと
参考サイト
- http://www.karakaram.com/phpstorm-plugin-php-annotations
- http://stackoverflow.com/questions/30328805/phpstorm-how-to-add-method-stubs-from-a-pecl-library-that-phpstorm-doesnt-curr
- http://koni.hateblo.jp/entry/2016/01/12/090000
- http://www.karakaram.com/phpstorm-useful-tips1
- http://qiita.com/Vexus2/items/d30d566944a39c773a3d