トップページ⇒php
1001コメント371KB

Perlコーディング初心者質問スレ Part 50

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/06/26(月) 00:46:38ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0052nobodyさん2006/06/27(火) 18:35:11ID:???
>>50
是非ご教示下さい!
0053nobodyさん2006/06/27(火) 18:40:24ID:???
定期的に削除でいいのか??
Content-type: application/octet-streamで検索
0054492006/06/27(火) 18:49:19ID:???
>>51
やっぱりcronかぁ。
ダウンロード自体の頻度はかなり低い(月に数回程度)ので
すごく無駄な気がしてしまふ・・・。

>ファイルのダウンロードはcgiから以外にはできないようにしておく。
そんなことってできるんスか!?
refererでチェック?でも、簡単に偽装できるから意味ないか。

>一度ダウンロードしたものは2度とできないようにしておく。
これもやり方がさっぱり思い付かない。
パーミッション変更?
でも、いつダウンロードが終了したかは確認できんよな。
これもcron?って、それならパーミッションいじるより削除した方が早いよな。

>>53
ダウンロード頻度が低い、つまり削除の頻度も低いので
定期的に削除というよりは都度削除希望であります。
でも、無理なら仕方ない、といった感じであります。
検索して調べてきます。サンクス!
0055nobodyさん2006/06/27(火) 19:06:41ID:???
そんなに頻度が多くないなら、Location使わずにCGI経由でダウンロードさせるようにすれば?
つまり、CGIがファイルを読み出して出力、全部出力したらファイル削除。

素のファイルには .htaccess などでアクセスできないように設定しておく。
0056nobodyさん2006/06/27(火) 20:19:59ID:???
55の言ってるので出来ますね
print "content-type:MIME-type\n\n";
open fp,"downfile";
print <fp>;
close fp;
unlink "downfile";
ただしMIME typeをちゃんと指定しないと、textで無理やり表示されたり、めんどくさい感じ・・・
あと、ダウンロード→キャンセルでもうファイルが消えてるので、結構使いづらいかも?
.htaccess使うまでもなくパーミッションを600とかにしとけば普通に見えない。

ところで、UPは誰がどういう風にするのかが気になる・・・
それによってはもっといいアイデアがあるかも??
0057nobodyさん2006/06/27(火) 20:42:38ID:???
いや、だから、>>53 が言ったみたいに
Content-Type: application/octet-stream
か
Content-Type: application/x-download
とでもしてDLさせればいいんでない?
0058492006/06/27(火) 21:36:29ID:???
Content-Type: application/octet-stream
とか初見だったんで最初はよく分からんかったけど。

ファイル読み込み
↓
出力
↓
ファイル削除

で出来ますた!サンクスであります。

>>56
それとほぼ同じ形に収まった・・・2時間以上かけてだけどw
UPは特定の仲間内(?)の任意の誰か、
またはすでにあるログから情報を抽出加工したものを新規ファイルとして作成、
という何とも分かりにくい感じ。深く気にしないでね。

