がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

あえての「WAF(FW)使わない」PHPサイトの開発(副題: でなきゃ定期的にバージョン上げろ)

微妙暴言のお時間でございます*1
いやまぁ昨今、サイト作るのにWAF/FW(Web Application Framework で Framework の略な)を使わない、って選択肢も稀かなぁと思っております。
……いやまぁ「うちのFWはSmartyです」とか言われた頃が(うっすらした殺意と共に)懐かしいのですが、昨今はそーゆー事もなく、Laravelとかチョイスされる事は多いんじゃないかと思います*2

でまぁ、別にFWがLaravelでもCakePHPでもSlimでもSymfonyでもYiiでもPhalconでもZend FrameworkでもFuelPHPでもCodeIgniterでもBEAR.Sundayでも ちいたん でもKonahaでもEthnaでもMojaviでもPiece Frameworkでもいいのですが*3 *4
割と気になるのが「そのFWのサポート寿命」と「メジャーバージョンアップにおけるハードルの高さ」。

勿論理想としては「FWのバージョンアップに合わせてこまめに調整とリファクタをしてちゃんとついていく」事で、それが出来るんならどのFW使ってもよいかと思うんですよ……次点は「FWのサポートが終了する時」で、その時に「どうするの?」ってあたりがちゃんとしているんなら。

ただ、割と見かけるのが
・FWのバージョンアップはしない(マイナーとメンテナンスは上げるけどメジャーは上げない、とか、メンテナンスは上げるんだけどマイナーメジャーは上げない、とかも含む)
・FWが「新しいバージョンのPHP」に対応していないからPHPのバージョンを上げない
ってスタンス。

いや別に「3ヶ月で終了するサービス」ならよいんですよ?
ただ、それが「年単位でビジネス上の計画も立っている」ような、それなりに末永いサイト(になるといいなぁ)である場合、ちょっとそれは「どうなんだろう???」と。

ちなみに最近「ローンチのタイミングですでに"Security fix期限が切れている"バージョンのFW*5をお使いになりやがってらっしゃる」ケースとかを以下検閲削除。
……じゃぁそれが「珍しい話か?」と問われると「割と見かける」んですよねぇ……… 勘弁してくれ orz

そーゆーのを数見てしまうと。
ふと「FW使わないで作ったほうが、PHPのバージョンはコンスタントに上げる事が条件だけど、より安全に回せるんじゃなかろうか?」とか思う事があったりするのですよ。
……いやまぁ「PHPのバージョンをコンスタントに上げる」事自体のハードルが高いんだろうけど……多分……高いかなぁ?……おいちゃんのやり方だとあんまり高くないっていうかマジでコンスタントに上げてるけど困った事ないし……そのうちその辺のノウハウ書こうかしらん? おいといて。
下手にFWに「振り回されて」「FW都合で"バージョン上げられません」って言うくらいなら「plainなPHPで開発してみたら?」とか思う事はまぁ、あったりするわけでございます。
まぁ「FWがやってくれていること」を全部自前、なので、相応のハイスペックスキルが求められますけどねぇ……*6 *7

とまぁ色々と考えたりするので。
ナニが言いたいかっていうと「運用までちゃんと想定して開発しようず、選択しようず」って話なんだけど、その辺、割と浸透してないような気がするんですよねぇ……という、「気付いて欲しい」ネタ。

ちな、Laravelは「LTS単位で乗り換えるとよいのかしらん?」って思ってたら、Laravelに熟達している複数人から「やめとけ。コンスタントにこまめに上げるのが一番楽」って言われたので、そーゆーもんらしいす。
おいちゃんは最近、Slimがお気に入り(自前のFW、どうしましょうかねぇ???)。

Slim、3から4へは「まぁまぁ書き換えがいる」んだけど「coreロジックは多分ほとんどいらない」ので……ニーズがあるんなら「Slim 3から4への移植方法」とか、どこかで書いてもよいのかも、って感じでございます。

