アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在、jcode.plを使用したShift JISで構成されていた Perlのcgi を UTF-8 に改造しています。

フォームに書き込んだPAGETITLEを別ファイルへUTF-8で書きこむ際に、文字化けしてしまいます。

書きこんだファイルを開けてみると、日本語が文字化けしています(アルファベットは大丈夫)

以下のPerlのPAGETITLEをどのように改造すれば、文字化けしないで、$foundations_fileへUTF-8で書き込みすることができるのでしょうか?

※個人的にはデータ書き込みの sub REGIST 以下を改造すれば良いのではと推測していますが、どうやれば良いのか分かりません。

どうかご教示、よろしくお願い致します。
m(_ _)m

-------------------------------------


#!/usr/bin/perl
use utf8;
binmode STDIN,":utf8";
binmode STDOUT,":utf8";

#基本セットアップファイル読込
require './setup_manage.cgi';

#このファイル
$cgi = "./foundations.cgi";

#デコード処理
&DECODE;


sub VIEW {

#基本設定ファイルの読み込み
&FOUNDATIONS_READ;

【省略】

<TABLE width="100%" border="0" cellspacing="0" cellpadding="1"><TR>
<TD width="70%">変更するデータを直接書き換えて [ 編集実行 ] を押して下さい。</TD>
<FORM method="post" action="./login.cgi">
<TD width="30%" align="right"><INPUT type="submit" value="メインメニューに戻る"></TD>
<INPUT type="hidden" name="mode" value="main">
<INPUT type="hidden" name="pw" value="$in{'pw'}">
</FORM>
</TR></TABLE>

【省略】

<TABLE border="0" cellspacing="1" cellpadding="4" bgcolor="#999999"><TR>

<FORM name="SUBMIT" method="post" action="$cgi" onSubmit="return kakunin()">

<TD width="160" bgcolor="#eeeeee">
<TABLE border="0" cellspacing="0" cellpadding="1"><TR>
<TD>ページタイトル</TD>
</TR></TABLE>
</TD>
<TD width="400" bgcolor="#ffffff">
<TABLE border="0" cellspacing="0" cellpadding="1"><TR>
<TD><INPUT type="text" name="PAGETITLE" size="60" value="$PAGETITLE"></TD>
</TR></TABLE>
</TD>

【省略】

-------------------------------------------------
# データ書き込み
#-------------------------------------------------
sub REGIST {

#全角英数字を半角に変換
$zenkaku = '0123456789';
$hankaku = '0123456789';

$in{'PAGETITLE'} =~ s/\,/&%/g;
$in{'PAGE1'} =~ s/\,//g;
$in{'PAGE2'} =~ s/\,//g;
$in{'PAGE3'} =~ s/\,//g;
$in{'CATECOL'} =~ s/\,//g;
$in{'PERIOD'} =~ s/\,//g;
$in{'TABLECOL'} =~ s/\,//g;
$in{'SIZECOL'} =~ s/\,//g;
$in{'SIZEROW'} =~ s/\,//g;
$in{'COPYRIGHT'} =~ s/\,/&%/g;


#ファイルロック開始
if( $lockkey ne '0' ){ &LOCK; }

#ファイルに書きこむ
if (!open(OUT,">:utf8",$foundations_file)) { &ERROR( read_foundations ); }

print OUT "$datenow,$in{'PAGETITLE'},$in{'INIMODE'},$in{'MODECHG'},$in{'PAGE1'},$in{'PAGE2'},$in{'PAGE3'},$in{'CATEVIEW'},$in{'CATECOL'},$in{'INICATE'},$in{'PERIOD'},$in{'RANKING'},$in{'CMODE'},$in{'RANKVIEW'},$in{'TITLEVIEW'},$in{'SRCHVIEW'},$in{'INPVIEW'},$in{'DATAROW'},$in{'TABLECOL'},$in{'BARCLR'},$in{'BARPER'},$in{'IMGPRT'},$in{'IMGSIZE'},$in{'SIZECOL'},$in{'SIZEROW'},$in{'IMGFRM'},$in{'COPYRIGHT'},$in{'GPVIEW'},";
close(OUT);


#ファイルロック解除
if( $lockkey ne '0' ){ &UNLOCK; }

&COMP;
}

A 回答 (12件中1~10件)

どう「実際に Encode::decode を使ったのか」が疑問ですが.... 少なくとも, pack しただけでダメなのは文字数を考えれば明らかで, 「pack で得られた文字列を改めて UTF-8 として解釈し直す」というのは必須なはず.



あと, 「フォームで出てくる」というときに, フォントなんかも問題になりえる. そもそも UTF-16 な出力をしているときに UTF-8 な出力をしちゃったらどう考えてもダメだし, あるいは「理由はさておき UTF-8 な文字コードを上手く扱えないフォントレンダラー」だったりするとやっぱり UTF-8 じゃダメだよね. ということは, 「フォームの表示を見る」だけではダメで, HTML (なり XHTML なり) のレベルで正しくなっているかどうかから考えなきゃならないような感じがします.
    • good
    • 0
この回答へのお礼

たびたびのご回答、誠にありがとうございました。

とても参考になります。

HTMLの設定は、以下のように全てUTF-8にしています。

-------------------------------

sub HEADER {
print "Content-type: text/html; charset=utf-8\n\n";
#print "Content-type:text/html\n\n";
print <<"EOF";
<HTML><HEAD>
<TITLE>管理ページ - 基本設定</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<META http-equiv="Content-Script-Type" content="text/javascript">
<META http-equiv="Content-Style-Type" content="text/css">
<META http-equiv="imagetoolbar" content="no">
<META name="robots" content="none">
<META name="robots" content="noindex,nofollow">
<LINK rel="stylesheet" type="text/css" href="$css">
<SCRIPT Language="JavaScript"><!--
function clrinfo(){
window.open("./color.cgi","clrinfo","toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=1,resizable=0,width=650,height=500") }
//--></SCRIPT>
</HEAD>
<BODY topmargin="10" leftmargin="0" rightmargin="0" text="#333333" bgproperties="fixed">
-------------------------------

あと文字が化けて出てくる

"$PAGETITLE"

の記載してあるHTMLも、上記設定内に含まれているので、UTF-8の状態になっているはずです。

-------------------------------

<TABLE width="100%" border="0" cellspacing="0" cellpadding="0"><TR>
<TD height="15"><HR width="100%" size="1" color="#cccccc"></TD>
</TR></TABLE>

<TABLE border="0" cellspacing="0" cellpadding="0"><TR>
<TD height="30">最終更新日時 : <FONT class="g10pt" color="#003d84">$DATE_FOUNDATIONS</FONT></TD>
</TR></TABLE>

<TABLE border="0" cellspacing="1" cellpadding="4" bgcolor="#999999"><TR>

<FORM name="SUBMIT" method="post" action="$cgi" onSubmit="return kakunin()">

<TD width="160" bgcolor="#eeeeee">
<TABLE border="0" cellspacing="0" cellpadding="1"><TR>
<TD>ページタイトル</TD>
</TR></TABLE>
</TD>
<TD width="400" bgcolor="#ffffff">
<TABLE border="0" cellspacing="0" cellpadding="1"><TR>
<TD><INPUT type="text" name="PAGETITLE" size="60" value="$PAGETITLE"></TD>
</TR></TABLE>
</TD>
</TR><TR>

-------------------------------

あと一息だと思うんですが・・・

お礼日時:2011/05/08 23:28

なんか言葉が足らないんだよな~.



例えば #8 のお礼で
「Encode::decodeを試してみましたが、うまくいきませんでした。」
って書いてるけど, これであなたが「どのように試したのか」わかる人がいると思いますか? また, #10 の方でも
「はい、HTMLは確認しています。」
と書いてるけど, 具体的にどのように確認したの?
    • good
    • 0
この回答へのお礼

お礼遅くなりましてすみません。
ご返答ありがとうございました。

ご指摘の通り、言葉足らずでした。

以下のコードを入れてみましたが、ダメでした。

use Encode::Guess qw/ shiftjis euc-jp 7bit-jis /;
use Encode qw/ decode /;
$enc = guess_encoding ( $PAGETITLE );
if ( ref $enc ) { $utf8 = decode ( $enc->name , $PAGETITLE ); }

htmlはコードの

<META http-equiv="Content-Type" content="text/html; charset=utf-8">

とcharset=utf-8 に全て変えました。

またIE や Firefoxで確認しましたが、やはり文字化けしていました。

いろいろ試しても変わらないので、諦めようかとも考えてきました。

お礼日時:2011/05/13 21:56

思うんだけど・・・無駄に複雑なもので検証してないです?



ここまでごちゃごちゃになったら
いっそすっきり単純化して
ひとまず「正しく動くもの」を作れません?

たとえば,ラジオボタンだけで
日本語の文字列を送って処理して出したり,
hidden属性もでいいや,それとか
POSTとGETを切り替えたり
とにかく単純でロジックが簡単に追えるもの.

いまのままだと
URLエンコーデとPerlのencodeとかが
ごっちゃごちゃになってませんか?

あとは,吐き出したファイル(htmlの必要ないですよね,ひとまず)を
エディタでみるんじゃなくて,バイナリエディタでみて
コードそのものを確認するとかも必要かも
そうすればブラウザやフォントの問題か否かもわかるのでは?
    • good
    • 0
この回答へのお礼

kabaokabaさま

ご回答ありがとうございました。

単純化するというのは、非常に良いアイデアだと思いますので、週末にチャレンジしようと思います。

「バイナリエディタでみてコードそのものを確認する」ということに関して、よく分からなかったのですが、やった方がよさそうみたいなので、ネットで意味を調べて分析を頑張りたいと思います。

フォントというヒントを頂き、なるほど!と思って、cssファイルのフォントをSimsunからMSゴシックに変えてみました。

しかしながら、症状は同じで文字化けは引き続き発生しています。

お礼日時:2011/05/10 22:18

「実際に出力された (X)HTML」は確認してる?

    • good
    • 0
この回答へのお礼

またご回答頂きまして、ありがとうございました。

はい、HTMLは確認しています。

やはり、化けたままです・・・。

お礼日時:2011/05/10 22:15

Encode::decode?

    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

Encode::decodeを試してみましたが、うまくいきませんでした。
(私のやり方が悪かったのかもしれませんが・・・)

なかなかの難問です(汗)

お礼日時:2011/05/08 21:14

もう一度、確認させてください。


No.2の記述で、

# これはコメントアウト
#binmode STDIN,":utf8";

というのも書いてますが、これもした上で文字化けをしているのでしょうか?

URLエスケープされた文字列に対してutf8フラグが立っているように見えるんですよね。

していただくことをまとめると、
まず、以下をコメントアウト。

#binmode STDIN,":utf8";

そして、以下もコメントアウト。

#デコード処理
#&DECODE;

さらに、以下の3行を追加。

sub REGIST {

#全角英数字を半角に変換
$zenkaku = '0123456789';
$hankaku = '0123456789';

# ここに以下3行を追加
use Encode;
use CGI;
%in = map decode_utf8($_), CGI->new->Vars;

$in{'PAGETITLE'} =~ s/\,/&%/g;
$in{'PAGE1'} =~ s/\,//g;

この回答への補足

お世話になっております。

以下のサイトは、何か手掛かりにならないでしょうか?


perlのUTF8プログラミングでのURLエンコード

http://typeangler.net/?m=blog&eid=f02547e63ab646 …

補足日時:2011/05/09 22:10
    • good
    • 0
この回答へのお礼

度々のご回答、誠にありがとうございます。

はい、この通り行っても文字化けしています。

ファイルへ書き出す際に化けている気がしますが、

その原因が分からないので悲しいです。

どうか引き続きよろしくお願い致します。

お礼日時:2011/05/08 23:37

前回の質問では、



stdio::getFormData(\%in,1,"sjis",1,",","$updir/");

との記述があったのですが、今回のコードにはこれはないのでしょうか?
あればコメントアウトしてください。

できればエディタで、%inを検索して、%inの記述がある行を全て抽出お願いします。

文字の化け具合に関しての補足は、詳しい人が回答(解説)してくれかもしれませんので、文字化けが解消しても質問はオープンのままでお願いします(実は私も回答者というよりこのサイトで勉強しているので^^;)
    • good
    • 0
この回答へのお礼

ryu_chanさま

ご回答ありがとうございました。

今回は、%in も stdio::getFormData(\%in,1,"sjis",1,",","$updir/"); も

ない状態です。

ちょっと途方に暮れていますが、
もし、何かお気づきの点がありましたら、よろしくお願い致します。
m(_ _)m

お礼日時:2011/05/08 10:25

#$in{'PAGETITLE'} =~ s/\,/&%/g;


#$in{'PAGE1'} =~ s/\,//g;

これらは代入でなく置換なのでコメントアウトする必要はないです。
推測で、

#デコード処理
&DECODE;

ここの関数の中で、%inに代入しているのでしょう。
なので、この関数呼び出しをコメントアウトして、No.2の記述を追加すればどうなるでしょうか?

この回答への補足

ちなみにDECODE処理は以下の通りです。

#-------------------------------------------------
# デコード処理
#-------------------------------------------------
sub DECODE {
if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});}
else { $buffer = $ENV{'QUERY_STRING'}; }

@pairs = split(/&/,$buffer);
foreach $pair (@pairs) {

($name,$value) = split(/=/, $pair);
$name2 = $name;
$value2 = $value;
$FORM2{$name} = $value;

$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
#半角カナを全角に変換
#Jcode::h2z_sjis(*value);
#文字コード変換
#Jcode::convert(*value,'sjis');

$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;
$value =~ s/\n/!%/g;
$value =~ s/\r//g;
$value =~ s/\t//g;
$value =~ s/\,/&%/g;
$value =~ s// /g;

#フォーム変数へ
$in{$name} = $value;
}
}

