IBMiのWeb開発では円マークに気をつけよう

IBMi の Web 開発しているときの **¥（円マーク）**  と **\（バックスラッシュ）** について気をつけましょうって話。

## 何を気をつけるのか？

Web開発をしている際の話。（※JISキーボード前提で）
WindowsのWebブラウザで、フォーム入力時に、キーボード右上段の `¥（円マーク）` を入力した際に、UNICODE（ *※以下 UTF-16 の 0x 形式で表記* ）の **円マーク(0x00A5)** となり、右下段の `\（バックスラッシュ）` を入力した際には、UNICODEの **バックスラッシュ(0x005C)** になれば良いのだけど、実際はそうはならない。
実際にはどっちも UNICODEの **バックスラッシュ(0x005C)** となる。

これは、自分も知らないような、昔々のお話 ASCII コードを 1bit 拡張して、半角カナを割り当てたり、バックスラッシュに見た目だけ円マークを割り当てたりの負の遺産によるモノ。

海外の友人と文字コード関連の会話する時は、まぁー常に伝わらない部分で「酷いSBCSを使っている（ｶﾀｶﾅを含めてそう思っている）」と言われている。確かに酷い😂

フォーム入力に限らず、API 連携でデータをやりとりする時も、**円マーク** や **バックスラッシュ** を含むケースはお互い齟齬がないように認識合わせも必要。

## 参考リンクや再現サンプル

- [サンプルDB DDS](https://github.com/ushiday/qiita-rpgle/blob/main/QDDSSRC/Q231223F.PF)
- [DB書き込みサンプル PHP※Web入力想定](https://github.com/ushiday/qiita-rpgle/blob/main/IFS/Q231223-01.php)
- [PHP実行スクリプト](https://github.com/ushiday/qiita-rpgle/blob/main/IFS/Q231223-01.sh)
- [日本語環境でのUnicodeの諸問題](https://ja.m.wikipedia.org/wiki/Unicode#.E6.97.A5.E6.9C.AC.E8.AA.9E.E7.92.B0.E5.A2.83.E3.81.A7.E3.81.AEUnicode.E3.81.AE.E8.AB.B8.E5.95.8F.E9.A1.8C)

## PHPでDBを更新すると...

以下のPHPサンプルコードで `\¥$(0x005C,0x00A5,0x0024)` を DB に書き込むと、CCSID による変換が行われる。
更に 5250 の表示の際には、エミュレータのコードページによる変換も行われ、エミュレータソフトにより見え方も異なる。あー混乱する...(TдT)

#### サンプルDB DDS
```txt:Q231223F.PF     
     A                                      CCSID(1399)
     A          R Q231223R
     A            CHAR_5026     16A         COLHDG('５０２６・文字列')
     A                                      CCSID(00290)
     A*
     A            CHAR_5035     16A         COLHDG('５０３５・文字列')
     A                                      CCSID(01027)
     A*
     A            CHAR_1399     16A         COLHDG('１３９９・文字列')
     A                                      CCSID(05123)
```

#### サンプルDB 書き込み PHP
```php:Q231223-01.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
![001-1399-pcomm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/d51a21c7-85fa-e132-9436-6057fc514131.png)

### ACS-1399
![002-1399-acs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/f5b382fb-3290-5635-76e5-b63d1e139993.png)

### Pcomm-5026
![003-5026-pcomm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/fb1145d6-d579-85dc-4a0a-318957b688e9.png)

### ACS-5026
![004-5026-acs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/4db70ba2-d44c-b444-44a5-4e22f5d3adf3.png)

## まとめ

まぁ、昔は世界中がITCで繋がるなんて想像もつかないだろうし、今とりあえず何とかななれば的な発想だったのかもしれないのは、仕方ないかもしれないけどね。
ややこしいのは、この”バックスラッシュ”が見た目は”円マーク”になっている事が混乱を招く。
Webから入力された「見た目円マーク」をDBに登録して、それを Windows のパス区切り文字なんかに使用した日にゃ全然上手く行かない、なんてことも有り得る。
さらに問題なのは、キーボードで、MacやLinuxなら良いのだけど、Windowsだと意識して変換（またはコピペ）しないと UNICODEの **円マーク** が入力出来ない事。ユーザーに「かな変換で円マークいれてね」ってなっちゃう。これだとバックスラッシュを自動変換した方が安全だったりする。
5250エミュレータも表現の挙動が、まちまちでこれまた混乱しやすい。使っているエミュレータが違うと会話が噛み合わない。P-Comm と ACS で表示がちがったり、ACS だとそもそも見た目に「**円マーク**」の区別がつかないのがさらに厄介。何とかなりませんかね？
兎に角、みなさんもWebから円マーク扱うときは気をつけましょう。:laughing: