質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

1820閲覧

【Perl】POSTメソッドで受け取った顔文字をujisのデータベースに文字化けなく入れたい。(内部コードEUC-JP)

jagaimo300

総合スコア20

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2020/10/15 08:40

編集2020/10/16 04:35

前提

Perl 5.24.3 内部コード EUC-JP
(XAMPPのPerlではなくActive Perlインストール後ジャンクション作成済み C:¥usr/bin/perl)
MySQL 15.1 Distrib 10.4.14-MariaDB, for Win64 ujis
使用環境Windows10 Home XAMPP

・デザイン業務を想定して入社したが、Perlの修正案件にバックエンドとしてアサインされてビックリした。
・Googleが先生
・文字コード EUC,ujisの知識が弱い
・2009年ごろ書かれたスパゲッティコード
・ファイルをローカルのブラウザ上で動かせない

※ソースコードは筆者が必要部分を推測、ググり、抜粋 見当違いな可能性有り(すみません)

発生している問題

ブラウザおよびデータベース上でこういった顔文字( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾が( ??????? )???このように文字化けして表示される。

#状況把握
Postメソッドで投稿したプロフィール分→パラメータで取得→DBに格納→ブラウザに表示
これがソース見ながらググった流れです。

考察

・POSTメソッドで受けとる時にPerlで文字コードを合わせる必要性
または
・POSTメソッドで受けとったデータを
DB格納前に文字コードを合わせる

Perl

1$kaomoji = "( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾"; 2print $kaomoji; 3#これは文字化けするし、このままクエリでDBに入れても当然文字化けする。 4 5 6 7 8 9if($param{'foo'}){ 10    #ここに一、二行書くだけのような気がしている。 11 push(@update_set, qq|foo="$param{'foo'}"|); 12}else{ 13 push(@update_set, qq|foo=""|); 14} 15 16 17

該当のテストソースコード

HTML

1<form action="hogehoge.cgi" name="form01" method="post" enctype="multipart/form-data" autocomplete="off"> 2 3<fieldset> 4<input name="mode" type="hidden" value="foofoo" /> 5<div class="woo"> 6<textarea name="foo" id="foo" cols="92" rows="5" class="form-control" placeholder="ここに入力※htmlタグ不可"></textarea> 7</div> 8<input type="submit" value="プロフィールを新規登録する" style="margin:15px 0;" class="btn btn-block btn-success btn-lg"> 9</fieldset> 10 11</form>

Perl

1#!/usr/bin/perl 2 3use DBI; 4use File::Basename; 5use Net::FTP; 6 7require 'jcode.pl'; 8require 'stdio.pl'; 9 10$database = "test_db"; 11$user = "root"; 12$password = "root" 13$dbh = DBI->connect("DBI:mysql:$database", $user, $password); 14#テーブル名はtest 15 16 17if($param{'mode'} eq 'foofoo'){ 18 19 20if($param{'foo'}){ 21 push(@update_set, qq|foo="$param{'foo'}"|); 22}else{ 23 push(@update_set, qq|foo=""|); 24} 25 26$query = qq| 27INSERT INTO `test` SET $update_set; 28|; 29 30$sth = $dbh->prepare($query); 31$sth->execute(); 32 33 34} 35 36

試したこと

Perl のPOSTメソッドの受け取り方

・read (STDIN, $PostData, $ENV{'CONTENT_LENGTH'}); を用いたもの、
・モジュール CGIを用いたもの
複数サイトを参考にしてやってみたが、

この問題を解決するには
筆者の見当違いのようでした。

現在モジュール Encode 試している

補足情報

#####データの受け取り方にはコレ使っていると推定

Perl

1%param = (); 2$key_type=''; $key_type_num=0; 3$foo=''; $foo_num=0; 4@keys = stdio::getFormData(\%param, "", "EUC", ";", "$img_dir/"); 5foreach(@keys){ 6 if(/file/){ next; } 7 if (/^key_type/) { 8 $param{'key_type'} .= $param{$_}." "; 9 $key_type_num++; 10 next; 11 } 12 if (/^foo/) { 13 $param{'foo'} .= $param{$_}." "; 14 $girl_option_num++; 15 next; 16 } 17 $param{$_} =~ s/\'/’/g; 18 $param{$_} =~ s/\"/”/g; 19} 20

#追記

###テスト実行記録2020/10/16

html

1 2#post_test.html 3 4 5<html> 6<head> 7<meta http-equiv="Content-Type" content="text/html"; charset="euc-jp"> 8<meta name="viewport" content="width=device-width, initial-scale=1.0"> 9<title>Document</title> 10</head> 11<body> 12<h1>顔文字をujisのデータベースに文字化けなく入れたい。</h1> 13 14<form action="https://localhost/new_sen-aso.com\tpl_site_adm\post_test.cgi" name="form01" method="post" enctype="multipart/form-data" autocomplete="off"> 15 16 <fieldset> 17 <input name="mode" type="hidden" value="foofoo" /> 18 <div class="woo"><textarea name="foo" id="foo" cols="92" rows="5" class="form-control" placeholder="ここに入力※htmlタグ不可"></textarea></div> 19 20 21 22 <input type="submit" value="プロフィールを新規登録する" style="margin:15px 0;" class="btn btn-block btn-success btn-lg"> 23 </fieldset> 24</form> 25</body> 26</html>

Perl

1#!/usr/bin/perl 2print "Content-type: text/html\n\n"; 3 4#post_test.cgi 5 6use DBI; 7use Encode; 8 9require '../stdio.pl'; 10 11$dbName = 'test_db'; 12$dbPass = 'root'; 13$dbUser = 'root'; 14 15 16$dsn = "DBI:mysql:$dbName"; 17$dbh = DBI->connect( $dsn, $dbUser, $dbPass, { RaiseError => 1 } ); 18$dbh->do("set names ujis"); 19 20 21%param = (); 22$key_type=''; $key_type_num=0; 23$girl_option=''; $girl_option_num=0; 24@keys = stdio::getFormData(\%param, "", "EUC", ";", "$img_dir/"); 25foreach(@keys){ 26 if(/file/){ next; } 27 if (/^key_type/) { 28 $param{'key_type'} .= $param{$_}." "; 29 $key_type_num++; 30 next; 31 } 32 if (/^girl_option/) { 33 $param{'girl_option'} .= $param{$_}." "; 34 $girl_option_num++; 35 next; 36 } 37 $param{$_} =~ s/\'/’/g; 38 $param{$_} =~ s/\"/”/g; 39} 40 41if($param{'mode'} eq 'foofoo'){ 42 43 44 45 if($param{'foo'}){ 46 print $param{'foo'}; 47 $query = qq| 48 INSERT INTO `test_hoge`(`comment`) VALUES ("$param{'foo'}") 49 |; 50 $sth = $dbh->prepare($query); 51 }else{ 52 print"foooooooooooooooooooooooooooooooooooo"; 53 } 54 55 56} 57 58$sth->finish(); 59$dbh->disconnect; 60 61

筆者は上記のようにXAMPP環境で実運用の処理をを限りなく忠実に再現して、
ブラウザに表示、DB上に表示させるテストに成功しましたが
問題のこの子たち↓は文字化けはしませんでした。これには思わず笑いました(笑)
(∩´﹏`∩) (。◕∀◕。)ノ⋆。оO(㋵㋺㋛㋗㋧♡
( ˘͈ ᵕ ˘͈ )♡
( *ˊᵕˋ)✩︎‧₊♡
( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾

クライアントが使用するデバイス・ブラウザ・顔文字キーボードアプリ(Simeji)などいろいろパターンを調査のち検証を重ねて特定を試みます。
先輩の皆様、ありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/10/15 09:49

>(内部コードEUC-JP) > for Win64 ujis ここが変更不可なら困難かと思います。
m.ts10806

2020/10/15 09:50

ちなみに変更できたとしても?????と文字化けして登録されたデータは救えません。
dodox86

2020/10/15 10:02

※「UJIS」と言う用語を「EUC-JP」として使っているものとしてコメントします。 確認ですが、データベースの文字コードはEUC-JPに設定済み、PerlのCGIのソースコードもEUC-JPなのですよね。 最初にPOSTメソッドで送るフォームのHTML自体の文字コードが正しくないのではないでしょうか。 htmlファイル自体の文字コードがEUC-JPでかつ、htmlにも以下のような記述がされているか確認してください。 <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> データベース内でEUC-JPであって、その内容を確認したときに文字化けであるなら、単に見た目の文字化けかもしれません。 それはお使いのターミナルの文字コードと使えるフォントによります。
dodox86

2020/10/15 10:04

それと、一応の確認ですが、以前のシステムでは動いていたのですか? 修正案件に取り掛かったところ、Windows環境なども以前から違っていて、今回の問題が起き始めた、ということなのでしょうか。
dodox86

2020/10/15 10:06

直接質問と関係ないですが、Windows10 HOMEって、実運用のサーバー用途に使って良いのでしたっけ。(<ライセンスの問題として) 個人のテスト用ならばOKでしょうけれど。
jagaimo300

2020/10/15 10:39

m.ts10806様> ご回答ありがとうございます。 既存のデータは無視でよいとのことで、これから記号、特殊文字が????になる前にデータベースに入れましょうということなのですね、、ありがとうございます。もっと見てみます。 dodox86様>  ご回答ありがとうございます。 まず、用語にかんしては申し訳ございません。 UJIS=EUC-JPという理解でいます。 ・DBの対象のテーブルにはujis_japanese_ciに設定されております。 ・Windows10 HOMEに関して →私は完全にテストのみです。 実運用のサーバーにアップロードしてテストすることができず、 reqiredされているファイルなどももらえません笑 XAMMPでテストコード書いてしています。。。 ・<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">に関して これは記述があります。 ・タスクの要件はプロフィール全員の顔文字が文字化けしているわけではないが、局所的に文字化けをしている。それを修正しろというのです。 サイトの構成がユーザー(メンバー)・チーム管理者・運営となっております。 局所的に文字化けしていることから、チーム管理者がメンバーのプロフィールを作成、登録した時に文字化けすると推定しはいるのですが、具体的なテストが出来ないため絶対はないですよね。 ありがとうございます、もっと調べてみます。
guest

回答1

0

ベストアンサー

社内の方針とかあるのでしょうが、一般論的にはこうすべきだろうというのを書いてみます。

  • jcode.plは今すぐ捨ててEncodeモジュールに完全移行。-- jcode.plは15年ぐらい前に時代遅れになったモジュールです。文字コード周りの処理は今はEncodeを使うのが大原則です。
  • perlスクリプトに外部から取り込まれた文字列データは、なにはともあれ即座に内部コードに変換(decode)。
  • パターンマッチや部分文字列の切り取りなど一切の処理は「内部コード」化された(decodeされた)文字列についてのみ行う。
  • 出力対象の文字列(今回なら$query)は出力寸前に(今回はmariaDBに対して$dbh->prepareする直前)に出力対象に合わせた文字コード(今回はEUC?)に変換(encode)。
  • (今回は関係ないかもしれないが)スクリプト内に文字列定数を書き込む場合はコードはutf-8にして、冒頭でuse utf8;を宣言する。

この原則を愚直に守り抜けば、perlスクリプト周辺で文字化けに悩まされることはなくなるはずです。

投稿2020/10/15 11:15

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jagaimo300

2020/10/15 16:04

KojiDoiさま > ご回答ありがとうございます、とても勉強になります。。 jcode.plがreqireされていて、 Encodeモジュールも多用されている(たくさんの方に修正を重ねられてきたよう)のでおっしゃる通りにEncodeを用いた処理で明日、decode encode注意してコードと対峙してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問