よろしくお願い致します。

補足日時:2011/05/08 08:21
    • good
    • 0
この回答へのお礼

ryu_chanさま

丁寧なご回答、誠にありがとうございます。

#&DECODE;として、No.2の記述を記載しましたが、ダメでした。

No.4のTacosanさまのアドバイスに基づき、文字コードの化け具合を遅まきながら確認してみました。



問題のフォームに

あ を入れると「あ」※ と出ます。

※化けて表示される可能性もあるので、念のため化けた文字の説明も書いておきます。

・aの上に波線がある文字 と

□の中に小さな数字4つ入っており、
・上二段が左から00
・下二段は左から81

次の□の数字は
・上二段が左から00
・下二段は左から82

と書いてありました。


いつも、上記の状態で文字化けします。


この文字を
http://seo.atompro.net/webtoolfree_strcnvj_.html
でescape変換すると、変換後の文字列は、
%E3%81%82 となりました。

さらにこの文字を

http://seo.atompro.net/webtoolfree_strcnva_.html



変換前:urldecode

変換後:sjis

で変換すると、見事に あ の文字に戻りました。



ちょっと複雑な感じがしますが、
この情報を元に、改善策を練ることはできますでしょうか?

何卒よろしくお願い致します。
m(_ _)m

お礼日時:2011/05/08 08:08