……って話が、もうちょっと活発に行われるとよいんですけどねぇ。
PHPカンファレンスとかでしゃべれば?」ごもっともでございます orz *8

*1:いつものこと、って気がせんでもないんだが、まぁ

*2:個人的には嫌いですが、まぁ

*3:順不同

*4:色々微妙だったり懐かしかったりするんだが気にしちゃいけない

*5:えぇLaravelでございましたともさ

*6:古参だと割といけそうな気もするが

*7:……思い返すに「絶対無理だろう」と思われるメンツも相応にいらっしゃるので以下検閲削除

*8:なんとか参加は出来そうですが、ちょい前まで、参加できるかも微妙だったのですよ orz

心房細動 で 心臓カテーテルアブレーション やってきました

いやまぁタイトルそのまんまなのですが。なんかの参考にでもなればなぁ、と思いまして(笑

端的には
・大体言われている通りの事が多かった
・でも「あんまりネットでは書いてない」知見もあった
ので、その辺を織り交ぜながら。

術前
ネットに書いてある事とそんなに変わらないかなぁ、と。
なお、除毛はおいちゃんがかかった病院だと「自分でやる」「後で看護師さんがチェックする(で、おいちゃんの場合はやってもらいました)」ってくらいかなぁ。
入院したのは、手術前日でした。
やったのは、点滴用のルートを取るくらい、と、除毛。
手術の説明をうけました……まぁ一般的な「こんな手術します」「一応こんな危険性があります」などを一通り。
ただまぁ「手術の失敗の確率」もあるんだけど、失敗しても病院が「全力でリカバリしてくれる」だろうから、「リカバリまで含めて全部アウトな確率」とか考えた時に「手術、やっぱり怖いですぅ」とかいう選択肢になり得るはずもなく、スムーズに会話は終了。

手術そのもの
全身麻酔……というか正確には「しんこんすい」とか言っていたような気がするんですが、ググっても出てこない orz
説明としては「全身麻酔は麻酔科の先生がへばりつくけど、今回はそこまでではない、けど、がっちし意識はlostする」的な説明をいただいてました。
他にも色々説明はいただいていたのですが、ネットに載ってる話が多いので割愛。
んで、「今からお薬入れます」の一言で、そりゃもぉがっつりとほぼ一瞬で意識を失ってました(笑
なお、手術時間は(おいちゃんの心房細動の場合)2~3時間程度だろう、ってお話で、実際、2時間程度で終わっていたようです。

手術直後
気付いたら病室のベッドでした。「足を動かすな」って話だけ覚えていたので、しっかりと「動かさないように」気をつけていたのを覚えてます。
あと、点滴に一緒に「眠くなる薬」入れられてたようで(これは看護師さんに確認済)、ほぼまる1日、寝てました(笑
手術は朝だったので、13:30くらいには昼食をいただきました。ネットにある通り「串刺しのおかず+おむすび」でした(笑
朝食ってないから腹減ってるし食った……のですが、眠くなる薬があるからなのか胃があんまり動いて無くて、夜になっても胃に昼食が残ってる状態だったので、がっついたのはちょっと失敗だったかもしれない(苦笑
小のほうは尿道カテーテルでございました……違和感が半端ない(笑
なお、心臓カテーテルは「太もも(おいちゃんは右太もも)から3本」「首から1本」だったそうです。なんで、太ももと首に絆創膏(的な、もうちょっと医療用のやつ)。
あと、太ももは一針、縫っていました。

たしか6時間後くらいに
・傷口の確認
尿道カテーテル抜く
・看護師さんに付き添ってもらって僅かに歩行
ってな感じだったかと思います。なお「とはいえあんまり動くな」とか言われてました。

なお夜も串刺し飯でした(笑

翌日
ここ、ネットではあんまり見かけなかったのですが。
・心臓というか肺というかあたりに微妙な違和感なんだか圧迫感なんだか(+僅かに咳)
・発熱。おいちゃんは37.4~37.6度くらいを推移
ってな感じでした。
医師に聞くと「発熱は3~4割くらいの確率である。とりあえずこれくらいなら大丈夫」との事でした。
まぁ(朝に採血からの)血液検査、心電図とレントゲンとってその結果を見つつ、でしたが。
……ぶっちゃけ「このタイミングでコロナ?」とか、幾分、ドキドキではありました。
で……足の一針を抜くのですが、結構いたかった(苦笑
あれ、麻酔とか出来ないモンなんかねぇ???

翌々日
予定だと退院……で、予定通り退院。
発熱は36.8~37.1くらいで推移。
言われた辺りとしては
・一週間は入浴禁止(シャワーは可)
・一ヶ月は「激しい運動禁止」。激しいの定義が「脈拍110を超える」なので、ウォーキングを超えると結構アウト臭(笑
・ストレスは大変によろしくないのでとにかく無理すんな
あたりが印象的だったかなぁ、と(笑

でまぁ数日。
・思った以上に心肺機能が弱ってる
・発熱はじわりと続いてる(多分、ゆっくり治癒が進んでる)
ってあたりが個人的にはポイントかなぁ、と。
おいちゃんは「寝ると色々治る」体質のようなので、「ちょっと頑張り目にウォーキング、寝る」を1日に2~3セット繰り返してます。

で……「退院したら普通の生活に戻れます」とか書いてある所が多いように記憶をしているのですが「身体にそこそこダメージが残ってるので、しばらくは安静に平穏におとなしくしている」必要があるなぁ、と思いました。
まぁ「ハツ焼いてる」しな(笑
退院後、1週間くらいは「休み、ないし半休」くらいは出来るようにしておいたほうがよいと思います*1

あと、書きたかったのがお金の話。
「高額療養費制度がないとほんのりと死ねます」www

うちの病院の場合で、3割負担で、手術だけで60万弱www
高額療養費制度の上限突破しますが、高額療養費制度の上限で大体止まるので(+1%があるから、ちょっとだけはみ出る)。
いくらになるかは収入次第ではありますが*2、申請しておいたほうがよいんじゃないかなぁ、と。
申請は、市区町村(だったと思う……都道府県単位ではなかったような記憶がかすかに)単位でも違うんでしょうが、うちの場合は
・役所に行ってもいいし
・郵便で送ってもらってもよいし
って感じで。おいちゃんは郵送でお願いしましたが、速やかにいただけました。必要書類だけ用意しておこう。

まぁ、満額支払ってもたしか後で返ってきたような記憶があるのですが。


とまぁ。
術前術中は大体「ネットにある通り」なのですが、術後のお話が「いくつか、あんまり載ってなかった」のと、お金の話が思ったより重要だなぁと思ったので(笑
とりあえず「治療行為とはいえ、一時的には身体にダメージが入るから、しばらくはおとなしくしてような!!」というお話でございました。

……うん、頑張って出来るだけ休憩するようにするお orz

2020/11/10追記
「発熱」と「動機っぽいの」と「胸部の圧迫感っぽいの」が大体おちついた。
手術からだと5日、退院してからだと3日経過。
まぁ冷静に考えたら「早い」ような気もするんだけど、これくらいはかかるねぇ癒えるのに。

*1:思います……思います orz

*2:……無言

お仕事コードの書き方(の一部)

おいちゃん、経験的に、割合とPHPが長くなってきております。
んで、PHPでコード書くとき、割と色々と「丁寧に」書く癖があって。
特に昔は割と嫌がられたりしてたもんだけど、おかげでバージョンアップしても「平気の平左で」受け入れられるんだよなぁ、とかふと思い出しまして。
……なんて事を考えるとお仕事コードの書き方で「おいちゃんが気にしている事」があって、その辺を書いておくとなんか役に立つ事もあるのかなぁ? と思い、雑文を散らかしてみようか、と。

端的には
・キワを攻めない
に尽きるのですが……かみ砕いて。

例えばif文の評価式は最終的にbooleanが欲しいものでございます。が、関数やらメソッドやらの戻り値が、空文字だったり数値0だったりNULLだったりする事もございます。
とはいえその辺は暗黙の変換があるので

if (null !== 関数())

とか書かなくても

if (! 関数())

と書けば「nullがreturnされてきたからbooleanだとfalseだからそれの否定だから」で簡単に処理を書く事ができます。

複数の条件式があっても、括弧で囲わなくても演算子の優先順位があるから、優先順位をちゃんと理解していれば括弧なんて不要です。

型とか気にしなくても、例えば「文字が欲しい」ところに数値0書いたってよしなに解釈してくれます。

その他諸々。
言語仕様を「熟知していれば」こその、「一見不思議なんだけど、言語仕様を熟知していれば理解できる」書き方ってのは、色々とございます。

おいちゃん、上述を一通り「大変にお好まない」んですねぇ。
関数の戻り値云々で、多分これはそこそこ引っかかっている人もいたんだろうなぁと思われるstrpos()。
正直、あの問題おいちゃんは「1度も引っかかった事がない」んですが、マニュアルにも書かれているくらいなんで「結構引っかかった人もいるんだろうなぁ」とか、しみじみ。

っつかif文とかwhile文とかの条件式を書く所はちゃんと「条件式」で。
かつ、==ではなくて===で「型を意識して厳密に」。
かつ昨今なら「declare(strict_types=1);」付けて。
この辺を死守しておくと、少々ナニカがあってもあんまり困りません。

括弧はちゃんと付ける。
「これくらいは演算子の優先順位があるから」と思っても、異なる演算子があるんなら「このくくりと」「このくくりと」がわかるように、しっかりと丁寧に書く。
省略しない。

……若干悩むのが「インクリメントとかの前置と後置」ですが。
まぁPHPの界隈だと「そのテクニック使うな」って言われる事が多いですかねぇ。なので使わないようにしてます。

「ンなこと言ったってその辺の挙動、そうそう変わらないよ」ってよく言われるんですが。
【PHP8.0】非厳密な比較演算子`==`の挙動が今さら変更になる https://qiita.com/rana_kualu/items/82cc8295d2102d14b88a
【PHP8.0】演算子.と+の優先順位が変わる https://qiita.com/rana_kualu/items/db7ae541016bd0b02122
諸行無常。一切のものは流転し変化し、変わるものでございます。

まぁ関数やメソッドの戻り値は「falseかしら? NULLかしら?」って調べるのが若干面倒かもしれませんが。
括弧付けるくらい、そんなに手間ですかしらん?
って思ってるです正直。

こーゆー思想で作ってるので。
(最近、Slimにどっぷりハマって放置してますが)自前のフレームワーク、PHP5からPHP7に対応させるとき、ほぼ修正いらずでした(一桁行くらいだったかし、修正したの)。
逆にこの辺が雑なコードをPHP5からPHP7に移植させるとき、驚くほど手間がかかりました。

いやまぁ「いつどこにコストをかけるのか?」って話なんだろうとは思うのですが。
どうせなら「その言語にちょっとくらい不慣れな人」が読んでもすんなり読めるような、丁寧なコード書いてたほうが色々とメリットも多いんじゃ無かろうか? と思うんですが、どうなんですかねぇ?

駄目なUUIDv4実装

「実装によってはUUID4が重複しうる」って話を聞いて「じゃぁ駄目な実装を書いてみよう」と思いました(笑
珍しく「徹頭徹尾、非実用」です(笑

<?php
mt_srand(time());
printf("%08x-%04x-4%03x-%04x-%012x\n"
    , mt_rand(0, 0xffffffff)
    , mt_rand(0, 0xffff)
    , mt_rand(0, 0xfff)
    , mt_rand(0, 0x3fff) + 0x8000
    , mt_rand(0, 0xffffffffffff)
    );

これだと、同じ秒で(別マシンだろうがなんだろうが)同タイミングで作成すると、ちゃんと(?)重複します(笑
いやまぁ「普通に考えて、最低限 random_bytes() だろ」とか思うのですが、そこはほら、実験という名のお遊びなのでwww

なお

mt_srand(time());

がキモになりますので、絶対に省略しないでください。省略されると、ちゃんと(?)重複しません(笑

うんなんか書いたら満足したwww

魔力と魔法、魔術

世界には不思議な力が満ちていた。
先人はそれを「摩訶不思議な力」と呼称し、それが転じて「魔力」と呼称された。

「極度にとがった天賦の才」を持ったもののみが扱い得る魔力であったが、徐々にその法則の端々が判明していった。
「魔力を扱うための法則」、魔法である。

理論としての魔法を追うように、魔法を扱う術(すべ)についての試行錯誤と考察、実践もまたノウハウが蓄積されていった。
「魔法を扱う術(すべ)」、魔術である。

かくして。

あるものは魔法を研究して新たなる法則を発見し。
あるものは魔術を修練して極めて強大な術を行使するようになった。

蛋白質摂取量の計算

カロリー計算にはあんまり心惹かれないのと、糖質はまぁそこそこがっつり制限を入れているので。
そうすると気になるのが「蛋白質は十分な量を摂取しておきたいなぁ」ってあたり。

「十分な蛋白質量、とは?」ってのは

・体重ベース
・除脂肪体重ベース

があるんだけど、なんか昨今見ていると「除脂肪体重のほうがよりよい」っぽい雰囲気があったので、そっちベースで。
おいちゃんの除脂肪体重は58kgくらいなので、必要量を「除脂肪体重の2~3倍(g)」だとすると「116~174g」。

んじゃ次は、日々の蛋白質量の大雑把な計算。……割と食事にルーティーンっぽいものがあってよかった(笑

朝)
ソーセージ3本(1本20g換算):8.4g
全卵:12g

昼)
刺身一人前:25~37g
or
メンチカツ2個:20g

夜)
鶏か豚(100g):20g
豆腐(1/4丁): 5g
納豆: 7.4g

夜の納豆は「食ったり喰わなかったり」なのでぶれるんだけど、大体これで75~82gくらい。
他にも少しはなにか食べてるだろうけど、一端、誤差で(牛乳とか、誤差というには多い気がするがw)。

あとプロテイン(X-PLOSIONさんのを買ってます)が
・1食30g当たり: 26.1g
なので。

・運動しない日は大体OK(納豆は食ったほうがよいかも)
・運動した日は1食くらいプロテインをいただく / ごっつく頑張ったら2食でもよいかも

くらいが、蛋白質の摂取としては当面妥当な所かなぁ、と。
まぁこの辺をベースに、軽くコントロールしていってみましょう。

ちょっとした小技……の背景

典型的には「(第一種)ホワイトリスト*1」の実装でありがちなのですが。

declare(strict_types=1);

$white_list = [
    'hoge',
    'foo',
    'bar',
    'baz',
    'qux',
];
//
$input = 'bar';
//
if (true === in_array($input, $white_list, true)) {
    echo "{$input} is in \n";
} else {
    echo "{$input} is NOT in \n";
}

こんな風に書く事が多いと思うんですよね、多分。

ただ、おいちゃんはこんな風に書きます。

declare(strict_types=1);

$white_list = [
    'hoge' => 1,
    'foo' => 1,
    'bar' => 1,
    'baz' => 1,
    'qux' => 1,
];
//
$input = 'bar';
//
if (true === isset($white_list[$input])) {
    echo "{$input} is in \n";
} else {
    echo "{$input} is NOT in \n";
}

valueは別に1でも''(空文字)でもtrueでもなんでもよいのですが(nullだけは嫌)。
あと、issetじゃなくてarray_key_existsでも、と思うのですがなんでだかarray_key_existsの綴りを指が覚えてくれないので、「値がnullじゃない事が確定している」状態だとisset使う事が多いです。

先に、テストコード。

declare(strict_types=1);

$s = 'a';
$awk = [];
for($i = 0; $i < 100000; ++$i) {
    $awk[] = $s;
    $s ++;
}
$t = microtime(true);
$hash_awk = array_flip($awk);
$t_end = microtime(true);
echo 'array_flip is ' , $t_end - $t , "\n";

//
$needle = $awk[ count($awk) - 1 ];

//
$t = microtime(true);
in_array($needle, $awk, true);
$t_end = microtime(true);
echo "in_\tis " , $t_end - $t , "\n";

//
$t = microtime(true);
isset($hash_awk[$needle]);
$t_end = microtime(true);
printf("isset\tis %.28f\n", $t_end - $t);

//
$t = microtime(true);
array_key_exists($needle, $hash_awk);
$t_end = microtime(true);
printf("array_\tis %.28f\n", $t_end - $t);

何回かお試し。

[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0030989646911621
in_ is 0.00078010559082031
isset is 0.0000009536743164062500000000
array_ is 0.0000009536743164062500000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0043699741363525
in_ is 0.00089287757873535
isset is 0.0000011920928955078125000000
array_ is 0.0000009536743164062500000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0034210681915283
in_ is 0.00078892707824707
isset is 0.0000009536743164062500000000
array_ is 0.0000009536743164062500000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0035109519958496
in_ is 0.00085806846618652
isset is 0.0000009536743164062500000000
array_ is 0.0000000000000000000000000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0038630962371826
in_ is 0.0010230541229248
isset is 0.0000009536743164062500000000
array_ is 0.0000009536743164062500000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0031359195709229
in_ is 0.00078296661376953
isset is 0.0000009536743164062500000000
array_ is 0.0000011920928955078125000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0031070709228516
in_ is 0.00080204010009766
isset is 0.0000009536743164062500000000
array_ is 0.0000000000000000000000000000
[gallu@ip-256.257.258.259 php]$ php t.php
array_flip is 0.0037379264831543
in_ is 0.0010411739349365
isset is 0.0000009536743164062500000000
array_ is 0.0000009536743164062500000000

issetとarray_key_existsは、なんかもはや「誤差レベル」のような雰囲気が(笑
in_arrayとは露骨に数値が違う、ってのだけ覚えておいていただければ。

ここで書きたいのは「検索するんなら、in_arrayよりisset(かarray_key_exists)のほうがよりよいのではないかしらん?」というお話でふ。

端的には「O(n)かO(1)か」の違いなのですが……厳密には「O(1)かどうかはkeyのコリジョンの具合にもよるんだけど、大分と1に近い」くらい。
in_arrayは線形探索だと思われるので、基本的に「配列を頭から舐めていって見つかったらそこで終了」となります。だからまぁ、テストでは最悪の形である「一番最後の要素」にしたのですが。
issetとarray_key_existsは「hash検索」なので。 https://gallu.hatenadiary.jp/entries/2006/09/30 とか https://gallu.hatenadiary.jp/entry/20060930/p2 とか見ていただくと(多少)細かく書いてありますが、元々が「速やかに検索するための方法」という側面でのhashでもあるので、要素がn個あっても、比較的高速に検索をする事が出来るようになるです。

これが「どっかから配列を取ってきて検索」の場合、「array_flipのコスト」と「検索のコスト」とのせめぎ合いになるので微妙な所ではあるのですが。
(第一種)ホワイトリストとかの場合は大体「コードのどこか(定数とか)」にあらかじめ配列を書いている、と思われるので。
そーゆー時は、普通の配列をin_arrayするよりもhash配列をissetなりarray_key_existsなりするほうが、速度的にも早いし、「検索」という理屈からもより「適切」なんじゃないかなぁ、とか思うわけなんですね。

なんていう小技を、なにげにちょいちょいと説明するケースがあったので、どこかで文章に残せたらなぁ、と思ったので残しておきます。

*1:許可されたモノが列挙されたリスト