IBMi の Web 開発しているときの ¥(円マーク) と \(バックスラッシュ) について気をつけましょうって話。
何を気をつけるのか?
Web開発をしている際の話。(※JISキーボード前提で)
WindowsのWebブラウザで、フォーム入力時に、キーボード右上段の ¥(円マーク)
を入力した際に、UNICODE( ※以下 UTF-16 の 0x 形式で表記 )の 円マーク(0x00A5) となり、右下段の \(バックスラッシュ)
を入力した際には、UNICODEの バックスラッシュ(0x005C) になれば良いのだけど、実際はそうはならない。
実際にはどっちも UNICODEの バックスラッシュ(0x005C) となる。
これは、自分も知らないような、昔々のお話 ASCII コードを 1bit 拡張して、半角カナを割り当てたり、バックスラッシュに見た目だけ円マークを割り当てたりの負の遺産によるモノ。
海外の友人と文字コード関連の会話する時は、まぁー常に伝わらない部分で「酷いSBCSを使っている(カタカナを含めてそう思っている)」と言われている。確かに酷い😂
フォーム入力に限らず、API 連携でデータをやりとりする時も、円マーク や バックスラッシュ を含むケースはお互い齟齬がないように認識合わせも必要。
参考リンクや再現サンプル
PHPでDBを更新すると...
以下のPHPサンプルコードで \¥$(0x005C,0x00A5,0x0024)
を DB に書き込むと、CCSID による変換が行われる。
更に 5250 の表示の際には、エミュレータのコードページによる変換も行われ、エミュレータソフトにより見え方も異なる。あー混乱する...(TдT)
サンプルDB DDS
A CCSID(1399)
A R Q231223R
A CHAR_5026 16A COLHDG('5026・文字列')
A CCSID(00290)
A*
A CHAR_5035 16A COLHDG('5035・文字列')
A CCSID(01027)
A*
A CHAR_1399 16A COLHDG('1399・文字列')
A CCSID(05123)
サンプルDB 書き込み PHP
//左から「バックスラッシュ、円マーク、ドル記号」
$val ='\¥$';
//SQL文
$sql=<<<EOT
INSERT INTO Q231223F
(
SELECT
'$val' AS CHAR_5026
,'$val' AS CHAR_5035
,'$val' AS CHAR_1399
FROM SYSIBM.SYSDUMMY1
)
EOT;
// SQLプリペア
$stmt = db2_prepare($db,$sql);
if($stmt === false){
echo 'ERR(01)Prepareエラー' , '<br>';
exit(3);
}
// SQLの実行
$result = db2_execute($stmt) ;
各エミュレータソフトで見え方
上記を書き込んだ結果を各エミュレータソフトとCCSID(1399と5026)で見たときの様子は以下の感じ。5035は1399と同じなので割愛。
Pcomm-1399
ACS-1399
Pcomm-5026
ACS-5026
まとめ
まぁ、昔は世界中がITCで繋がるなんて想像もつかないだろうし、今とりあえず何とかななれば的な発想だったのかもしれないのは、仕方ないかもしれないけどね。
ややこしいのは、この”バックスラッシュ”が見た目は”円マーク”になっている事が混乱を招く。
Webから入力された「見た目円マーク」をDBに登録して、それを Windows のパス区切り文字なんかに使用した日にゃ全然上手く行かない、なんてことも有り得る。
さらに問題なのは、キーボードで、MacやLinuxなら良いのだけど、Windowsだと意識して変換(またはコピペ)しないと UNICODEの 円マーク が入力出来ない事。ユーザーに「かな変換で円マークいれてね」ってなっちゃう。これだとバックスラッシュを自動変換した方が安全だったりする。
5250エミュレータも表現の挙動が、まちまちでこれまた混乱しやすい。使っているエミュレータが違うと会話が噛み合わない。P-Comm と ACS で表示がちがったり、ACS だとそもそも見た目に「円マーク」の区別がつかないのがさらに厄介。何とかなりませんかね?
兎に角、みなさんもWebから円マーク扱うときは気をつけましょう。