ところで、少し気になったんだけど、
>>53>>55>>56>>57
の言おうとしてる内容はほぼ同じって解釈で合ってるよね??
0059nobodyさん2006/06/27(火) 21:54:28ID:???
合ってる合ってる
0060562006/06/27(火) 22:01:59ID:???
>>57
なるほど、そういうmimeタイプがあるんですね。知らなかったです。
nameを指定するオプションとかも使えそうな感じ・・・(?
0061492006/06/27(火) 22:38:41ID:???
本題とちょっとズレるけど、
open直後にunlinkしても内容は保持されるみたいだね。
てか、UNIXなんかのテンポラリファイル使う場合は常套手段だとか。
>>56の例で言えば、
open fp,"downfile";
unlink "downfile";
print <fp>;
close fp;
って感じだな。
こうした方が、異常終了の際にファイルが消えてないってリスクが減るのでベターなわけだ。
0062nobodyさん2006/06/28(水) 00:23:47ID:???
>>61
お前ぶっとばすよ?
0063nobodyさん2006/06/28(水) 00:32:55ID:???
>>62
やめて
0064252006/06/28(水) 00:51:27ID:Ty2xiiJR
perl -c ではOKでエラーは見つからないです。
localでは、問題が見つからなかったのでサーバにアップロードしたらエラーが出まして
自分が考えれるところを確認しましたが、分からなくなってます。

ttp://hisazin-up.dyndns.org/up/src/11946.txt
再びいろいろといじっているせいで若干おかしなものも混ざっているかもしれませんが、
このような形です。
何の引継ぎなどがない場合には78行目の処理が行われて、
別ルーチンから投稿フォームが出力されます。
その投稿フォームから出力された場合に85行目からの処理が実行されて、問題がなければ
投稿OKかどうかの確認ページの出力
その確認ページからデータを引き継いだら143行目の処理に入るのですが、
143行目の処理の中で
ローカルでは問題なく結果が表示されるのですが、
サーバへアップするとどうしても500エラーとなってしまいます
0065nobodyさん2006/06/28(水) 01:54:52ID:???
こりゃまたけったいなスクリプトがきたぞ
0066nobodyさん2006/06/28(水) 02:00:58ID:???
☆
0067nobodyさん2006/06/28(水) 02:05:10ID:???
500エラーのときは鯖のエラーログ出せよ。

どうせヘッダ出力してないとかそういうのだろうけどな。
0068nobodyさん2006/06/28(水) 02:58:08ID:???
sub nothing_log{
nothing_log: <<<これは一体?
print "その記事はすでに削除されているので書き込みできません\n";
exit;
}
0069nobodyさん2006/06/28(水) 03:28:54ID:???
>>68
ラベル。
0070nobodyさん2006/06/28(水) 03:45:51ID:???
>>25
まず、require文とhtml_head("掲示板")だけで動くのか報告よろ。
どうせ晒すなら全部晒してもらうとこっちでもテストできるんだけど・・・
0071nobodyさん2006/06/28(水) 03:58:15ID:???
あ、わかった。143行目を print "\n\ntest\n"; で解決ですね。たぶん
あるいは html_head("掲示板"); print "test\n"; とか
82行目のifをスルーした場合どこにもヘッダを出力する
ルーチンがないので、普通にエラー・・・・・・・・・・・・
0072nobodyさん2006/06/28(水) 04:19:30ID:???
・・・
form_vew_make($pop_name,$pop_title,$pop_msg,$pop_icon,$pop_color,$pop_password,$pop_mail,$pop_home,$pop_thread);
こういう代入はあまりにも毒々しいので、$popなんとかは全部1つのリファレンスにまとめた方がいい。
あるいは%FORMをそのまま放り込んで、$pop系の変数を全部捨てた方がいい。
$lenなんとかはlenごときで変数作るなよと、wその程度だったら
必要な時にlen_count($なんとか)で取れば十分。
あと$view_flagのgoとbackは、goとbackを代入してるif文のところで
そのまま処理すればよいので不要
0073nobodyさん2006/06/28(水) 08:40:19ID:???
すみません。
BASIC認証するときのサーバの負荷について教えてください。
[ID]:[PASS]
というようなユーザファイルあると思うんですが、
何件ぐらい大丈夫なんでしょうか。
5万、10万件ぐらいは平気な感じでしょうか。
データベースでなく、ただのテキストファイルの検索って
どれぐらい大変なのかわかりません。

レンタルサーバじゃ実験できないし、
apacheのインストールの勉強も途中という
初心者ですので。
よろしくお願いします。
0074nobodyさん2006/06/28(水) 09:22:51ID:???
>>73
perlの話じゃないので、スレ違い。使ってる鯖(apacheなり
なんなり)のスレを探してそっちできけ。
0075nobodyさん2006/06/28(水) 09:34:48ID:???
板違い
0076nobodyさん2006/06/28(水) 10:04:15ID:???
>>74
73です。
たしかに、1をよく読んだら全然違ってました。
初心者、perlつながりで質問してしまいました。

旅に出ます。><
0077nobodyさん2006/06/28(水) 17:08:53ID:???
どこがperl繋がりなんだ…
0078nobodyさん2006/06/28(水) 17:13:29ID:???
perlで.htaccessなり.htpasswdに追加アッー!
0079nobodyさん2006/06/28(水) 17:38:43ID:JW7kjnCG
質問があるんですが「->」って何に使うんですか?
検索エンジンでは記号の検索ができないので、調べようにも調べられずに困っています・・・。
0080nobodyさん2006/06/28(水) 17:43:27ID:???
>>79
「perl アロー演算子」辺りでぐぐる
0081nobodyさん2006/06/28(水) 20:12:24ID:xzEYpxD8
デリファレンス
0082nobodyさん2006/06/29(木) 00:16:50ID:???
$hoge->[10] $hoge は配列へのリファレンス
$hoge->{piyo} $hoge はハッシュへのリファレンス
$hoge->()    $hoge はコードブロックへのリファレンス
$hoge->piyo() $hoge はオブジェクト(メソッドコール)

っていう理解でいいですか?
0083nobodyさん2006/06/29(木) 00:18:42ID:???
まぁ合ってる。
ただリファレンスじゃなくて
リファレンスの参照というか、デリファレンスというか
0084822006/06/29(木) 00:33:58ID:???
$hoge->[10] で要素が参照できるなら $hoge は配列へのリファレンス、というわけではないのでしょうか?
デリファレンスしてるのはアロー演算子ですよね?? 混乱してきた。。。
0085nobodyさん2006/06/29(木) 00:37:48ID:???
ごめん、82を読み違えてた。
合ってる。$hogeは配列へのリファレンス。

0086nobodyさん2006/06/30(金) 00:52:51ID:???
掲示板で無造作な大量リンクのカキコを排除したいと考えています。

  if( $txt にURLが5個以含まれる ){

    はじき処理

  }

の場合は、IF文のカッコ内にどのような文字を入れるとよろしいでしょうか。
よろしくお願いします。
0087nobodyさん2006/06/30(金) 01:03:46ID:???
$text =~ m!(http://.*){5,}!s
とかでいいんじゃね
0088nobodyさん2006/06/30(金) 01:31:11ID:???
>>87
なりました11111111
ありがとうございました   三 三 旦
0089nobodyさん2006/06/30(金) 10:18:19ID:???
perl 5.8.6 で XML::RSS を使って Podcast 情報を取得しようとしていますが、enclosure url が引っ張り出せません。XML::RSS では出来ないようなのですが、他に enclosure url が取得できるものはあるでしょうか。m(_ _)m
0090nobodyさん2006/06/30(金) 10:41:50ID:???
crypt関数について質問です。
#saltはランダムです
$crypted_pass = crypt($password, $salt);

$crypted_passは、$password='1111';$saltはランダムなので毎回違った
文字列になります。すごい疑問なんですが、これをBASIC認証のための
.htpasswdファイルに書き込むと、'1111'でも$crypted_passは毎回違う
文字列ができるのに、何回$crypted_passを作ってもBASIC認証の
ダイアログに'1111'を入れると認証されます。
すごいバカなので全然理解できないです。

わかりにくいとあれですので、やってみたいことを細くします。
フォームから入力されるパスワードを$FORM{'pass'}
.htpasswdファイルにすでに書いてあるパスワードを$pass_htpasswdとします。

パスワードが正しかったら〜するって言うことが目的なんです。
if( crypt($FORM{'pass'}, $salt) eq $pass_htpasswd){hoge処理;}
こういうことがしたい場合は、$saltを固定しないとperlでは
できないんでしょうか?固定するとこの処理で大丈夫みたいです。
ランダムだと毎回違う文字列が出てきてだめです。

サーバだとなんで、'1111'ってわかるんでしょうか。
perlでもなんか処理のしかたありますか。
ちょっと、長い文章で申し訳ないですが、よろしくお願いします。
0091nobodyさんNGNG
ヒント:crypted文字列の前から二文字はsalt
0092nobodyさん2006/06/30(金) 12:01:59ID:???
>>91
cryptの戻り値(digest)にはsaltの情報も含まれているのであとで確認したいときは
それをsaltとしてそのまま食わせればいいことになっている。

When verifying an existing digest string you should use the digest as the salt (like
"crypt($plain, $digest) eq $digest"). The SALT used to create the digest is visible as part of
the digest. This ensures crypt() will hash the new string with the same salt as the digest.
This allows your code to work with the standard crypt and with more exotic implementations. In
other words, do not assume anything about the returned string itself, or how many bytes in the
digest matter.

0093nobodyさん2006/06/30(金) 15:14:17ID:???
>>91
>>92
90です。
ありがとうございます。
できました!!!

saltといっしょだったんですね。
cryptだとパスワードそのまま、saltにできるんですね。
すごく便利です。
ありがとうございました。
0094nobodyさん2006/06/30(金) 15:22:58ID:???
なんか勘違いしてそうな文面だな。
0095nobodyさん2006/06/30(金) 16:17:19ID:???
            第三者                  「通信は傍受される」のがセキュリティの前提で
             ↓
     受信     ↓傍受   送信          この場合、パスワードが傍受されるから
サーバー←←←[パスワード]←←←クライアント     生でパスワードを送るのはダメ


            第三者                 パスワードからハッシュ関数で生成した
              ↓                   ダイジェストを送信すれば、傍受されても
     受信      ↓傍受   送信          ダイジェストからパスワードは復元できない
サーバー←←←[ダイジェスト]←←←クライアント    (できるけど、とてつもなく時間がかかる)ので安全

ダイジェストを受け取ったサーバーは、自分が持っているパスワードをダイジェスト化して
それと送られてきたダイジェストを比べる事で、パスワードが合っているか判断する
っていう理解でおk?
0096nobodyさん2006/06/30(金) 16:20:58ID:???
>>95
それだと、「ダイジェスト」を「パスワード」と読み替えたのと全く同じなのでよくない。
0097nobodyさん2006/06/30(金) 16:38:41ID:???
下手な図だが。要はパスワードの平文をサーバに保存しないのがcryptの一般的な目的かと

 パスワード入力 ランダムなサルト
      ↓    ↓
crypt($password, $salt);
 ↓              登録時
保存(ダイジェスト化されたパスワード)
 ├──────┐    照合時
 ↓            │
照合           │頭にくっついているサルトだけが
 ↑            ↓    自動で取り出される。
crypt($password, $salt);
     ↑     パスワードとサルトが同じであれば
 パスワード入力     出てくるダイジェストが同じものになる
0098nobodyさん2006/06/30(金) 16:45:56ID:???
なるほど。ダイジェストだけ保存しておけば、認証はできるのかぁ。
セキュリティは難しいです>< 結城たんのアリス本でも読もうかな・・・
0099nobodyさん2006/06/30(金) 17:07:50ID:???
>>98
たん付けとは浩に失礼だ。
0100nobodyさん2006/06/30(金) 17:12:00ID:???
>>94
90です
if( crypt($FORM{'pass'}, $pass_htpasswd) eq $pass_htpasswd){hoge処理;}
$saltの文字列が長いときは、crypt関数が、
頭から2文字saltを取ってきてくれて、.htpasswdに記録されている
パスワードをそのまま$saltに入れても大丈夫

っていうことかと思ったのですが。
違いましたでしょうか?
スクリプトは正常に動いてるみたいです。

よくわかりませんが、BASIC認証は通信を暗号化
しないとだめなんですよね。
たしか。
0101nobodyさん2006/06/30(金) 17:18:35ID:???
>>100 勉強してきたようだな。
>>93の
> saltといっしょだったんですね。
から>>100の意味は読み取れないぞ。
それに、書くなら、
crypt関数は$saltの先頭2文字をsaltとみなして計算するから、
とかするのが正しいだろう。

ロジックが重要なプログラムの世界で、言葉遣いぐらい、と思っているとひどい目に遭うぞ。
0102nobodyさんNGNG
ミルカさん萌え
0103nobodyさん2006/06/30(金) 17:50:56ID:???
正確には一概に頭二文字とはいえないな。ライブラリ依存。
POSIXやSUSv3の範囲で言えば確かにそうだけど、
拡張として$n$...$形式のsaltに対応している環境も結構ある。
ttp://www.gnu.org/software/libc/manual/html_node/crypt.html
ttp://www.freebsd.org/cgi/man.cgi?query=crypt&apropos=0&sektion=3&manpath=FreeBSD+6.1-RELEASE&format=html
0104nobodyさん2006/06/30(金) 18:21:42ID:u4Lu+yYC
メールアドレス:[email protected]
### メール投稿設定 ###
�@$tmail = '';# 投稿用メールアドレス
�A$mailhost = '';# 受信メールサーバー
�B$mailid = '';       # メールアドレス(@以下は入れないでください)

って言うのがあったんだけどそれぞれ何入れればいいんですか?
一応番号ふっときました
0105nobodyさん2006/06/30(金) 18:27:54ID:???
>>104
Perlうんぬん以前の問題だな・・・

PC初心者板マジオススメ
http://pc7.2ch.net/pcqa/
0106nobodyさん2006/06/30(金) 18:28:48ID:???
>>104
ここはスクリプトを「作る人」のためのスレだ。使う人はスレ違い。
作者に聞け。
0107nobodyさん2006/06/30(金) 19:33:30ID:???
作者も聞かれても困るけどなw
0108nobodyさん2006/07/01(土) 00:20:37ID:???
�@$tmail = '[email protected]';# 投稿用メールアドレス
�A$mailhost = 'pop.mail.yahoo.co.jp';# 受信メールサーバー
�B$mailid = 'info';       # メールアドレス(@以下は入れないでください)
とでもやっておけばいいんじゃないの?
シラネ
0109nobodyさん2006/07/01(土) 15:05:13ID:???
ページ移動させたいときに

print "Location: http://google.com/";, "\n\n";

ってやるけど、windowsのローカル+Apache+ActivePerl だと 500エラー返しちゃうんだよね…
eval でもエラーにならないんで、
Location: ができるかどうかって前もって判断することってできる?
0110nobodyさんNGNG
正常に飛びましたが何か?
0111nobodyさん2006/07/01(土) 15:50:23ID:???
>>110
マジでΣ
何かの設定違ってんのかなー。

>>109 なんで &quot; になってんのかわかんないけど。

まあ、ぐぐったら tok2 とか infoseek とかでも Location は 500 るっぽいんだけど、
それは手動で設定変更して HTML吐いての meta タグで飛ばしてた。
プログラム内で自動で判断できれば一番なんだけど、何か対策ないかねえ。
0112nobodyさん2006/07/01(土) 16:43:35ID:???
print "Status: 302 shine\n";
も一緒に吐くとどうなる?
0113nobodyさん2006/07/01(土) 16:44:34ID:???
こうだったorz
print "Status: 302 Shine Compact\n";
0114nobodyさん2006/07/01(土) 18:13:25ID:???
>>113
500だねぇ・・・。
動くとこでやってみたけど、何これ? マジック?
0115nobodyさん2006/07/01(土) 18:23:44ID:???
print "HTTP/1.1 301 Moved Permanently¥n";
こいつを出してからにするとどう?
0116nobodyさん2006/07/01(土) 18:52:35ID:???
>>115
おおおおお(*゜▽゜)

print "HTTP/1.1 301 Moved Permanently\n";
〜

だといかなかったけど、参考にぐぐって、

print "Status: 301 Moved Permanently\n";
print "Content-type: text/html\n";
print "Location: http://google.com/\n\n";

こうしてやったらいきました! すごい! ありがとう!

……っていうか、ひょっとして Content-type: ないからあかんかった……?(;´Д`)
動くとこはなくても動いたんだけどw
0117nobodyさん2006/07/01(土) 19:08:37ID:???
Content-Typeはどんなステータスでも必須だったような。。

>>115
それはnph-*なファイル名でないとあかんやん。
0118nobodyさん2006/07/01(土) 19:09:54ID:???
>>114
CGI/1.1仕様でちゃんと決まってますよ。
0119nobodyさん2006/07/01(土) 19:13:14ID:R0VHYefT
申し訳ないです。

鯖のインストール済モジュールが知りたくて、検索してたら↓の情報がありました。
ttp://antipop.gs/mt/2004/11/21/115534

ただこれを実行すると DBI など複数同一表示されるものがあるのですが、
これを重複をなくすにはどうすれば良いでしょうか?
0120ヽ(´ー`)ノ ◆.ogCuANUcE 2006/07/01(土) 20:57:42ID:???
use strict の後に my %c; を、for の後に grep { !$c{$_}++ } を入れるんだ。
0121nobodyさん2006/07/01(土) 21:38:28ID:???
>>99
お前は呼び捨てかよw
0122nobodyさん2006/07/01(土) 23:52:40ID:???
「9.56」みたいな、小数点付きの数字を画像表示させたいと考えているのですがよく分からず困っています。

小数点さえなければ
------------------------------------------------------
$cout = sprintf("%06d",$cout);

for($i = 0; $i < length($cout); $i++){
$no = substr($cnt,$i,1);
push(@image,"./img/$no.gif");
}

print "Content-type:image/gif\n\n";
binmode(STDOUT);
print &gifcat'gifcat(@image);
------------------------------------------------------
というコードで、数字を画像表示させられるというのは分かるのですが、
なにぶん小数点が含まれるとなると・・・・どうしたらよいか・・・・

ちなみに「img」ディレクトリに「0.gif〜9.gif」という数字の画像と
「point.gif」という小数点を表示する画像が入っています。

どうかよろしくお願いします orz
0123nobodyさん2006/07/02(日) 00:05:54ID:???
>>122
未だにperl4なのがアレだけど…。多分、以下の1行入れるだけでいける。

for($i = 0; $i < length($cout); $i++){
 $no = substr($cnt,$i,1);
 $no = 'point' if ($no eq '.'); ### この行を入れる ###
 push(@image,"./img/$no.gif");
}
01241222006/07/02(日) 00:29:28ID:???
>>123
え・・・>>122は入門書っぽい本を参考にして組んだのですが・・・
何かまずかったでしょうか・・・?

とりあえずありがとうございました orz
0125nobodyさん2006/07/02(日) 04:58:17ID:???
Image::Magickで「9.56」の画像を作ればいいんじゃね
01261192006/07/02(日) 13:06:22ID:???
>>120
ありがとうございました、希望の動作になりました。

Perl はコードが省略化されて読めなかったりするのですが、
119のリンク先では↓の部分が難解でした。もしよければ解説おねがいします。

print qq|<li><a href="http://search.cpan.org/search?module=$_";>$_</a></li>\n|
for sort
map {$_ =~ m/^.+?"Module" (.+?)$/}
qx/perldoc perllocal/;

# printの行は↓に変更、最後にセミコロンを付けるとエラー
# print "<li><a href=http://search.cpan.org/search?module=$_>;$_</a></li>\n"
# for sortの行は理解不能無理、こんなループ見たことない検索しても出てこない
# mapの処理自体は分かるが、左に代入先などがないので出力が分からん・・・
# qxは調べて分かった。でもどういう出力に・・・
0127nobodyさん2006/07/02(日) 13:35:34ID:???
後ろから読んでくと分かるはず。

qx: qxの実行結果を
map: map に通してモジュール名だけ抜く
sort: ↑をソートして
for: そのそれぞれについて(foreach)
print: print
01281192006/07/02(日) 14:16:29ID:???
>>127
ありがとうございます、↓やっと分かってきました。

use strict;
my %c;
my @qx = qx/perldoc perllocal/;
my @module = map {$_ =~ /^.+?"Module" (.+?)$/} @qx;
my @modlist = grep { !$c{$_}++ } @module;
@modlist = sort @modlist;
foreach (@modlist) { print "<li>$_</li>\n"; }
0129nobodyさん2006/07/02(日) 17:13:00ID:???
$_[0]って何だ?
エラーメッセージが一つしか表示されない。
もう一つ表示するはずなんだが・・・。

&error("ダメだ","ダメっす");
コレだと『ダメだ』しか表示されない・・・。
『ダメだ』と『ダメっす』をランダムってか表示させたいんだが
0130nobodyさん2006/07/02(日) 17:36:43ID:???
>$_[0]って何だ?
配列の一番はじめの要素
>&error("ダメだ","ダメっす");
サブルーチンに配列で引数渡してるところ
>コレだと『ダメだ』しか表示されない
アタリマエ
0131nobodyさんNGNG
sub error {
print $_[int(rand(scalar(@_)))];
}

我ながら酷いコードだな
0132nobodyさん2006/07/02(日) 18:36:42ID:n0vd3nFA
ちょっと行き詰ってしまったので質問させてください

今回UTF-8を使用しようと思いjcode.pmでエンコードしようとしたのですが
一部の文字列が文字化けすることに気づきました。

例)心霊

ちなみにエンコード方法は
Jcode::convert (\$value, 'utf8');
としているだけで特に怪しいことはしていないと思います

ちなみにそこを#でコメントアウトしてみると
フォームページ自体をUTF-8で書いているため
さきほどの「心霊」と言った文字列も問題なく表示されるわけですが
フォームページをEUC-JPなどにすると
当然のごとくEUC-8になってしまうため問題があります

何か私自身の書き方に問題があるのでしょうか?
それとも仕様なのでしょうか?
お手数をおかけして大変申し訳ありませんがご教示頂けると嬉しいです

よろしくお願い致します
0133nobodyさん2006/07/02(日) 18:53:53ID:???
129だが解決方法を教えてくれ
0134nobodyさん2006/07/02(日) 18:58:30ID:???
せめて sub error を晒せ。
いまんとこ解決というかそれは当たり前というか。
>>130 も書いている通りなんだが。
>>131 もなんか書いてるし。
それを参考にどうぞ。
0135nobodyさん2006/07/02(日) 19:00:42ID:???
>>131
配列の添え字は整数しかとらないんだし、
randの引数はスカラーコンテキストだからこれで良いじゃないか。
sub error { print $_[rand @_] }

>>132
何をしようとしているときに問題が発生するのかが良くわからんので、問題が発生するときの
・内部エンコーディング(UTF-8ならutf-8フラグはあるのかどうかも出来れば)
・出力/入力するエンコーディング
・どっちの方向に変換しようとしているのか
辺りを詳しく。

スクリプトの内部処理をUTF-8で行って、出力するページのエンコーディングを
EUC-JPにしようとしているわけ?勘では多分、使い方の間違いだ。
Jcode::convert(\$value, '変換先のエンコーディング', '元の文字列のエンコーディング');
ってやって見れ
01361322006/07/02(日) 19:09:39ID:n0vd3nFA
>>135
ごめんなさい、誤解させてしまうような書き方をしてしまいました

基本的には内部においてUTF-8で処理したいのです
eucやsjisに変換する気はありません

ただどんな文字コードでフォームから入力されても
UTF-8に変換したいために
Jcode::convert (\$value, 'utf8');
としています

# 現在のブラウザではフォーム入力ページがUTF-8なら
# UTF-8で文字コードを送信してくれるという話なので(どっかで聞きました)
# Jcode::convert (\$value, 'utf8');
# をしなくても実害はないといえば実害がないのですが
# 万が一sjisとかで送信してくるブラウザ等があった場合にも
# 対応したいと思い変換処理させています

ところでUTF-8フラグはEncodeモジュール以外でも必要なのでしょうか?
(今回の件で色々ぐぐっていたときUTF-8フラグというものについても読んだのですが
Jcodeモジュールを使う時にフラグ云々という話は出てこなかったので不要なのかと思っていました)

続きます
0137nobodyさん2006/07/02(日) 19:10:50ID:???
Jcode::convert (\$value, 'utf8');
を
jcode($value)->utf8();
にしてみたら?
自動判別が働いて正しく格納されるはず。

入力のエンコードを誤認してたらどうしようもないけどね
0138nobodyさん2006/07/02(日) 19:11:56ID:n0vd3nFA
入力された文字列を処理させる流れは以下のような感じです

sub decode {
my ($buffer, $key, $value);

if ($ENV{'REQUEST_METHOD'} eq "POST") {
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
$buffer = $ENV{'QUERY_STRING'};
}

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

$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

Jcode::convert (\$value, 'utf8');

$in{$name} = $value;
}
}
0139nobodyさん2006/07/02(日) 19:16:54ID:???
あの〜packしてる時点でスクリプトを書いている文字コードへ変換しているはずですが・・・

