2026年5月8日金曜日

Chrome デベロッパーツールでのウィンドウサイズ表示

開発者ツールで

レスポンシブデザインや開発では、chrome そのもののウィンドウサイズを変更させて確認することが多いです。
その場合、デベロッパーツール(F12)を開いたときに右上に表示されるウィンドウサイズ、とっても重宝します!

トリガーがわからない!

ところが、このウィンドウサイズ、表示されるときと、されないときがあるんですよね。
しかも、表示してほしい時に限って表示されないんで、モヤッとしてしまいます笑

発見しました

ようやく、解決方法を見つけました!
長かった(´Д⊂グスン

デバイスのツールバーをね、2回押すといいよ!

デバイスツールバーを押すと、一度は小さいスマホサイズになるけど、もう一度押すと元に戻ります。

この状態で chrome のウィンドウ幅を変えると・・・

ほらね!

まとめ

と、いうことで、AIに聞いても教えてくれなかった裏技を発見したのでしたw
めでたしめでたし。

2026年5月7日木曜日

以前の Outlook を使いたい!

新しい Outlook

いや、いらないよね?
たまに起動してしまうとパスワード求められて来るのもびっくりするし。
マイクロソフトアカウントのパスワードかと思いきや、メールアカウントのパスワードだし。
せっかく作ったアドインが使えないし。
アドインを買ってくれてるユーザーも使えないし・・・

おかげで、弊社の Outlook アドインの売れ行きが冴えません。

以前の Outlook を使うには

従来の Outlook を使うには、新しい Outlook の「ヘルプ」メニューにある、「従来の Outlook に移動」をクリックします。


最近は、このメニューさえ出ないそうですよ!
その場合、Outlook をアップデートすると「従来の Outlook に移動」が出てくるそうです!

アイコンを変更しましょう

タスクバーとかメニューとかデスクトップのアイコンを使って Outlook を起動してると思いますが。
毎回、「従来の Outlook に移動」を選ぶのはうんざりしますよね
そこで、Outlook (classic) のアイコンと入れ替えましょう!

そのためには、実行ファイルの場所が必要になりますね。
ここです!
C:\Program Files\Microsoft Office\root\Office16

ここにある、OUTLOOK.EXE を右クリックして「タスクバーにピン留めする」を選ぶと、タスクバーに表示されます!

あとは、このショートカットアイコンをデスクトップなどの好きな場所に配置すればいいですね。

新しい Outlook のアイコンが不要な場合は、右クリックで消去しちゃいましょう!

既定のアプリに変更する

WEBサイトの mailto: のリンクなどでメールを送信したいとき、これまた新しい Outlook が表示されちゃいますね。
しつこいなーって思います(笑)
既定のアプリを変更しましょう。
Windowsの「設定」「アプリ」「既定のアプリ」です。


ここで、「ファイルの種類またはリンクの種類の規定値を設定する」下の検索ボックスに
MAILTO
と入力すると、現在設定されているメールソフトが表示されます。

メールソフトの部分をクリックすると、候補となるアプリの一覧が表示されますので、Outlook(クラシック)を選んで「規定値を変更する」ボタンを押します。

まとめ

という流れで、Outlook(classic)が使えるようになりました。
このまま従来の Outlook をこれからもずっと使い続けられるといいのですが・・・w

2025年7月31日木曜日

iOS で ajax が動かない

$.ajaxで undefined なエラー?

iOS 用のアプリ(WEBアプリ)で、ログイン後にデバイストークンを登録しようとして、以下のような構成にしてました
login.js - IDやパスワードを調べてログインするまでをクラス化したもの
device_toiken.js - デバイストークンをDBに登録するためのクラス
ここで、デバイストークンの登録が必要なのはデバイスがスマホアプリの時だけです。
サービスはスマホに PUSH 通知するけど、WEB PUSH は使わないんで。
なので、login.js と device_token.js は、独立してて相互通信をする必要はないのよね。

カスタムイベントを用意する

そこで、login.js はログインが成功したら、独自に作ったカスタムイベントを発行するんです。
こんな感じ。

    // ログイン完了イベントを発行する
    window.dispatchEvent(new CustomEvent(LOGIN_EVENT_NAME, {
        detail: {
            login_id: login_id,
            device_type: device_type
        }
    }));

受け取り側の device_token.js では、イベントを待機したらデバイストークンを取得してサーバに登録します。
こんな感じです。

    // ログイン完了イベントでデバイストークンを取得して登録。
    window.addEventListener(LOGIN_EVENT_NAME, async (event) => {
        const login_id = event.detail.login_id;
        const device_type = event.detail.device_type;
        await registerDevice(login_id, device_type);
    });
データベースへの登録処理は $.ajax()なり $.post()なりでサーバのAPIを呼び出すだけです。
で、Android アプリは正しく動作するのに、iOS アプリだとエラーの不明な例外で落ちます。
login.is では、イベント発効前に $.ajax で ID が正しいかとかパスワードが正しいかとかやってるのに。
iOS だとデバイストークンの保存APIだけが落ちるんですよね・・・
丸一日追いかけましたよ・・・

ようやく

という書き出しから想像つくと思うけど。
要するにね、カスタムイベントハンドラ内での $.ajax だから落ちるんだと分かった。

login.jsでdevice_token.jsのクラスを依存させて次のように書き換えました。

    if(this.IsMobile) {
        const tokener = new DeviceTokenClass();
        var device_token = await tokener.getDeviceToken();
        if(device_token != null) {
            var result = await tokener.registDeviceToken(login_id, device_type, device_token);
        }
    }

まとめ

せっかく2つのクラスを分離してたけど、それができなくて残念でしたが。
Androidは動くけど、iOS では動かない!
なぜじゃ!?
という事態になったら、こういった部分が引っかかってるかもです。
納期ギリギリまにあったので、よし!w

めでたしめでたし。

2025年7月30日水曜日

Android Studio で Emulator が動かない

エミュレータが動作しない

開発PCが壊れたので新しく Windows11 Pro の環境でプロジェクト再構築。
Android Studio を使ってアプリ開発しようとしたら、エミュレータが動かない。
Pixel 9 terminated.とかいうエラーダイアログが出て動作しません。

Android Studio は新しいバージョンになってるんだが・・・

Windows のユーザー名

新しいPCはマイクロソフトアカウントでユーザー名が日本語なんですよ。
どうやら、こいつが原因のようです。

ところが。Windows11のユーザー名は変更できない!
(できるのかもしれないけど、無理だった)

Android のディレクトリを変更する

・環境変数 ANDROID_SDK_HOME を設定
 コントロールパネル「システム」「システムの詳細設定」「環境変数」を開いて新しい環境変数を作成します。
D:\Programs\Android\.android を作ってそこを指定してみました。
・ユーザープロファイルフォルダの .android を丸ごとコピーします。
ユーザプロファイルは C:\ユーザー\ユーザー名 のフォルダね。
・念のため、ユーザープロファイルの .android フォルダの名前を .android_bak にしました。
・Android Studio を起動。
・エミュレータ起動。

まとめ


無事、エミュレータが動作しました。
Android Studioの関係者が見てたら、修正してほしいですねw

めでたしめでたし。

2025年4月11日金曜日

WindowsUpdateでフォントがおかしくなった!

Windows10 Update

使ってるPCはWindows11にアップデートできない機種なので Windows 10 を使い続けてます。
昨夜、「更新してシャットダウン」を選んで朝まで放置してたら、例によってPCは起動状態でした。
まあ、いつものことだから、イラつきもしませんが(笑)

エクスプローラの表示がおかしい

さて、今日も作業を・・・とみるとエクスプローラの表示がおかしい。
おいおい、なんだよこりゃ?
システムフォントが変わったのかな?

フォントを変更する

たしか、Windows はフォントの大きさを変えられるけどフォント自体を変更することはできなかった気がする。
そこで、これ!
「Meiryo UIも大っきらい!!」
ダウンロードして展開したら実行ファイルをクリック。
フォントを指定して、「一括設定して終了」これでOK
文字化けさえしなければなんでもいいので、「Meiryo UI」を指定しました。(笑)

まとめ

と、いうことで、昨日までとちょっと違うけど、文字化けを対策できました。
有用なソフトウェアを公開してくれている Tatsu さんに感謝です!
ありがとうございます!

2024年12月29日日曜日

VisualStudio Installer プロジェクトでコードサイン証明書を適用する

pfx形式が使えなくなった

製品のインストーラ(exe形式ファイル)を作成するために、これまで頑なに Install Shield 2015 の無料版を使用していましたが。
コードサイン証明書が変更になってしまい、pfx形式だとうまくビルドできなくなってしまいました。
そこで、VisualStudio 2022 の Installer プロジェクトを新たに作成することにしました。

ビルドしたインストーラファイル(msi形式ファイル)にコードサイン証明書を適用する必要があるのですが、その手順を自動化したので紹介します。

USBドングルでの証明書

これまでは、コードサイン証明書は .csr 形式のファイルで提供されていて、そいつを元に .pfx 形式ファイルを作成していました。
インストーラプロジェクトでは、sign タブの部分で pfx ファイルとパスワードを設定さえすればビルドできてたんですよね・・・
Visual Studio 2015の Install Shield では、ストアに登録した新しいコードサイン証明書を指定しても、エラーになってビルドできませんでした。

Installer Project を作成する

VisualStudio 2022 の Installer プロジェクトを作ります。
プロジェクトのプロパティで必要事項を設定するのですが、設定項目が Install Shield とほぼ同じのため、さほど混乱はしませんでした。
重要場部分としては、次のような点でしょうか。

  1. ProductCode はバージョン番号を変えたら必ず新しいものに変更する。
  2. UpgradeCode は変更してはならない。(そうしないとインストール時に以前のバージョンをアンインストールしてくれなくなります)
  3. ProductName 部分はインストール先のフォルダ名に利用される点に注意
  4. Version は##.##.####形式でなければならない
これまでバージョン番号には ##.##.##.## の形式だったのが使えなくなりました。
後述のアンインストールしてくれない問題は、ここが原因なのかもしれません。

signtool.exe を使ってコードサイン証明書を適用

無事インストーラが出来上がったら、コードサイン証明書を適用します。
signtool.exe の GUI で使用するのですが、入力項目が多く、とっても面倒でした。
ということで、インストーラプロジェクトの PostBuildEvent に次の行を追加して自動化しました。

signtool sign /a /n "証明書のトークン名" /t "タイムスタンプサーバのURL" /d "製品記述" /du "製品のURL" $(BuiltOuputPath)

途中でトークンパスワードを入力する手間が発生するけど。GUIでごにょごにょ入力するよりは、はるかにマシになりました。

以前のバージョンをアンインストールしてくれません。

UpgradeCode は正しく設定しているにもかかわらず、インストーラが以前のバージョンを事前にアンインストールしてくれなくなりました。
いろいろ試したり調べたりしたけど、どうしてもだめでした・・・。
バージョンの表現形式が変わってしまったからなのかもしれません・・・
あるいは、exe形式から msi形式に変わったからなのか?

もし情報をお持ちの方いらっしゃいましたら、教えてくださいませ。

まとめ

ついに Install Shield を脱却しましたw
めでたしめでたし。

2024年11月17日日曜日

スタイルシートに指定している色で表示されない

Color picker で異なる色が表示される

WEBページの設計では、色にこだわるケースが多いですね。
顧客から指定された色でデザインをしていたんですが、おかしな現象がでました。
スタイルシートに指定している色で、表示されないのです。

コードでは次のように指定しています。

--color-main-bg: rgb(3, 180, 198);
.top-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    max-width: 100%;
    padding: 1rem;
    margin: 0 auto;
    background-color: var(--color-main-bg);
}

