2014年8月12日火曜日

PHPerの書くコードの保守性・管理性が劇的に上がるのスマートな方法

みなさんお仕事の進捗どうですか?
今日は



こんな軽はずみな発言をしてしまったが故にネットで触れては行けない3大炎上案件について触れる。

※ネットで触れては行けない3大炎上案件とは?
  • Excel関連(スクショとか)
  • 宗教(エディタとか)
  • PHP
のこと。

で今話題の元ネタを既に@sue445さんが魚拓してくれてる。

(炎上したら即魚拓とれるとか世の中ホントに怖い便利になったもんだ。)
なのでもしかしたら炎上して灰になるかもしれないけど勇気出して対抗記事を書く。

■はじめに

まず最初に言っとくけどPHP特有のずっと変わらないスマートな書き方ってあんまり無い。
ずっと変わらないのはPHPとか関係なく世間一般的に読みやすいコードの共通事項。
そういうのは世の中にいっぱいあるのでそう言うところで学ぶと良い。
例えばまずリーダブルコード読む。



これを読んだら
  • 変数のスコープは小さくしよう
  • わかりやすい名前を付けよう
  • ロジックはシンプルにしよう
とか自然と考える。
そしたら使いまわされるたった一つの変数に全部配列で突っ込んで管理とか数千行あるメソッドとか無くなるはず。
これだけで保守性とか管理性が劇的に上がると思う。
こういうのは言語関係ないのでみんなが学んでいくべき。
そして先人が知の高速道路を用意してくれてるのでありがたく活用するといい。

結論これで8割くらいの問題が解決すると思う。
けどそれ言うと終わっちゃうので読みやすいコードを書くことを踏まえた上でPHP特有の事を書いていこうと思う。

1. PHPの今を知る

まずPHPの最近の事情を知るべき
当たり前だと思うかもしれないけどまずホントこれ。
例えば非推奨の関数のereg()使ってる人とかまだ見かける。
そういうのを知りたかったら

PHP:The Right Way

を見ると良い。
原文はGithubで最新情報に常に更新されてる

Githubのリポジトリ

基本の項目を読むだけでもヒアドキュメント構文や三項演算子にも触れているので初級者PHPerにはとても有効だ。

PHP:The Right Way 基本の項目

ただ個人的には変数の宣言については一概に宣言を省略すれば良いとも言えないと思ってる。
たとえば
$fuga = hoge();
みたいな既存のコードで変数もメソッドも一見して意味がぜんぜんわかんないコードと出会った時。
ホントはちゃんとテストコードがあってリファクタリング出来ればベスト。
だけどこんなコードがあるようなプロダクトはテストコードも無い。
しかも$fugaのスコープが長すぎて消すことすら不安。
そんなときに
$users = $fuga;
として$usersを使うのは良いと思う。
これはコメントでもいいけどこういうちゃんと自分なりに意図があってすることには意味がある。

と話が脱線したね。
PHP:The Right Wayを全部読んだら大抵のことは出て来る。
コーディング規約のPSRなんかは新規案件なんかは積極的に取り入れた方が良い。
でも
  • PHP のオブジェクト指向
  • クロージャなどの関数型指向
  • PDO
  • Composer
なんかは読んだだけじゃすぐにはわからないかもしれない。
そういう時はわからない箇所にフォーカスした本を呼んだり実践で試したりを繰り返しやると良い。
オブジェクト指向とかデザインパターンとかいきなり全部スーッと入って来ない。
PHPの良い所はそういうことに対しての正しい情報(ドキュメント)がちゃんと用意されてる。
そして同じくらいダメな情報も用意されてる…
ここで大事なのは情報の選択。
なのでPHP:The Right Wayを更新してるエンジニアのTwitterをフォローしたりすると良い。
(正直自分も完璧である自信はないから今繰り返してる途中)

2. フレームワークを使う

もし今から新規開発をするとしてプレーンなPHPだけで開発をするのはやめた方がいい。
工数もかかるけどそれ以上にオレオレで実装した箇所を保守するのが大変になる。
だからオープンなフレームワークを使うこと。
ただ残念なことにPHPにはRuby On Railsみたいな標準となるフレームワークは無い。
しかしPHPにはオープンなフレームワークが沢山ある。
そんな中でちょっと前までは4大フレームワークは
  • CodeIgniter
  • CakePHP
  • Symfony
  • Zend Framework
と言われていた。
でも最近は
が勢いのある。
ただCakePHPも3系に上がったりSymfony2も2.5が出たりとしてる。
既にそっちを使ってる人が無理に乗り換える必要はない。
でも僕はFuelPHPが好きだからここを読んだ人にはFuelPHPを薦めておく。
LaravelとかPhalconとかYiiがすごくいいよ!って人が居たら是非とも良さをエントリーを書いて伝えて欲しい。
(それを見て僕も、もしかしたら乗り換えるかもしれないw)
でここから先は便宜上FuelPHPを選んでくれたとして話する。
まず知っておくことは
これらが必ず助けてくれるはず。
これらを見てまずはインストールして試してみるとFuelPHPの良さにすぐ気づくはずだ。
え、もっと親切なHow Toが欲しい?
そういう人はこれを読むといい。
FuelPHPの使い方だけじゃなくてIDEやPHPUnitを使ったユニットテストとか開発環境の使い方まで網羅してる。
「最近のモダンなPHP開発を知りたい!」って人も読んでみるといいと思う。
なんかFuelPHPの宣伝になってしまったけど開発をするならなんらかのフレームワークは使った方がいい。
その中でも人気のモノは人気の理由があるからそこに乗っかった方がいい。