># 万が一sjisとかで送信してくるブラウザ等があった場合にも
># 対応したいと思い変換処理させています
そりゃおまいさんがどんなコンテンツを管理しているかによる。
UTF8で書かれたページからshiftjisで
しかもフォームデータをエンコードもせずにダイレクトで送ってくるブラウザ
使ってる奴なんて死ねばいいと思うよ
0140nobodyさん2006/07/02(日) 19:19:08ID:???
139の一行目はなんか激しい勘違いなので忘れてw
0141nobodyさん2006/07/02(日) 19:23:43ID:n0vd3nFA
>>137
jcode($value)->utf8();
にしてみたら上手く行ったかと思ったのですが
ためしにフォームページをEUC-JPにして入力してみると
入力された文字列はEUC-JPのまま出力されていました・・・

>>139
>しかもフォームデータをエンコードもせずにダイレクトで送ってくるブラウザ
>使ってる奴なんて死ねばいいと思うよ

もうちょっと正直に書きますと
ある分野のデータベースを作っているのですがその検索フォームを
「自分のサイトにつけたい人はどうぞ」
という風にしたいと考えているのです
ですのでその入力ページがeucもあればsjisもあるかと思うので
鯖側でUTF-8に変換したいなあと・・・

最後まで解決しなければその案は断念しますがw
0142nobodyさん2006/07/02(日) 19:47:20ID:???
>>138
切り分けができてないな。そんなに長いプログラムではどこで
間違ってるか特定できないだろ。