Chrome color picker で別の色が表示される

Chrome で表示させて、開発者ツールを開くと、図のようにちゃんとコーディングした内容が反映されています。

ところが、Chromeの拡張機能の Color Picker で表示されている部分を調べると

おいおい、どーして色が違うんだよ・・・
おれさまのコードのどこに問題があるって言うんだよ~・・・
使ってる bootstrap とか normalize とか milligram なんかが悪さしてるのかな~・・・
と、必死にデバッグするも、問題点が見つからない・・・・

マルチディスプレイ

ディスプレイを2つ並べて開発してるんですが、表示してるページをもう一方のディスプレイにスライドすると・・・
あら不思議。ちゃんと指定された色で表示されちゃいます。

いったい、どういうことヨ?
どうやら、ディスプレイがおかしいのだということで、調べてみたよ。

画面の色調整

コントロールパネルに「色の管理」というのがありまして。
「詳細設定」-「ディスプレイの調整」というボタンがありました。
ぽちっ!

なんだかわからないけど、とりあえず、「次へ」ボタンで進めていきます

まとめ

するってえと、見た目も Color Picker でもちゃんと表示されるようになりましたよ!

いやあ、てっきり自分のプログラムが悪いんだろうと、とっても長い時間悩みましたよ
ほんと、こーゆーの勘弁してほしいですわ。
ま、なおってくれたので良しとしましょう。
めでたしめでたし。

