1. shinkuFencer

    Posted

    shinkuFencer
Changes in title
+PHPで出来てしまうが控えたほうががいい書き方
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,147 @@
+正常系は上手く動くし問題ない!と思ってもケースによっては危なかったり
+あんまりよくない書き方ってあると思います。
+そういうような控えたほうががいいような書き方をケース別にまとめたものです。
+まばらには書かれているんですが、一つの場所にはまとまってないのでメモがてら。
+
+## ==での比較
+
+違う言語から戻ってくると間違って書いてしまいがちな判定。
+以下のようなコードがあるとします。
+
+```php
+if ($target == 1) {
+ echo 'this is 1';
+}
+```
+
+普通に1で通るのですが、1以外のものも結構判定が `true` になってしまいます。
+`true` になってしまうものとしては以下。
+
+```php
+$target = "1";
+$target = true;
+$target = "1aaa";
+
+// 上記はすべてtrueになる
+```
+
+すべて暗黙の型変換が原因
+暗黙の型変換を頼りたい場面(そんなにないと思いますが)以外は
+`===` を使った方がいいと思います。
+
+## 空文字判定としてのempty
+
+上記で取り扱った例に近いのですが
+`empty()` は 空文字以外にも色々 `true` 扱いしてくれます。
+
+> [PHP: empty \- Manual](http://php.net/manual/ja/function.empty.php)
+
+>次のような値は空であるとみなされます。
+"" (空文字列)
+0 (整数 の 0)
+0.0 (浮動小数点数の 0)
+"0" (文字列 の 0)
+NULL
+FALSE
+array() (空の配列)
+$var; (変数が宣言されているが、値が設定されていない)
+
+0という文字も空扱いになってしまいます。
+そのため、「何も文字が入って来ないときは変わりに文字を代入」のような処理の場合は
+空白比較をしたほうが良いです。
+
+## 配列の宣言なしでの代入
+
+下記のような処理があるとする。
+
+```php
+$array = [];
+$array['flower'] = "yeah";
+$array['star'][1] = "hoge";
+$array['star'][2] = "hoge";
+```
+
+`$array['star'] = []` ってわざわざ宣言しなくても
+配列ができあがってくれます。
+簡単な処理なら便利なのですが
+以下のようになってしまうと値が入らなくなってしまいます。
+
+```php
+$array = [];
+$array['flower'] = "yeah";
+// string型のものを入れる
+$array['star'] = "string!";
+// すでにstringが入っているので代入できない
+$array['star'][1] = "hoge";
+$array['star'][2] = "hoge";
+```
+
+そのため、できるだけ配列をネストしたりする場合は
+空配列を宣言しておいたほうが明示的でわかりやすくなるので安心です。
+
+## arrayを引数とするfunction
+
+以下のような処理があるとする
+
+```php
+public function jsonToProfileText($json)
+{
+ // jsonをデコードしてarrayに
+ $student = json_decode($json, true);
+ return $this->createProfileText($student);
+}
+
+private function createProfileText($student)
+{
+ $name = $student['name'];
+ $age = $student['age'];
+ return "My Name is" . $name . ", " . $age . " years old.";
+}
+```
+
+arrayにすべてのデータが入ってて、そのまま渡したほうが楽なので引きまわしてます。
+
+この場合、配列なので想定キーに文字列が入っていない場合があります。
+その場合配列の中にキーがあるかまで気にしないといけないので
+もし厳重にチェックしたい場合は配列のキーチェックなどが必要になります。
+でも `createProfileText` は文章を作る処理なのにキーを気にするのは
+文章作るという作業の範疇を超えている気もします。
+
+渡してあげる文字を気にするのはどちらかと呼び出し側なので
+呼び出し側で見てあげて、文章を作る方には必要な要素だけ渡してあげると
+`createProfileText` は文章をつくることに集中できます。
+
+上記のことを踏まえて直すと以下のようになります。
+
+```php
+public function jsonToProfileText($json)
+{
+ $student = json_decode($json, true);
+ return $this->createProfileText(
+ $student['name'],
+ $student['age']
+ );
+}
+
+private function createProfileText($name, $age)
+{
+ return "My Name is" . $name . ", " . $age . " years old.";
+}
+```
+
+こちらに関してはケースバイケースなので
+必ず分解してパラメータを渡そう!ってことではないですが
+考え方として頭に入れておくと空チェックなどが集約できますし
+見通しがよくなることがあります。
+
+## 外部参考URL
+
+### まとめる上で参考にしたページ
+
+* [PHPの文字列比較で気をつけるべきこと – 暗黙の型変換 \- EC studio 技術ブログ](http://techblog.ecstudio.jp/tech-tips/php-string-compare.html)
+* [PHP isset, empty, is\_null の違い早見表 \- Qiita](http://qiita.com/shinichi-takii/items/00aed26f96cf6bb3fe62)
+
+### その他有用Tips
+
+* [isset\(\)と\!is\_null\(\)の値は常に等しいか \- cnrdの日記](http://d.hatena.ne.jp/cnrd/20091127/1259235755)
+* [PHP初心者が仕事で躓いた4つの罠 \- pixiv inside](http://inside.pixiv.net/entry/2015/12/02/203958)