Jcode::convertを疑うのなら、4valueにこの値をいれて
Jcode::convertを呼んだらこれこれこうなったけど
期待している値はこれだというのを示さないと。
0143nobodyさん2006/07/02(日) 20:06:33ID:n0vd3nFA
>>142
えっと・・・このソースの大半は一般的な入力データ処理だと思いますが・・・
とりあえず>>132で書いた通り
Jcode::convert (\$value, 'utf8');
をコメントアウトすれば問題なく処理されます

一応文字化けした結果も載せておくと
「心霊」をUTF-8で記載されたページから入力すると
unpackされた値は「%E5%BF%83%E9%9C%8A」になりそれをpackして
Jcode::convert (\$value, 'utf8');
で変換すると「綽??」(← 文字化けしたもの)
となってしまうというわけです(当然期待している値は「心霊」です)

ちなみに「心」だけでも「霊」だけでも正常に出力されます
0144nobodyさん2006/07/02(日) 20:40:15ID:???
いやだから??とか文字化けしたとかじゃわかんないでしょ。
utf8フラグと文字コードのダンプぐらい示さないと。
0145nobodyさん2006/07/02(日) 20:48:13ID:???
ためしに
Jcode::convert (\$value, 'utf8', 'euc');
と
Jcode::convert (\$value, 'utf8', 'sjis');
ってやった結果も記してくれんかな
0146nobodyさん2006/07/02(日) 20:55:32ID:???
そもそも他人に使わせるなら日本語限定ではだめじゃん?
ttp://www.russky.net/article/list.asp?id=855
これは gb2312 だけど euc-kr にも日本語のひらがなが入っていたようないないような。
0147nobodyさん2006/07/02(日) 21:13:47ID:???
おおかたencode/decodeを適切にやってないと予想。