c.f.
https://support.hp.com/jp-ja/document/c04249810

SQLiteを使ったプログラムで Out of memory 例外が発生する

メモリいっぱいあるのに、Out of memory

C# で開発したファイル処理プログラム。
SQLite を使ってインデックスを貼り高速検索するようにしてます。
SQLite の便利な機能に、データベースをメモリ内で処理させるってのがあります。

   SqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = ":memory:" };
   SqlConnection = new SQLiteConnection(SqlConnectionSb.ToString());
  
こうすることで、オンメモリ処理になり、さくさく動くようになります。
DataSource をハードディスク上のファイルに置き換えることもできますが、それだと遅くて使い物にならないような機能のプログラムなんです。
このプログラムにちょっとばかり大きなファイルを処理させると、途中で Out of memory 例外でエラーになって落ちてしまう問題が出ました。
どーして?
タスクマネージャで見ててもメモリの空き容量は十分にあるのに。
そんな、ばなな。

キャッシュを大きくしてみたり

SQLite out of memory で検索しても、どういうわけかなにもヒットするページがありません。
しかたなく接続時のパラメータを変更してみたり。

SqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = ":memory:", CacheSize = 10000 };
PageSize とか MaxPageCount といったパラメータも変更してみたけど、効果なし・・・困りました。

32ビットを選ぶ?

Visual Studio のプロジェクトは「AnyCPU」としていて、32bitでも64bitでも動作するようにしてるつもりだったけど。
プロジェクトプロパティ「ビルド」の項目に、「✅32ビットを選ぶ」ってのがありました。

なんじゃ、こりゃあ?ってなくらい、知りませんでしたよ。(笑)
このオプションのせいで、AnyCPU が 32bit プロセスとしてビルドされてしまうわけです。
これまでリリースしてたプロダクト、全部再確認が必要になりましたよw

上記チェックボックスをOFFにして、64bitOSで動作させたら、Out of memory例外は出なくなりました。
あ、プロジェクトプロパティは Debug と Release の両方の構成を変えなきゃならないから、注意してくださいまし。

今回の問題は、問題を再現するのにもトライアンドエラーするのにも1時間以上かかるので、大変でした。

ま、解決できてよかった。
めでたしめでたし。

2024年11月10日日曜日

bootstrap(v5) でブレークポイントが正しく表示されない


スマホサイズで改行されてしまう!

bootstrapでデザイン中に、スマホサイズでrow の col が12以内なのに改行されてしまう問題に遭遇しました。


<div class="container-fluid">
    <div class="row">
        <div class="col-6 col-sm-4 col-lg-2">
          ll
        </div>
        <div class="d-none d-sm-block col-sm-4 col-lg-4">
          lr
        </div>
        <div class="d-none d-lg-block col-lg-4">
          rl
        </div>
        <div class="col-6 col-sm-4 col-lg-2">
          rr
        </div>
    </div>
</div>

これ実行すると、スマホサイズの時、ll と rr 部分が改行されて出力されてしまいます。
なぜじゃあ?

解決方法

row の部分を次のように変更することで、無事行内に収まるようになりました。


<div class="container-fluid">
    <div class="d-inline-flex w-100 justify-content-between">
        <div class="col-6 col-sm-4 col-lg-2">
          ll
        </div>
        <div class="d-none d-sm-block col-sm-4 col-lg-4">
          lr
        </div>
        <div class="d-none d-lg-block col-lg-4">
          rl
        </div>
        <div class="col-6 col-sm-4 col-lg-2">
          rr
        </div>
    </div>
</div>

まとめ

けっこう格闘してしまった
動いたから、よし!
めでたしめでたし。

2024年10月28日月曜日

deprecated: str_replace(): passing null to parameter #2 ($replace) of type array|string is deprecated

大量の str_replace のエラー

CentOS もサポート終了してしまったので、数ある Linux プロジェクトの多くを Ubuntu に変更してます。
当然、CakePHP3 のような古いバージョンで構築されているプロジェクトも移植の対象になります。
とあるプロジェクトを Virtual Machine 上に構築した Ubuntu 22.04 LTE 上で動作させようとして、最初に CakePHP home を表示したら、こんなエラーがたくさん出てきまして。

PHP8.1 あたりで仕様が変わったことによる問題なんですけどね。
CakePHP のソースも変更しなきゃならないの?とビビってしまいました。

動作環境

OS:Ubuntu 22.04.01 LTE
MySQL: MariaDB 15.xxx
PHP 7.4.33
phpMyAdmin: 5.2.1
CakePHP 3.10

ということで。
CakePHP3 を動作させるための環境なので、PHP 7.4 で動かそうとしてるんだけど、Cake の homeページを開こうとするときに、PHP 8.x が動いちゃってる、という状況なんですね。

PHP の動作バージョンを変更する

この方法は、あちこちに書いてありますが、alternatives で定義しておき、バージョンを変更します。
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.3 100
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.4 110
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.0 120

sudo update-alternatives --config php
There are 3 choices for the alternative php (providing /usr/bin/php).

Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/php8.1 130 auto mode
* 1 /usr/bin/php7.4 110 manual mode
2 /usr/bin/php8.1 130 manual mode
3 /usr/bin/php8.2 82 manual mode

Press to keep the current choice[*], or type selection number:
ここで、対象となる PHP をセットしておけばいいわけです。

apache2 の mod を変更する

ちゃんとPHPを7.4に変更したのに、ブラウザで表示させたときのエラーは消えません・・・PHP8 で動いてしまいます
原因は apache2 でした。
# ll mods-enabled/php*
lrwxrwxrwx 1 root root 29 Oct 28 11:06 mods-enabled/php8.1.conf -> ../mods-available/php8.1.conf
lrwxrwxrwx 1 root root 29 Oct 28 11:06 mods-enabled/php8.1.load -> ../mods-available/php8.1.load