「UTF-8で外部ファイルへ書き込めていない」と推測した根拠は? 「UTF-8 じゃない」としたら何で書き込まれている?



「具体的には、どうすれば良いでしょうか」って聞いてるけど, 「何を入力したら何が出てくるのか」はわかるはずだから, あとは文字コード表とにらめっこすればいいだけ. 「文字化けしてる」と思ったらこのくらいは考えていいんじゃない?
    • good
    • 0
この回答へのお礼

Tacosanさま

ご指摘及びアドバイス、誠にありがとうございます。
基本的なところが抜けておりまして、誠に恥ずかしい限りです。

文字化けについて分析したところ、新たなことが分かりました!
※詳細はNo.5様のご回答のお礼に記述しました。

解決へ向けて一歩進めることができました!

お礼日時:2011/05/08 08:12

回答側で動きもしないcgiのスクリプトをdebugする元気はないけど


そもそも,
cgiではない「普通のperl script」の段階で
日本語の入出力はできてるのですか?

日本語が書かれたファイルを読み込んで,
処理した後に
また別ファイルに出力する
ってことができてるんでしょうか?

それができてるのであれば
cgi特有の部分が問題だということになるのでは?
    • good
    • 0
この回答へのお礼

kabaokabaさま、ご回答ありがとうございました!

日本語が書かれたファイルを読み込んで,
処理した後にまた別ファイルに出力することはできています。

出力の際に、文字化けして書き込んでいる状況です。

cgi特有の部分というのは、具体的にどのあたりが怪しいと思われるのかアドバイス頂けると幸いです。

お手数おかけ致しますが、よろしくお願い致します。

m(_ _)m

お礼日時:2011/05/08 00:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!