3. なんでもかんでもCMSを辞める

さっきのフレームワークの延長上にCMS(コンテンツマネジメントシステム)がある。
これは完成されたアプリケーションを利用するというものだ。
もし、今必要とされてるプロダクトが完全にマッチしてるならCMSを使うといい。
けどPHP界隈では

  • ECサイトはとりあえずECCUBEのカスタマイズ
  • フレームワークのようになんでもWordPressを使って制作

みたいなことを見かける。
それぞれ優れたCMSだけど得意不得意はある。
これはフレームワーク以上に明確にある。
たとえばECCUBEは確かにECサイト向けのCMSだけど注文カートをカスタマイズは大変。
WordPressは本来ブログを作るものだ。
それを無理矢理カスタマイズしてECサイトや複雑なWebサイトにするのはイケてない。
例えばポータルサイトならMagic3が適してるしECサイトはZen Cartだってある。
もちろんブログ付きのホームページを作ったりするのにWordPressは抜群の効果を発揮する。
つまり適材適所が大切。
そしてどれもマッチしないならどれかを無理矢理カスタマイズするよりはフルスクラッチで作ったほうが良い事が多い。

まとめ

結局のところ



これ。
そうすると自然と自力も上がるし保守性・管理性も上がる。
自力が上がれば他の言語に手を出したり(そしてPHPを卒業したり)PHPの良し悪しを汲んであげれるはず。
ということで


コレ最強。
以上がそーだい的な保守性・管理性を劇的に上げる方法。





おまけ

PHPの保守性・管理性とは関係ないけどおまけ。


1. PHPの苦手なことは他に任せる


もう身も蓋も無いけどPHPはみんなの知ってる通り万能な言語ではない。
CMSと一緒で得意不得意があるし特に不得意なところに関しては滅法弱い。
これは変数の扱いが曖昧とか関数の命名規則が統一されて無くてイケてないとかじゃない。
こういう言語としてイケてないところが致命的と感じる場合はPHP以外の言語を書くしかないかな
(「他の言語を書く」の選択肢には転職とかも含めてね)

ここでの苦手なことは「実際にPHPでこれをやろうとしたら苦行」みたいな事。
例えば
  • 並列処理
  • 複数プロセス間(複数アクセスに対してとか)のリアルタイムなデータ共有
とかはもう言語仕様としてそうなってるのでそこを超えるのは大変なのは当たり前なんだけど大変。
プロセス間通信が必要な処理とか書いてもCと変わらない。
(Cが簡単と言う人には簡単かもしれないけど僕は違った)
マルチスレッドとかもそうだけどこういうのはC#とかJavaで書いた方が幸せになれると思う。
(最近だとErlangなのかな?)
他にもinputとoutputがハッキリしててアクセスが多くて速度が重視するような場合(RESTAPIとか)はPHPで書くよりScalaで書いたが絶対幸せになれる。
WebSocket使うような非同期処理ならNode.jsとか使ったほうがいいと思う。
型安全とかもそうだけどプロダクトとしてそちらが適してるならそっちを使ったほうがいい。

ただPHPも得意なことはある。
シンプルなWebサービスを作るときは簡単だし高速。
開発環境はライセンス費を掛けずにIDEもあるしvagrantなどツールも充実してる。
TDDやBDDもできるしテストの自動化みたいなひと通りの流行りの事は出来る。
それとPHPは別にセキュリティが苦手なわけじゃない。
セキュアなWebアプリって観点だと最近のモダンなフレームワークでちゃんと作れば問題ない。
セキュリティに関しては言語関係なくセキュリティに対する知識とフレームワークやミドルウェア含めバージョンアップ出来る状態の維持が一番大事だと思う。

2. 保守性はコードも大事だけどデータも大事


コードの保守性も確かにとても大事なんだけどそれと同じかそれ以上にデータも大事。
具体的にはクソなDB設計の上には何を作ってもクソ。
例えばどんなに綺麗に設計してもtext型で巨大な文字列とか入ってると*を使うORMが死ぬ(速度的に)
他にも1テーブルに100カラム以上みたいなSQLアンチパターンがあるとクエリビルダでも死ぬ(つかSQLが死ぬ)
でアプリケーションの寿命よりデータの寿命の方が長いからデータの闇は深い。
あるあるネタだけど5年前くらいのアプリケーションのリプレース案件。
コードは綺麗に出来るけどデータは既存から持って来ないといけない。
そこで立ちはだかる数百のテーブルと複雑に絡み合うViewとトリガー…みたいなとき(この場合は担当者が死ぬ


ということでコードに対する向上心と同じようにデータ設計に対する向上心も持ってほしい。