0148nobodyさん2006/07/02(日) 21:35:08ID:???
ああ、大体わかった
「綽??」ってのはUTF-8の文字列をEUC-JPとして見たときのものだ。

つまり変換自体には問題はなくて、結果を表示するページを
間違えてUTF-8じゃなくEUC-JPにしてしまっている、と。
0149nobodyさん2006/07/02(日) 21:47:43ID:pDw8h7zX
s/\x0D\x0A/\n/g;
tr/\x0D\x0A/\n\n/;
とかって、改行コードの統一処理はどのタイミングでやるもの?
何かファイルを読み込むごとに毎回するもの?
0150nobodyさん2006/07/02(日) 21:52:43ID:???
混在してるとごちゃごちゃするので、なるべく入り口近くで決めた形式に
統一しちゃうね。場合によっては無駄になることもあるけどわかりやさ
優先。
01511322006/07/02(日) 22:03:39ID:n0vd3nFA
>>144
>>143の??は実際には文字化けの□をもっと縦長にした感じのが出ています
ただここにコピペしたら?に変換されてしまったわけで

>>145
入力ページはUTF-8で記載されていますのでその上での結果です
>Jcode::convert (\$value, 'utf8', 'euc');
「綽??」
>Jcode::convert (\$value, 'utf8', 'sjis');
「蠢?怺」
ちなみに↑の例ですが入力ページをそれぞれeucおよびsjisに変えたら問題ありませんでした
今回の「心霊」のようにそれぞれの文字コードで別の問題ある文字がないとは限りませんが・・・

>>146
そうかもしれません

>>147
その可能性がないとは言えませんが私は適切にやってるつもりなのでなんとも

>>148
ブラウザでのエンコードはUTF-8になっていることを確認した上で見ています
なのでブラウザの問題ではなくむしろ下に書くように
jcode.pmモジュールがUTF-8をEUC-JPに誤読しているのかと・・・

つづく
■ このスレッドは過去ログ倉庫に格納されています