# a2dismod php8.1
# a2enmod php7.4
# service apache2 restart

home を開いてみると、無事エラーが消えているのを確認できます。

まとめ

「環境構築」って、なんか、しょっちゅうやってる気がします。
え?コンテナを使えって?w知ってるw

ま、こういった悩みを持ってしまう人も、少なからずいるだろうから、書き留めておきますよっと。
c.f.
https://qiita.com/murakami77/items/a9945f2a8e51ca3791de

2024年6月14日金曜日

Hyper-Vで終了できなくなったOSを削除する。

仮想マシン上のOSが落ちてしまった

Hyper-Vで作成した仮想マシン、何らかの問題で固まってしまうことがあります
OSは動きっぱなしなのでメモリとかリソースを使ったまま。
動作中の仮想マシンは Hyper-V に削除メニューがありません。
そうなってしまった場合の対処方法についてまとめます。

OSをインストールしたら固まってしまった

今回は、CentOS 6.5 という古いバージョンのしかも32bit版の環境を作る、という目的でした
インストールの手順は省くとして。
最終的に起動後は、こんな状態になってしまい、「停止」とか「シャットダウン」も機能しなくなってしまいました!

Hyper-V では「実行中」と表示されていてメモリを消費しています。
「削除」メニューもありません・・・
このまま放置するとメモリの無駄遣いですね・・・

エクスプローラで、Hyper-V の仮想マシン用フォルダを削除しようとしても、「使用中」で削除できません。

そんなときの対処方法

Hyper-V を停止して、その間にフォルダを削除してから Hyper-V を再開すればいいってことです。

Windows の「サービス」を起動して、「Hyper-V Virtual Machine Management」を見つけましょう

「スタートアップの種類」を「手動」に変更して「適用」を押します。
「停止」ボタンを押してサービスを停止します。
必要ないのかもしれませんが、なんとなく、この時点で Windows を再起動させています。

Windows を再起動させたら、まず、不要な仮想マシンフォルダをエクスプローラで削除します。

削除できました!

サービスを起動して、「Hyper-V Virtual Machine Management」を「自動」にして「開始」します。

Hyper-V を起動してみると、無駄に動作していたOSがなくなっていることがわかります。

まとめ

これ、よくあるんですよねー。
同じように困ってしまったら、上記方法を(自己責任の範囲でw)お試しください。
めでたしめでたし。

2024年5月5日日曜日

PHP の日本語ファイル名処理で文字化け

電子情報保存法に対応

請求書をサーバに保存して電子情報保存法に対応しましょ、という仕組み作りがあちこちで行われているかと思います。
過去の経験から、サーバー上に文書ファイルを保存しようとする場合、日本語のファイル名では保存しない方がいいと思いますよ。
たとえば、濁点、半濁点付きのファイル名「ぱぴぷぺぽ.pdf」ファイルをそのままサーバに保存しておいて、ブラウザでダウンロードできるようにしようとすると
Windows クライアントでは正しく表示できるけど、MacOS では正しく処理できない、といった問題が発生してしまいます。

そこで、サーバに保存するときには、ファイル名を半角英数字のみにして保存するようにしてみました。
ファイル名を拡張子と分離するには、PHP の pathinfo() 関数を使います。
半角英数ファイル名の構造には、BASE64 エンコードと使えない文字を置き換える base64UrlEncode() 関数を使って処理します。

BASE64を使ったエンコード処理

