一つ一つが小さいので、まとめましたよ。
1.switchの分岐
もう、すっかりお約束かと思うんですが、
「switch($data)」と書いた時に、「==」で比較されますよっていうやつ。
で、以下の様な解決策が、提示されてますと。
ケースごとに異なる処理を、ポリモーフィズムで表現する(生PHPで) - Qiita
あるいは、上記の参考リンクに書かれている以下とか。
PHP :: switch の case 文で厳密な型比較をする [Tipsというかメモ]
・・・これなら別に、if~elseでもよくない?と思ってしまったんですよね(苦笑)
いや、別の記事にもリンク貼った事ありますが、
個人的に、以下の様なコードもあるので、stateパターンを使う事に否定的ってわけじゃないんですけど。
final_magic/view.php at master · kitoku-magic/final_magic · GitHub
ただ、分岐した「後」の、各クラス毎の処理の差異が殆どない様なケースだったら、
別に、そこまでしなくても良いんじゃないかなぁと。
「今はまだ少ないけど、これから差異が増える(この考えもYAGNI観点からは微妙ですが)」のが、
「確定」レベルならアリでしょうけど、そうじゃないのにって所じゃないですかね。
単に、「何がなんでもデザパタを適用する」的な、信者的な考えが苦手って話な気もしますけどね(苦笑)
2.HTMLのnameやDBのカラム名の、スネーク・キャメルの統一
結構、昔から時々感じていたんですけどね。
「user_id」と「userId」が混ざってますと。
で、混ざっているが故に、以下の様なコード(あくまで一例)をわざわざ書く必要があると。
$data = array( 'user_id' => $_POST['userId'], );
$entity->setUserId($_POST['user_id']);
$result = array( 'userId' => $row['user_id'], );
$entity->setUserId($row['user_id']);
とりあえず、最も多そうなケースとして、
「DBのカラムでuserIdというケースを見た事がない」のは、大文字・小文字を区別しない以下が原因かなと。
【MySQL】カラム名の大文字、小文字の区別 at softelメモ
といっても、別に「userId」というカラム名にしても良いじゃないかとも思うんですが、一旦置いておきましょう。
ただ、そうなると命名を統一するには「set_user_id()」となり、ここに違和感を感じる人が多いんだろうと。
いや、「setUserId」だろう?なんか、変じゃね?と。
といっても、set_user_idにしたら、何か問題が起きるのかという所なんでしょうと。
・・・何が理由があるんですかね?いや、命名が統一されているケースは、おそらく一度も見た事が無いので。
問題があるなら、統一されてなくても全然良いんですけど。
個人的にはスネーク派ですが、何も問題が無いなら「どちらかに統一」をって思うんですよね。
統一されていれば、キャネルでも良いよと。
3.DateTime::createFromFormat
これはマニアックな気がしますが、例えば以下の様(PHP7.2.10)に書くと。
<?php // ケース1、問題無し $datetime = new DateTime('24:59:59'); var_dump($datetime); // ケース2、問題無し $datetime = new DateTime(); $datetime->setTime(25, 0, 0); var_dump($datetime); // ケース3、問題無し $datetime = DateTime::createFromFormat('H:i:s', '25:00:00'); var_dump($datetime); // ケース4、指定されているフォーマットと違うので、$datetimeがfalseになる $datetime = DateTime::createFromFormat('His', '25:00:00'); var_dump($datetime); // ケース5、Fatal Error $datetime = new DateTime('25:00:00'); var_dump($datetime); $ php datetime_test.php object(DateTime)#1 (3) { ["date"]=> string(26) "2018-11-25 00:59:59.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" } object(DateTime)#2 (3) { ["date"]=> string(26) "2018-11-25 01:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" } object(DateTime)#1 (3) { ["date"]=> string(26) "2018-11-25 01:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" } bool(false) Fatal error: Uncaught Exception: DateTime::__construct(): Failed to parse time string (25:00:00) at position 0 (2): Unexpected character in ・・・以下、省略
となるので、「DateTime::createFromFormat()」が良いんじゃないの?と。
特にケース4が良いと思いますね。
応用すると、以下の様な事も出来ますし。
【PHP】DateTimeクラスでcheckdate()より汎用性のある日付チェックを行う - Qiita
注意点としては、上記の場合「年月日が翌日になる」って所でしょうか。
4.DateTime同士の日時比較
↑の3と関連しているんですが。
注意:
ちょっと意外だったので、驚きましたね。
実例は、上記リンク先に書いてあるので、省略します。
5.stringとintの比較時のキャスト
例えば「リクエストパラメータの値(string)と、DBから取得してきた値(最近は、intのケースが多いか?)」を比較する時に、
「intをstringにキャスト」するか、「stringをintにキャストするか」的な話なんですが、
<?php $request_parameter = '1a'; $db_value = 1; if ((int) $request_parameter === $db_value) { echo "string to int\n"; } if ($request_parameter === (string) $db_value) { echo "int to string\n"; } $ php cast_test.php string to int
と通ってしまうので、「intの方をstringにキャストする」が良いかなと。
といっても、値が大きくてfloatの場合、
stringにキャストしたら以下の様になるので、そこは別途注意でしょうけどね。
<?php $db_value_int = PHP_INT_MAX; $db_value_float = PHP_INT_MAX + 1; var_dump($db_value_int); var_dump($db_value_float); var_dump((string) $db_value_int); var_dump((string) $db_value_float); var_dump(sprintf('%u', $db_value_int)); var_dump(sprintf('%u', $db_value_float)); $ php cast_test.php int(9223372036854775807) float(9.2233720368548E+18) string(19) "9223372036854775807" string(19) "9.2233720368548E+18" string(19) "9223372036854775807" string(19) "9223372036854775808"
6.NOT NULLが付いていない
「数値型の0や、文字列型の空文字の値に、特別な意味があったり、既存との値の体系的に、どうしてもNULLが必要」
ってケースぐらいですかね、NULLを許容する必要があるのって。
それすら微妙でしょうか?
user_idが0、日付が0001-01-01(ここは、さほど調べてませんが)、名前が空文字、statusが0・・・
statusが0のケースが時々って所じゃないですかね。
新規で作るならstatusが0の場合にも意味を持たせない方が良いと思いますけど。
書き切れないぐらい色々なケースがあるでしょうけど、やっぱりNOT NULLを付ける形が良いんじゃないかなと。
いや、単純に以下の様な事をいちいち意識したくないってのが、本音ですけどね(笑)
7.O/Rマッピングについて
先日、以下の記事が盛り上がってましたので。
これ、以下の記事では主題じゃなかったので書かなかったですが。
以下の様に、「SQLは書くけど、全部じゃないよ」的なO/Rマッパーじゃダメなんですかね。
other/order_repository_impl.php at master · kitoku-magic/other · GitHub
「和洋折衷」というか、良いとこ取りみたい感じですけど(笑)
あと、直でSQLを書いているというルール違反については、
「SELECT 」「INSERT INTO 」「UPDATE 」「DELETE FROM 」とかでGREPして、
以下のクラス「以外」がヒットしたら「おや?」とかね。
other/rdbms_storage_handler.php at master · kitoku-magic/other · GitHub
なので、既存のFWでも、あまりガッツリ使わなければ良いんじゃないかと思いますね。
要は、「変わったSQLを書くときに、どうか?」ってのがポイントなんじゃないのかと。
以下の様なSQLを、業務で書く必要があったらとか。
other/reservation_double_booking_check.php at master · kitoku-magic/other · GitHub
8.SQLで取ってきたデータに、使いたいカラムが含まれていない
上記の7とも少し絡むんですが、
「SQLで項目が指定可能だと良い」と。
いや、別にどうって事ない話なんですが。
というのも、項目が固定だと「不要だと思ったら、後で必要になった」的なケースが何度も起きて、
その度にソース修正するの?と。
だから、常に全項目取得(パフォーマンスはありますが、ここはさほど)で良いんでは?とも思いますが、
流石に不要項目(上記の通り、不要だと思ったら、後で必要になったりもしますがね)があまりにも多過ぎる場合にはとも思いまして。
なので、「項目を指定しなければ全項目取得だが、項目を指定する事も出来る」が良いかなと。
必要なデータを取得する時に、項目が指定可能とかも。
外部APIの場合は、項目を細かく指定するのは難しいかもしれないので、
「全項目フラグ=true or false」みたくなるかもしれないですけどね。
以上です。
ここまで書き終えて、以下の話じゃないけど、
基本的に「大したことじゃない事」に、頭を使いたくないみたいですね(苦笑)
どこにリソースを突っ込むのか? って選択は大事だよねぇ - gallu’s blog
あと、本日のBGM(曲の途中から)は・・・以下かな(笑)
Within Temptation - Whole World is Watching ft. Dave Pirner - YouTube