function base64UrlEncode($data) 
{ 
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 

ファイル名の拡張子以外の部分を base64UrlEncode で構築する処理を用意してみました。
入力フィールドで拡張子を指定しなかった場合は、.pdf ファイルだという処理も入れてみています。

function buildFileName($filename, $def_ext = 'pdf')
{
    $file_parts = pathinfo($filename);
    $filenode = $file_parts['filename'];
    $ext = $file_parts['extension'];
    if(strlen($ext) == 0)
    {
        $ext = $def_ext;
    }
    $name = $this->AsCommon->base64UrlEncode($filenode) . '.' . $ext;
    return $name;
}

日本語ファイル名が正しく処理されない

$filename = uildFileName("ぱぴぷぺぽ.pdf");
を実行すると、".pdf" という文字列が返ってきてしまいました・・・
またもや日本語処理に別の対応が必要になってしまいます・・・こまったもんだ・・・
調べると、ロケールの設定に依存しているため、というのがわかりまして。
setlocale(LC_ALL, 'ja_JP.UTF-8');
を実行してやると、上手くいくようになりました。

cakePHP での対応

pathinfo() やそのたぐいの関数を使うソースプログラムに、毎回 setlocale を記述するのは無駄を感じますね。
ましてや、プログラムを国際化対応しようとすると、あちこち変更しなければならなくなってしまいます。

cakePHP の config/app.php を見ると、次の記述があります。

'App' => [
    'encoding' => env('APP_ENCODING', 'UTF-8'),
    'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja_JP'),

これを利用して、config/bootstrap.php の 112 行目あたりに以下を追加しました。

setlocale(LC_ALL, Configure::read('App.defaultLocale') . '.' . Configure::read('App.encoding'));

まとめ

毎度のことながら、日本語対応は問題が多く発生しやすいですね。
国際化対応時に、上記対策でうまくいくのかどうかまでは試しておりません。あしからず。
今回も苦しめられましたが、なんとか事なきを得ました。

めでたしめでたし。

参考になったサイト
https://qiita.com/REAS07/items/3f86a0834d612edaecd6

2024年4月18日木曜日

cakePHP3でメールの受信

XSERVER でも使えるように

cakePHP3を使ったプロジェクトでメールを受信して添付ファイルを保存しようとしましたら。
まず、POP3用のライブラリをインストールしなきゃいけないことがわかりました。
で、VM上の Linux にインストールしてみました。

# pear channel-update pear.php.net
/usr/share/pear/Net にPOP3.php, Socket.php がインストールされました。
# pear install Mail_mimeDecode
/usr/share/pear/Mail にインストールされました。

でも、本番環境の XSERVER では root 権限でインストールなんてできないよね。
と、いうことで。 /usr/share/pear/のファイルを CAKEPHP_DIR /appendix/pear に無理やりコピーして使うことにしました。

require が動かない

 require('Net/POP3.php');
require('Mail/mimeDecode.php');
としなきゃいけないのに、パスが効いてないから読み込めない。
PHP で get_include_path() を呼び出すと、次のようなインクルードパスが設定されていました。
".:/usr/share/pear:/usr/share/php"
そこで、
set_include_path(get_include_path() . PATH_SEPARATOR . CAKEPHP_DIR . '/appendix/pear/');
を呼び出すことで require がうまくいってくれました。

ポート番号995(POP3S)での受信設定

アカウント情報は、とりあえず MailServers データベースにでも置いといて、次のように取り込むようにしました。

  $account = $this->MailServers->find()
    ->select(['pop3_server', 'pop3_port', 'pop3_account', 'pop3_psw'])
    ->first();
実際に POP3サーバに接続してログインする部分のコードは、こんな感じ
  $pop3 = new Net_POP3();
  $pop3->connect($account->pop3_server, $account->pop3_port);
  $pop3->login($account->pop3_account, $account->pop3_psw);
  $message_count = $pop3->numMsg();
$account->pop3_port を 995 にすると、接続ができずに悩みました。
pop3_server にプロトコルヘッダ ssl:// を付けてあげることで接続できました(^^)v

メール受信処理

実際には、message-id をDBに保存しておいて、すでに処理済みのメールかどうかをチェックしたりするのですが
メールの取り込みは次のような感じです

    for($mail_no = 1; $mail_no <= $message_count; $mail_no++)
    {
        $msg = $pop3->getMsg($mail_no);
        $decoder = new Mail_mimeDecode($msg);
        $mime = $decoder->decode([
            'include_bodies' => true,
            'decode_bodies' => true,
            'decode_headers' => true,
        ]);
        $messageid = $mime->headers['message-id'];
        $subject = $mime->headers['subject'];
        $sender = $mime->headers['from'];
        $date = $mime->headers['date'];
        // メール解析
        [$body, $attachments] = $this->analyze($mime);
        // 必要な処理
    }

今回は本文と添付ファイル情報を必要としたので、メールの mime 解析部分は、こんな感じです。

function analyze($mime)
{
    $body = "";
    $attachments = [];

    if(!isset($mime->parts))
    {
        // シングルパート(テキストのみ)
        $body = trim(mb_convert_encoding( $mime->body, "UTF-8", 'ASCII, JIS, UTF-8, SJIS' ));
    }
    else
    {
        // マルチパート
        foreach($mime->parts as $part)
        {
            if((strtolower($part->ctype_primary) == 'text') && (strtolower($part->ctype_secondary) == 'plain'))
            {
                $body .= trim(mb_convert_encoding( $part->body, "UTF-8", 'ASCII, JIS, UTF-8, SJIS' )) . "\n";
            }
            else if((strtolower($part->ctype_primary) == 'application')) 
            {
                $filename = $part->ctype_parameters['name'];
                if(empty($filename))
                {
                    $filename - $part->d_parameters['filename'];
                }
                if(0 < strlen($filename))
                {
                    if(isset($part->body))
                    {
                        $attachment = [];
                        $attachment['filename'] = $filename;
                        $attachment['body'] = $part->body;
                        $attachments[] = $attachment;
                    }
                }
            }
            else if(strtolower($part->ctype_primary) == 'multipart')
            {
                foreach($part->parts as $part2)
                {
                    if(strtolower($part2->ctype_primary) == "text") 
                    {
                        $charset = $part2->ctype_parameters['charset'];
                        $body = mb_convert_encoding($part2->body, 'UTF-8', $charset);
                        break;
                    }
                }
            }
        }
    }  
    return [$body, $attachments];
}

pear の修正

いろいろエラーが出たので、pear 側のソースも変更しました。

■Net/POP3.php 変更点
/* 第3パラメータが非推奨になっていたので削除
define('NET_POP3_STATE_DISCONNECTED',  1, true);
define('NET_POP3_STATE_AUTHORISATION', 2, true);
define('NET_POP3_STATE_TRANSACTION',   4, true);
*/
define('NET_POP3_STATE_DISCONNECTED',  1);
define('NET_POP3_STATE_AUTHORISATION', 2);
define('NET_POP3_STATE_TRANSACTION',   4);

// クラス名と同名のコンストラクタが非推奨なので変更
// function Net_POP3()
function __construct()

■Mail/mimeDecode.php 変更点
// ISO-2022-JPのメールヘッダを正しく解析してくれない。
function _decodeHeader($input, $default_charset=false)
{
    if (!$this->_decode_headers) {
        return $input;
    }
    // iconv_mime_decode を使うように変更。
    $input = iconv_mime_decode($input, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
    // Remove white space between encoded-words 以下を削除。
    return $input;
}

// はだかのHTMLテキストが渡されてエラーでまくりなので変更
function _quotedPrintableDecode($input)
{
    // Remove soft line breaks
    $input = preg_replace("/=\r?\n/", '', $input);
    $input = quoted_printable_decode($input);
    // Replace encoded characters 以下を削除
    return $input;
}

まとめ

XSERVERにインストールできないとなると、AWS EC2 あたりにサーバー移動しなきゃならないかな?と悩んでいたので、受信できるようになって助かりました。

めでたしめでたし。

2024年3月11日月曜日

Excelから変換したPDFが携帯電話で表示されない

管理してるWEBサイトに Excel で作成されたファイルを表示するために、PDFに変換してアップします。よね?
うちもそうしてます。
日本語のファイル名にならないように英数名のファイルにしてアップロード
よし。これで完了、っと。

携帯(iPhone)で見えないとのご連絡!

いや、いつもやってることなのに。
どれどれ、と自分の iPhone で開いてみると・・・

 ほんとだ!
左上1/4くらいしか表示されません!
で、しばらくすると全体が表示されます・・・・
いや、これじゃ、あかんでしょ・・・

PDF に変換する!

Excel でPDFファイルとして保存するには、2つの方法があります。

ひとつは、「ファイル」メニューから「Adobe PDF として保存」を選ぶ方法です。
今回は、こちらの機能を使ってPDFに変換しました。

PCではちゃんと表示されるのにな・・・

別の方法を試してみる

もう一つ。
「ファイル」「名前を付けて保存」で、ファイル名の下のコンボボックスで「PDF(*.pdf)」を選ぶ方法です。

今回のファイルの場合、こちらを使うと、PDFのファイルサイズが少し小さくなりました。

まとめ

2番目の方法で出力したファイルをWEBサイトに公開したところ、iPhone でもサクッと表示されるようになりました。
同じ悩みを経験した場合は試してみてくださいまし。

めでたしめでたし。

2024年3月10日日曜日

WEBアプリ[Enter]キーでフォーカス移動の問題点

HTMLの[Enter]でフォーカス移動

むかしはねぇ。業務系アプリのほとんどで、入力枠で[Enter]押されたら、次の入力枠にフォーカスを移すのって、当たり前でしたよね。
ところがどっこい。HTMLでの[Enter]は submit() がデフォルトになってる。
業務系WEBアプリとしては、[Enter]キーでフォーカス移動は、ユーザーからのご要望も強くありますね。
と、いうことで。
[Enter]キーでのsubmit()をフォーカス移動にしてたのが、次のコードです。

$(function(){
  $("input").on("keydown", function(e) {
    if ((e.which && e.which !== 13) && (e.keyCode && e.keyCode !== 13)) 
    {
      return true;
    }
    else
    {
      var count = $('input').length;
      var current_index = $('input').index(this);
      for(let index = current_index; index < count; index++)
      {
        var next_input = $('input')[index + 1];
        var is_hidden = $(next_input).is(':hidden');
        var is_readonly = $(next_input).prop('readonly');
        var is_button = $(next_input).is(':button');
        if(is_hidden || is_readonly || is_button)
        {
          continue;
        }
        $(next_input).focus();
        return false;
      }
      $('input')[current_index].blur(); 
      return false;
    }
  });
}(this));
textarea に移動しない!と思った人は変更してくださいw

MacOSの[かな]キーでフォーカス移動してしまう!

Mac 使いのお客様から、こんなクレームが来ました!
フォーカスが移動する、ってのなら上記コードが原因のわけです。
と、いうことで。
MacOS 機を入手して動きを調べてみました。

「かな」キーの keyCode が 13 !!!

なんでこんなことしてんですかねーw
数字(と記号の)郵便番号入力から、住所欄の入力に移動して「かな」キーを押すと、住所欄すっ飛ばして「名前」のところにジャンプしてしまうわけですw
『使えねぇ』と思われても仕方ありません。ええ。

keydown を keypress に

  $("input").on("keydown", function(e) {
この部分を

  $("input").on("keypress", function(e) {
に変更することで、対応できました。

まとめ

ちなみに、「かな」キーのkeydownでのkeyCode は 13 でしたが、 keypress での keyCode は 229 が入ってきます。

HTMLって日本語のことちっとも考えてくれてないよね。
IE にあった、IME の制御機能、入れてほしいよね・・・

とりあえず動いた。
めでたしめでたし。


参照
Enterキーを無効にする方法
日本語入力時のキーイベントの仕様変更と対策

2024年2月8日木曜日

CakePHP でアソシエーションを含めたレコードの読込み

containを使え

あちこちのサイトを見ると、contain を使った方法がたくさん書いてありますね。
たとえば、products テーブルに取引先のIDである partner_id が含まれているとき
$product_id で示されるレコードを取得するには、次のように書きます。

  // コントローラの initialize() で
  $this->loadModel('Products');
  // レコードの取り込み処理で
  $record = $this->Products->get($product_id, ['contain' => ['Partners']]);

cakePHP を書きなれている人なら、同じみでしょう。
QueryBuilder を使った find() などでもアソシエーションとともに読み込みできますね。

  $record = $this->Products->find()
    contain(['Partners'])
    ->first();

どんだけ書くねん!

『こう書いておけば動く』から、なんでしょうか・・・
たぶん、世界中の人が、さまざまなプロダクトのテーブル参照を『とっても便利な』QueryBuilder を使って読み込んでいるのでしょうね。

おおきなプロダクトになってくると、それぞれのテーブルごとにレコード参照のコントローラ.phpファイルが増えて、手に負えなくなってしまいますねぇ

簡単にしちゃいましょう

レコードが _id で示されるインデックス指定のフィールドを持っているとき、contain でアソシエーションを『含めずに』読み込む、なんてことは逆に少ないはずです。
少なくとも、私の担当するプロダクトではレコード読込でアソシエーション不要、なんてことは皆無に近いですね。
そこで、こんなコードを共通コンポーネントに書き加えました。

/**
 * 指定テーブルのアソシエーション(BelongsTo/BelongsToMany)を含めて
 * レコードを取得する
 */
function LoadRecordWithBelongs($table, $id)
{
  $record = false;
  $contains = [];
  $associations = $table->associations();
  $items = $associations->getByType(['BelongsTo', 'BelongsToMany']);
  foreach($items as $item)
  {
    $name = $item->getName();
    $contains[] = $name;
  }
  $record = $table->get($id, ['contain' => $contains]);
  return $record;
}
ようするに、belongsTo, belongsToMany のアソシエーション定義されているテーブルなら、そいつをまとめて読み込んでくれよ、というコードです。

まとめ

共通化することで、たくさんのソースを削除することができるようになりますが。
それは、これからやり始めようとしてるところです・・・w

めでたしめでたし。

2024年2月3日土曜日

Visual Studio Code でCentOS7のリモートデバッグができなくなった!

突然使えなくなった VS Code + Remote SSH

昨日まで、普通に使えていた VS Code と Hyper-V 上の CentOS 7.9 上でのリモート開発
今朝、突然、使えなくなりましたよ。
どうやってもつながらない!
今日は土曜日だから、月曜あたりは日本中でこの問題、世界中で騒がれるんじゃないでしょうかね・・・
ったく・・・

パスワード入力してログインしようとすると、エラーになって繋がりません。

glibcとlibstdc++のバージョンが古い?

OSの中身を見てみると、確かに古いようです。
で、それならバージョンアップしてやろうということで、やってみました。
バージョンアップでやってみたことは、次の通り。
・gcc のバージョンアップ 13.2.0 をインストール。2度失敗。長かった・・・
・ここで、libstdc++を入れ替えできました。
・次に glibc のバージョンをあげる件ですが、結論から言いますと失敗しました。
・python 3 のインストール
・yum が動かなくなるので yum 編集
・gmake が古いと怒られます。で、4.2あたりをインストールしようとすると、エラーで止まっちゃう!
と、いうことで、CentOS7 側での対応はできませんでした。
(6時間・・・返してくださいよ・・・(´;ω;`))

解決方法

要するに、Visual Studio Code のアップデートが原因なんですよ
January 2024 (version 1.86)
拡張機能の Remote SSH がアップデートされてました。
で、このアップデートを古いバージョンにして、CentOS 側の /home/ユーザー ディレクトリ上の .vscode-server ディレクトリを削除。
・・・問題は変わりませんでした。
納期すぎていて、とっても焦っているのに、丸一日潰れかかってます・・・どーしてくれるんだ!

対応策

VS Code のバージョンをダウングレードしてしまいます!
まず、現在の VS Code をアンインストールする前に、次を実行しておきます。
・VS Code の自動アップデートを停止しておく。(設定:update あたり)
・拡張機能の自動アップデートを停止しておき。
VS Code をアンインストール。
このページの Downloads ってとこから該当バージョンをダウンロード
インストールしましょう!
CentOS 側の /home/ユーザー ディレクトリ上の .vscode-server ディレクトリを削除もわすれずに。

動いた!

昨日まで使っていたワークスペースを開いてみると、無事パスワード入力後に編集できるようになりました。
めでたしめでたし。

2024年1月28日日曜日

Hyper-V に Ubuntu 22.04.03 をインストールしようとして・・・

なんども失敗したので、記録しとく。

いつものとおり、Ubuntuサイトから .iso ファイルをダウンロードして
いろいろと失敗したので。

cloud-init で停止してしまう

上段に[Install Complete!]がでたんで[Reboot]を選択したら、真っ黒画面になってしまって、一晩放置してもNGだった。
再度、インストールを試みてみると、ログで reached cloud-init のところで止まったまま。(これも一晩放置したけどダメ)
cloud-init を無効にする方法はネット上にあるけど、そもそもログインする前に死ぬので、どーしようもない
※このVM、Hyper-Vでは起動中のままになってしまって、削除することもできなかったよ。
Hyper-Vサービスを停止⇒PC再起動⇒VMファイルを削除⇒Hyper-Vサービス起動で削除できました。

そこで。ネットワークにつながない状態でインストールすればいいんだ!ということに気づいたわけです。 Hyper-V のネットワークアダプタを接続せずに新しい Ubuntu をインストールすることで、ようやくログイン画面にたどり着きました!

インストール後の注意点

Ubuntu の説明サイトを見ると、sudo コマンド経由の説明ばっかりで、めんどくさいですよね・・・
あちきは、もっぱら $ sudo su - を実行して root 権限に移動してから処理してます。

まだネットワークアダプタがない状態で、次をやっておきます。
cloud-init を無効化

  # touch /etc/cloud/cloud-init.disabled
  
これでネットワークつないで起動しても cloud-init で止まることはない(はず)

ついでに、起動高速化のため、あちこちに書いてある grub timeout を変更しておきます。

  # sudo gedit /etc/default/grub
  # GRUB_TIMEOUT=2
  # sudo update-grub
  

ネットワークを設定します。
# ip link でネットワークアダプタ名を取得します (ここでは、eth0)
で、ネットワーク設定の yaml ファイルを編集します。(IPアドレスは、ご自分の環境に合わせてくださいまし)

  # mv /etc/netplan/00-installer-config.yaml  /etc/netplan/00-installer-config.yaml.disable
  # vi /etc/netplan/01-installer-config.yaml
  network:
    version: 2
    renderer: networkd
    ethernets:
      eth0:
        dhcp4: false
        addresses: [192.168.0.90/24]
        routes:
          - to: default
            via: 192.168.0.1
        nameservers:
          addresses: [192.168.0.1]
  

ここで一度シャットダウン。Hyper-V の設定でネットワークアダプタを接続して起動します!
・・・真っ黒画面になってしまうかもしれません(実際、大汗でしたw
2分ほど待つと、boot シーケンスが動作し始めますので、我慢してください(笑)
ネットワークに繋がれば、TeraTerm でSSHログインできます。

真っ黒画面対策として、パッケージ関係のアップデートを行います。

  # apt update
  # apt dist-upgrade
  # apt autoremove
  

再起動してみましょう!

  # reboot
  
さくっと起動するようになりました。

blk_update_request: I/O error

Hyper-V コンソールを表示させると、しょっちゅう blk_update_request: I/O error が出力されます。
これは、フロッピーディスクがないってエラーのようです。 よそのサイトを参考に、以下の方法でエラーをなくすことができました。

  ▼ blacklist に登録
  # echo "blacklist floppy" >> /lib/modprobe.d/dist-blacklist.conf
  ▼ カーネルから floppy を削除
  # rmmod floppy
  ▼ dracut がなかったのでインストール
  # apt install dracut-core
  ▼initramfs の再構築をする
  # cd /boot/
  # dracut -f -v
  ▼再起動
  # reboot
  


次からは、失敗しないぞ!w
めでたしめでたし。

参考にしたサイト
https://x.momo86.net/article/154
https://qiita.com/n_mikuni/items/bf94289eaff93b82ac27

2024年1月27日土曜日

仮想マシンサービスは利用できません

Hyper-V マネージャでサービスを停止してしまった

どうしても止められなくなったVM(Ubuntu)を再構築しちゃおうと思ったんだけど、できなくて
いろいろやってるうちに、「サービスの停止」を選んでしもうた!(笑)
サービスを停止させた Hyper-V マネージャを復活させる方法について。

Hyper-Vのサービスを停止させてしまうと

こんな画面になっちゃって、仮想マシンが表示されなくなってしまいます。

Hyper-V サービスを復活させるには

PowerShell を「管理者モード」で起動します!

サービスを自動起動に設定します。

PS C:\WINDOWS\system32> sc.exe config vmms start=auto

[SC] ChangeServiceConfig SUCCESS

次に、サービスを開始します。

PS C:\WINDOWS\system32> sc.exe start vmms

SERVICE_NAME: vmms
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 39080
        FLAGS              :

Hyper-V の仮想マシンが復活してくれます


めでたしめでたし。

2023年7月26日水曜日

WEBサーバで、一定時間だけ有効な認証キーで登録する

メールアドレスの入力確認のための方法

2度入力させるUIって、ほんとダメですよね。

メールアドレスを入力してください。(*)
確認のため、再度メールアドレスを入力してください。(*)
(*)必須項目。しかもコピペできないw

んでも、入力ミスっていたら、その後メール来ないし。(笑)
これ、よく見かけますよねぇ。
昔はうちもやってましたが(笑)

認証キーを送信して、入力させる方法

そこで、30分とか1時間だけ有効な認証キーを送って、それを入力してもらうようにするといいんですね。
これも、よく見かけるようになりましたが(笑)

こんな画面です。

メールアドレスを入力して「認証キー送信」ボタンを押してもらう。
受信したメールに記載の認証キーを入力して、本来の登録処理にする。
こうすることで、メールが届かなかったら、入力ミスだとわかるし、メールが届けば間違いないメールアドレスだと判断できますね
認証キーは一定時間(たとえば30分)だけ有効で、それを過ぎると無効になります。

で、これをどのようにサーバー側で実装しようか、ということですよ。

HTMLページ上の Ajax を使った Javascript は以下のような感じになります。

// 認証キーを送信する処理
onButtonSendAuthKey = function()
{
    // メールアドレスに認証コードを発行するサーバープログラム
    var url = '/regist-temporary';
    var params = {
        mail: $('#input-mail').val()
    };
    $.post({
        url: url,
        data: params,
    }).then(function(response){
        // 略
    });
}

// 入力されたメールアドレスと認証キーで登録する処理
onButtonEntry = function()
{
    // メールアドレスを登録するサーバープログラム
    var url = '/regist-user';
    var params = {
        mail: $('#input-mail').val(),
        auth_key: $('#input-auth_key').val()
    };
    $.post({
        url: url,
        data: params,
    }).then(function(response){
        // 略
    });
}

30分有効な認証キーをどう管理する?

ランダムな認証キーは乱数で構成すれば簡単にできますが、作成した認証キーをどのように管理するのか?
というのが今回のテーマです。
Session と Cookie を使って、ブラウザ側に記憶させる、という方法もあるでしょうけど、クライアント側に覚えさせるのは、ちょっと抵抗を感じてしまいます。
んでは、サーバー側で対応するとすると、どうすべきでしょう?
データベースに一時ユーザーテーブルを用意しておく、という方法が一般的のようです。

一定時間を経過したら、その情報を削除しなければならないわけで、それには cron でシェル作ってDBの作成時間を見て delete、と。
と考えるとですね、おっさんプログラマにはリソースの膨大な無駄遣いのように思えて仕方がないのですよ(笑)

サーバー側の認証キー送信処理(/regist-temporary)では以下の手続きが必要になります。
・認証キーを生成する。
・メールアドレスに認証キーを送信する。
・メールアドレスに対して発行した認証キーを記録する。
・30分経っても登録されない場合、認証キーを削除する。
サーバー側の登録処理(/regist-user)は以下の手続きが必要です。
・認証キーが無効になっていないかを判断する。
・メールアドレスと認証キーが一致するか判断する。
・本来の登録処理を行う。
という流れなんですが、リソースの使用を最小限に留めて、サクサク動くようにできないもんでしょうかね。

/dev/shm を使う!

そこで、思いついたのが、一般的な Linuxサーバに必ず用意されていて、あまり利用されている風ではない、/dev/shm (RAMディスク)を利用する方法です。
1.ユーザーごとに生成した認証キーを /dev/shm/サービス名/temp_auth/ ディレクトリに記録しておく。
2.登録時には、記録内容を照合する。
3.cron で記録ディレクトリの一定時間経過したファイルを削除する。
という方法ですね。

メールアドレスごとに認証キーを生成して、RAMディスクに記録する

// メールアドレスごとの認証キーを生成して、送信する処理
function send_auth_key($mail)
{
    // ランダムな認証キーを生成
    $auth_key = $this->create_auth_key();
    $path = '/dev/shm/service/temp_auth';
    $rc = mkdir($path, 0777, true);
    if(!$rc)
    {
        //エラー処理
    }
    //メールアドレスを Base64(URL)エンコード
    $mail_hash = $this->Base64UrlEncode($mail);
    // 拡張子に .key を追加(なんとなくw)
    $fname =  $mail_hash . '.key';
    $filename = "$path/$fname";
    $rc = (0 < file_put_contents($filename, $auth_key));
    if($rc)
    {
        $rc = chmod($filename, 0666);
        if($rc)
        {
            // 認証キーをメールで送信(省略)
            $rc = $this->send_auth_key($mail, $auth_key);
        }
    }
}

// ランダムな認証キー生成
function create_auth_key($column = 6)
{
    $authKey = '';
    $digits = '0123456789';

    for ($i = 0; $i < $column; $i++) {
        $authKey .= $digits[rand(0, strlen($digits) - 1)];
    }

    return $authKey;
}

// Base64URL encoder
function Base64UrlEncode($data) { 
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 
  
// Base64URL decoder
function Base64UrlDecode($data) { 
    // = 埋めしなくてもいける
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); 
} 

メールアドレスを BASE64エンコードするのは、メールアドレスの中にファイル名に使用できない文字が含まれるかもしれないのを避けるためですね。
BASE64で利用される +と/ の記号は -と_ に変換することで、ファイル名として機能するようにしています。
あと、chmod 0666 しておくのは、apache と cron でアクセスしてくるユーザーが異なるためです。

一時ファイルを一定時間後に削除する、のはcron で以下のように設定しました。(例は3分ごとに実行してるので、少しタイムラグあります)

#crontab で認証キーの制限時間超えたファイルを消す
*/3 * * * * find /dev/shm/service/temp_auth/ -name '*.key' -mmin +30 -delete > /dev/null 2>&1

実際に認証キーとメールアドレスが送られてきたときの処理コードを入れておきます。

function checkAuthKey($mail, $auth_key)
{
    $rc = false;
    $error_message = '認証キーが異なっているか、または期限が切れています';
    $path = '/dev/shm/service/temp_auth';
    $mail_hash = $this->Base64UrlEncode($mail);
    $fname =  $mail_hash . '.key';
    $filename = "$path/$fname";
    $saved_key = false;
    if(file_exists($filename))
    {
        $saved_key = file_get_contents($filename);
    }
    if($saved_key)
    {
        $rc = (strcmp($auth_key, $saved_key) == 0);
    }
    return [$rc, $filename, $mail_hash, $error_message];
}

まとめ

今回はサーバー側で一時的な認証キーを生成してメールアドレスの確認と登録処理に至るプロセスで、Cookieやデータベースを使わない方法をまとめてみました
こういった需要って、よくあることだと思うので、参考にしてくださいまし。
実際、サクサク動いてくれるし間違いも起こりにくいので、安全に運用できています。
めでたしめでたし。