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

CGIだけどなんか質問ある Pert 5.01

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/03/03 12:49ID:673UxTI5
print"くだらない質問はここにかけや!";

0166nobodyさん02/03/05 23:03ID:???
>>165
後にある場合はvarsかsub;で先行宣言しておかないと。
0167nobodyさん02/03/05 23:07ID:???
そっか宣言しないとエラー出るね。ありがと>>166
0168お腹さん@名無しいっぱい。02/03/05 23:27ID:???
>161
呼んだ?
016975とか02/03/05 23:43ID:???
おおお!昨日はどうもでした!
>>161のとおりなんだけども!ウザいとか言われてへこむから、
なんか端的な解決策あったらお願いしますYO!!!!!!
0170お腹さん@名無しいっぱい。02/03/06 00:11ID:???
>169
そうさネー。もっとスクリプトを整理することサネー。
チョット仕様がわかりかねる部分があるケド、MODEがcomment,light,cellular の
3つがあってcommentモードは print "Location: "; exit; で終わってるのはどう
いう処理?
017175とか02/03/06 00:19ID:???
コメントモードは終わったら表示を更新するだけです。そうか言われてみれば
もっと簡潔な処理できますね。
でも、どうやらもっと別の要因の気がします。
今、フォームデコードする直前あたりからEUCに変換するまでをバイナリで
丹念に調べてます。
0172お腹さん@名無しいっぱい。02/03/06 00:25ID:???
>171
Location: でパラメータを渡さずにこのCGIを呼ぶならどれも実行されないような
気もするケド。。。最終的にLocation: http://xxxxxxx の指定を書くというこTO?
017375とか02/03/06 00:29ID:???
ああ、そうか。いや、実は秘密モードってのが実は通常モードで
引数なければそっちに行くんです。だから、Locationで飛ばさなくていいんですよね。
なんでそんなことしてたんだろう。
0174お腹さん@名無しいっぱい。02/03/06 00:32ID:???
パラメータチェックおよびエラー画面表示等が1つもないケド、必要ないの?
017575とか02/03/06 00:57ID:???
パ、パラメータチェック..うーん、いまいちよくわからんす。

昨日教わったフォームデータを受けてるところ、調べてみたら
同じアという文字をEUCとsjisで送信すると
EUCでは%8E%B1を受け取ってデコード直後から最後まで8Dになってます。
sjisでは%B1を受け取って最後までB1のまま。
&jcode'convert(*value, "euc",$form_code,"z");
とか
&jcode'h2z_sjis(*value);
って文法間違ってないですよね??
0176お腹さん@名無しいっぱい。02/03/06 00:59ID:???
;# URLデコード処理実行

if ($in{'mode'} eq "comment" && $in{'message'} ){
  commentモード処理;
  exit;
}

if ($in{'mode'} eq "light"){
  ligntモード処理;
  exit;
}

if ($in{'mode'} eq "cellular"){
  ligntモード処理;
  exit;
}

※ 現在、大まかに上の処理の流れになっているのでif文がそれぞれ独立していて、
  それぞれのブロックが終了したら exit; で処理が終了してしまう。つまり、
  2つのifブロックを実行することはありえないし、パラメータによってはどの
  ifブロックも実行しないでなにも返さないCGIになってしまい、スクリプトエラー
  になると思う。したがって、大枠としては以下のように書き替えたほうがいいの
  では?
;# URLデコード処理実行

if ($in{'mode'} eq "comment" && $in{'message'} ){
  commentモード処理;
}
elsif ($in{'mode'} eq "light"){
  ligntモード処理;
}
elsif ($in{'mode'} eq "cellular"){
  ligntモード処理;
}
else { デフォルト処理;}
017775とか02/03/06 01:02ID:???
なるほど。全く持ってそのとおりです。
0178お腹さん@名無しいっぱい。02/03/06 01:07ID:???
とりあえず、半角の全角変換はいまの時点でこだわる必要はないと思うし、
別に半角のままでも化けないかもわからないので、まず処理構造をスッキリ
スマートにさせたほうが分かり易くなると思う。
少し読み進めてみると、ファイルロックはしないようにしたみたいダケド、ロックファイル
の後始末(アンロック)などが残っているのでこれは削除したラ?
0179お腹さん@名無しいっぱい。02/03/06 01:10ID:???
あと、携帯には詳しくないが、たしかドコモあたりではヘッダに Content-length: を
付加しないと動かないとかとほほに書いてあったようなきがするケドドウ?
018075とか02/03/06 01:15ID:???
あ、ファイルロックしてます。昨日、ソースお見せするのに
関係なさそうだったのでカットしただけです。
デフォルト処理はif文無しなので、変なパラメータならデフォルトが実行されます。
これ、とほほさんのラウンジの構造そのものなんですが(笑)。
でも全部elsifで繋いだほうが後始末何度も書かなくて済むのでより簡潔ですね。
変更します。
018175とか02/03/06 01:17ID:???
>>179
おっとそれは未確認です。が、僕、学生でも家族でもないのにAUなんです。
追々ドコモでチェックしてみます。
0182お腹さん@名無しいっぱい。02/03/06 01:21ID:???
最初の行あたりの以下の部分って使ってなさそうだケド、もしかしてそのファイルロック
部分かなんかで使ってる?使ってなければ削除したりーナ!

$ENV{'TZ'} = "JST-9"; # Set timezone
@wdays = ( "sun", "mon", "tue", "wed", "thu", "fri", "sat", "sun" ); # Constant variables
018375とか02/03/06 01:27ID:???
あーファイルロックで使ってます。
全部elsifで繋ごうと思ったんですが、commentモードは終了後に掲示板に
戻らないとならないので別個のif文にしてその中でモードを変更するか
locationで飛ばさないとダメですよね??
0184お腹さん@名無しいっぱい。02/03/06 01:52ID:???
commentモード後に必ずLocation: で飛ばす仕様なら「デフォルト処理」に書くほうが
いいと思うケド、どのモードでもない場合(仕様がどうなのかわからないが)やcommonモード
でメッセージが空の場合などの対処も同時に「デフォルト処理」部分でしておく必要はあるネー。

;# URLデコード処理実行
;# ファイルロック実行
if ($in{'mode'} eq "comment" && $in{'message'} ){
  commentモード処理;
}
elsif ($in{'mode'} eq "light"){
  ligntモード処理;
}
elsif ($in{'mode'} eq "cellular"){
  ligntモード処理;
}

;# デフォルト処理;
018575とか02/03/06 02:03ID:???
結局、>>183の前者の方に変更しました。
表示部は必ず実行する、コメントするならしてから表示部を実行する。という感じ。
0186お腹さん@名無しいっぱい。02/03/06 02:14ID:???
だいたい ifブロック構造はまとまってきた?
018775とか02/03/06 02:18ID:???
はい。おかげさまで見やすくなりました。
0188お腹さん@名無しいっぱい。02/03/06 02:21ID:???
次は、URLデコード部分でR!
なぜか知らんがPOSTおよびGET送信を分けて書いてあるのでアル。
018975とか02/03/06 02:23ID:???
はい。だめですか
0190お腹さん@名無しいっぱい。02/03/06 02:26ID:???
分けて書く特別な意味があるならそうすべきだし、特に意味がなければまとめて
書くほうがよりコンパクトで分かりやすいソースにあるってなもんだ!!
019175とか02/03/06 02:37ID:???
どうやったら一つにできるのか考え中です..
0192お腹さん@名無しいっぱい。02/03/06 02:39ID:???
以下の1行でPOSTだろうがGETだろうが 変数 $_ にぶち込んだことになると思うが。

read(STDIN, $_, $ENV{'CONTENT_LENGTH'}) unless $_= $ENV{'QUERY_STRING'};
019375とか02/03/06 02:44ID:???
つまり、$QUERY{'〜'}と$FORM{'〜'}の二つに分けないで、
一つの配列に両方入れるということですか?
0194お腹さん@名無しいっぱい。02/03/06 02:46ID:???
ああ、それってわけてたんだァ。わけないとまずいことでも?
019575とか02/03/06 02:50ID:???
いえ、配列の添え字も重複してないんで、分けなくていいっちゃーいいかも、です。
ところで、192は意味がわかりません。unless、それ以外は..。
0196お腹さん@名無しいっぱい。02/03/06 02:51ID:???
POST送信の場合、$ENV{'QUERY_STRING'} に値がセットされることは
ないと思うが、これって思い違いカナ?
0197お腹さん@名無しいっぱい。02/03/06 02:56ID:???
192 で変数 $_ に「aaa=%a0%2e&bbb=esc」みたいなのが取得できたからつぎは&
で分割したそれぞれを更に=で分割してデコードをぶちかますから大枠は以下の
ようになるハズでアール。(チョット文字コード変換は置いといて)

for ( split('&') ){
nbsp; nbsp;($name, $_)= split('=');
nbsp; nbsp;tr/+/ /; s/%(..)/chr(hex($1))/eg; # URLデコード
nbsp; nbsp;$in{$name}= $_; # 値のセット
}
019875とか02/03/06 02:56ID:???
別ページからのリンクや、BBS内での過去レスへのリンクのURLに?mode=light&page=3
とかって入るんです。
0199お腹さん@名無しいっぱい。02/03/06 02:58ID:???
197はチョットインデントミス

for ( split('&') ){
   ($name, $_)= split('=');
   tr/+/ /; s/%(..)/chr(hex($1))/eg; # URLデコード
   $in{$name}= $_; # 値のセット
}
0200nobodyさん02/03/06 03:00ID:???
>196
<form action="hoge.cgi?foo" method="POST">
とかすると同時に送れたと思う。
0201お腹さん@名無しいっぱい。02/03/06 03:02ID:???
>200
なるホードネー! それじゃー新たな必殺技を考えるからしばしお待ちを...
0202お腹さん@名無しいっぱい。02/03/06 03:07ID:???
これでPOSTおよびGETの値を取得できるかナ!

read(STDIN, $_, $ENV{'CONTENT_LENGTH'});
$_.= "&$ENV{'QUERY_STRING'}";
020375とか02/03/06 03:08ID:???
おお、なるほど!それなら意味がわかりました!
0204お腹さん@名無しいっぱい。02/03/06 03:10ID:???
どうYO!これで1つのハッシュにまとめられそうな予感?
020575とか02/03/06 03:22ID:???
んー今のところうまく行ってないっす..
0206お腹さん@名無しいっぱい。02/03/06 03:27ID:???
わたしは日本語EUC文字コードでしかHTMLフォーム送信をしたことがないから
わからんケド、経験上EUCで送信したHTMLフォームから入力された値はEUCの
URLエンコードで返ってくるのでSJIS送信の場合は必ずSJISのURLエンコード
で返ってくるのかチョットまだ試したことがないから取得パラメータの文字コードの解析
は必要なのかどうか迷うところネー。
020775とか02/03/06 03:36ID:???
んーその前にEUC送信でつまづいてマス..
0208お腹さん@名無しいっぱい。02/03/06 03:39ID:???
URLデコードはできた?
この際、内部処理はすべてEUCで、HTML出力はすべてSJISにしては?
なにかできない理由あったッケ?
020975とか02/03/06 03:47ID:???
できました!!とりあえず、URLデコードとやらを簡潔にすることはできました。
全部SJISですか..。それが一番いいんですかね??文字化けしにくいですよね。
どっかの解説で、日本語使うならEUCだ!という知識を身に付けたので出力までEUCにしてただけです。
0210お腹さん@名無しいっぱい。02/03/06 03:50ID:???
確かにEUCを愛用しているわたしとしてはEUCがいちばん使いやすいし、
経験上文字化けしたことがないし、文字コード変換のプロセスも必要なくなるし、
いいことづくめだとは思っています。
021175とか02/03/06 03:58ID:???
そうですかー。僕の掲示板やたらと重いんで、sjis変換するの躊躇するんですが、
文字化けよりはいいかな。
ていうかEUCって文字化けしないんですか?
0212お腹さん@名無しいっぱい。02/03/06 04:02ID:???
EUC送信部分ってlightモードDA・YO・NE?
021375とか02/03/06 04:03ID:???
おっと、また問題発生!
さっきモードうんぬんを変更したせいで、
書き込み後のURLが?mode=commentのままになっている..
やっぱりLocationで飛ばしたほうがいいのかなあ。
021475とか02/03/06 04:04ID:???
lightモードとHeavyモードです(笑)
0215nobodyさん02/03/06 04:06ID:???
すみません。
foreach $line(@hoge_lines){
@超hoge=split(/<>/,$line);
&普通にhoge;
}
こういうのがありまして、
&普通にhogeというサブルーチンは
sub 普通にhoge{
名前:超hoge[0]
題名:超hoge[1]
}
となっているとします。
このルーチン内に別のログファイルの内容を読み込んでうまく組み込むにはどうすればよいのでしょうか?
0216お腹さん@名無しいっぱい。02/03/06 04:09ID:???
>213
GET送信ならURLに?name=value&.... がくっつく(Location: 等で飛ばさない限り)

>214
Heavyモードってファイルには無いネー。これが隠し?
021775とか02/03/06 04:14ID:???
>213はちょっと検討中です。
heavyが隠し(笑)。こっちは重いだけでいまのところ問題なしです。
0218nobodyさん02/03/06 04:18ID:???
>215
@hoge_linesとログファイルの書式,
読み込んで組み込む時の上手い下手の定義とかを書いて。
0219お腹さん@名無しいっぱい。02/03/06 04:19ID:???
>215
ネタかと思ったが...
0220nobodyさん02/03/06 04:24ID:???
この板,最近煽りが多いからたまにはマジレスもしとかんと(w
0221お腹さん@名無しいっぱい。02/03/06 04:34ID:???
>220
そうダネ。この板、最近ムネオが多いネ!
022275とか02/03/06 04:38ID:???
結局、Locationで飛ばしました。
なんか、mode=commentとか全部postで送ったら、URLは簡潔だけど挙動がおかしいんです。
書き込み後、更新ボタンを押すと、重複して書き込まれてしまいます。
022321502/03/06 04:45ID:???
>>218
@hoge_linesは
$name,$title
で
ログファイルの書式は
名前<>題名<>
こんな風です。

上手いはとにかくできでどんな形でも組み込めればおいしい。
下手は組み込みを失敗している状態のことでSU!


0224お腹さん@名無しいっぱい。02/03/06 04:49ID:???
いい忘れてたケド、昨日のjoin関数で繋げる部分は以下のように変えテーナ!

print OUT join($SEPA,"$yy年$mm月$dd日","$jj時$ff分$bb秒",$in{'from'},
&nbps;       $in{'message'}),"\n";
0225お腹さん@名無しいっぱい。02/03/06 04:51ID:???
また、インデントしくじったーゼ!
224の &nbps; 部分はインデントミスさー
022675とか02/03/06 04:55ID:???
あーはいはい。すでにそのような感じに変えてありまっす。
あと、splitのほう、^Kは\^Kと書かないとだめでした。
ちなみに、なぜ^Kなんでしょう??
takakura^kenさんからの書き込みあったらマズイ!
0227お腹さん@名無しいっぱい。02/03/06 04:57ID:???
これもまた説明不足だったーネ。
これはコントロール文字のつもりだったので以下のように書き換えてみて、

$SEPA= "\x0b"; # セパレート文字(コントロール文字^K)
0228nobodyさん02/03/06 05:06ID:???
>>223
sub 普通にhoge{
 名前:超hoge[0]
 題名:超hoge[1]
 特別なhuga;
}
sub 特別なhuga{
 open LOGFILE, "logfile.dat";
 while (<LOGFILE>) {
  push @LOG, sub { {name=>$_[0],title=>$_[1]} }->(split /<>/);
 }
 close LOGFILE;
}
#$LOG[0]->{name}
022975とか02/03/06 05:09ID:???
なるほど、そうでしたか。なんか特殊なものなんだろうなあと思って調べたんですが、
^Kという文字列は僕のしょぼい検索に引っかかりませんでした..。
無知でお恥ずかしいです..
0230お腹さん@名無しいっぱい。02/03/06 05:12ID:???
まあ、フリーのCGIなどではセパレート文字に <> などというものを使って
る人がおおいけど、これだと2バイトになってしまうから、敢えて1バイトの
コントロール文字を使うという心意気みたいなもので、テキストデータを処理
する際の手筋ダーネ!
023175とか02/03/06 05:19ID:???
なるほどです。
ところで、昨日教わったやり方だとデータファイルに<br>が入ってましたが、
これを例にならって^Rという勝手な区切り文字に変えてしまったんですが、
\x0bと同時に使って区別できる区切り文字ってありますか?
0232お腹さん@名無しいっぱい。02/03/06 05:22ID:???
そうネー。\x1b なんかはお手ごろかと。
\x1b ESC文字(コントロール文字^[)
023375とか02/03/06 05:31ID:???
あ、それは\eのことですよね!僕のしょぼい検索にもひっかかりました。
ありがとうございます。

さて、そろそろ寝ます..最近、仕事中にしか寝てないんです(!)
2夜に渡って大変お世話になりました。どうもありがとうございました。
とりあえず明日全部sjis変換を試してみます..。
023422302/03/06 05:48ID:???
ちょっと形を変えて組み込めたんですが、
logfile.datの方から読み込んだ名前の数をカウントして
もう一つの方から読み込んだ名前の横に表示しようとすると、
1に対する文句の数 2
2に対する文句の数 3
3に対する文句の数 5
と1に対する文句の数にそのまま+されていってしまいます。

これはどうやれば解決できるのでしょうか?


023522302/03/06 05:50ID:???
と1に対する文句の数にそのまま+されていってしまいます。×
と1に対する文句の数にそのまま+されていってしまいます。文句の数がね○
0236nobodyさん02/03/06 05:57ID:???
>234
sub 特別なhuga{
 @LOG = ();
〜以下略〜
0237nobodyさん02/03/06 07:01ID:CkyOD57T
>>236
もっと詳しく書いてやれYO!
0238nobodyさん02/03/06 10:32ID:CkyOD57T
早くしろよ。
0239ぷうすけ02/03/06 11:05ID:qVBo2uea
mkdirに関する質問です。よろしくお願いします。

  $ret=mkdir($fname,0777);

 perlのcgiプログラム内にて、ディレクトリを上記の方法で作成して、その
中にデータファイルを作成する、というようなことをやろうとしています。
Webブラウザからのアクセスにより、上記の文は実行され、ディレクトリは作
成されます。$retには成功の1が返っていますが、実際のパーミッションは
755となっています。これは、サーバの設定のせいなのでしょうか?または、
なにかプログラム的に対策が取れますか?なお、cgiの置いてあるディレクト
リのパーミッションは777になっています。
0240nobodyさん02/03/06 13:41ID:???
>>239
多分サーバーの設定だろう。
詳しくは俺もよく知らんが、perldoc -f umask が参考になるかもしれない。

等と適当な事を逝ってみる。
0241nobodyさん02/03/06 14:34ID:???
タブ区切りテキストの read.txt を読み、
ユーザーの入力を格納した %hoge と %foo で5,6列目を上書きし、
write.txtに保存したいです。
以下のように配列 @temp を一時利用したコードを書いたところ、
\tでjoinしたにも関わらず、タブ文字でなく「\t」を区切り文字に連結されました。
つまり、
print "@temp[0]\\t@temp[1]\\t@temp[2]\\t 〜 @temp[8]\\t\\n";
を実行した時と同じ結果になりました。
望む結果を得るにはどうしたらいいのでしょうか?

$counter=0;
open READ, "read.txt";
open WRITE, "+>write.txt";
while ($input = <READ>){
$counter++;
@temp = split (/\t/,$input);
@temp[5] = $hoge{$counter};
@temp[6] = $foo{$counter};
print WRITE join('\t',@temp) ;
}
close READ;
close WRITE;
0242nobodyさん02/03/06 14:42ID:???
>241
'\t'
"\t"
この二つの違いはわかるかい?
024324202/03/06 14:50ID:???
いや、わかんないです。
てかそれだけヒントをもらえれば自分で調べます。
0244nobodyさん02/03/06 14:56ID:???
>243
君は241だろ。(w
まぁ、がんばれ。
頑張って無理だったらここを見ろ。
ttp://tohoho.wakusei.ne.jp/wwwperl1.htm#String
ttp://tohoho.wakusei.ne.jp/wwwperl1.htm#Esc
024524302/03/06 18:46ID:???
はぅん。こりゃ失敬。&さんくす。
024675とか02/03/07 00:36ID:???
YO-YOのお方、今日もいるかな?文字化けの件、解決しました!!
&jcode::convert(\$value,"euc","","z");
これが動作してませんでした。第3引数がダメなようですが、何故でしょう??
それから、sjis用対策をいろいろ教わりましたが、例えば、発言者名が全部半角カナだと
getcodeの返り値がundefなので文字化け対策の部分は全部素通りしてたのでした。
実際携帯から書き込む人は何故か名前を全部半角カナで書く人が多いし、
本文も全部半角カナで書かれても困るので、フォームから漢字一文字をこっそり送って
その漢字コードに全部合わせることにしました。
若干不明な点を残しつつも文字化けにおびえる日々からは開放されました..。
0247nobodyさん02/03/07 06:17ID:WTUe3Qf1
age
0248ぷうすけ02/03/07 17:26ID:+Mtxnc4D
  <form action='./hoge.cgi' method='GET'>
  <input type=password name='pass' size=8 maxlength=8>
  <input type=submit name='button' value='認証'>
  <input type=hidden name='data' value='hoge'>
  </form>

perlのCGIにて、このようなHTMLを出力して、パスワードを
入力させようとしています。テストはWin2000 + IE5.5です。
パスワード用のテキストボックスにパスワードを入力して、
「認証」ボタンをマウスでクリックすると、正しく3つの要素が
QUERYとして送信されます。しかし、キーボードでEnterを押したり、
スペースバーでボタンを押したような場合、
name='button' value='認証'
の情報が、まったく送信されません。どうしてこのようなことに
なるのでしょうか?

最後に、ありがとうございました。>240さん
助かりました。

0249nobodyさん02/03/07 17:31ID:???
>248
認証を押してないから。
0250ぷうすけ02/03/07 18:08ID:+Mtxnc4D
>249
押したYO!!
0251nobodyさん02/03/07 18:19ID:???
マウスボタンから指紋を検出してます。
0252nobodyさん02/03/07 20:08ID:???
>248
submitタイプにname属性はありません。
つーか、パスワードをGETで送るな。
0253nobodyさん02/03/07 20:33ID:???
>>252
あるが?
0254nobodyさん02/03/07 20:35ID:???
>>252
>submitタイプにname属性はありません。
付けちゃいかんって事は無かったと思うが。
0255nobodyさん02/03/07 20:48ID:???
>248
俺はWin2k+IE5.5SP2でちゃんと送れる。
マウスクリック、スペースキー、エンターキー全て正常に送れた。
0256nobodyさん02/03/07 21:01ID:???
なんかこの板、おそろしく人いないんですけど。
0257nobodyさん02/03/07 23:26ID:???
んな、いまさら・・・・
0258nobodyさん02/03/07 23:51ID:???
>>248
やってみたらテキストフィールドでのEnterだけ入らなかった。
スペースでもEnterでも、ボタンを押せば送られる、という事かな。
ついでに、<input type="button" name="button" value="認証"> だと何やっても送られなかった。
仕様なのかな。
025925802/03/07 23:53ID:???
<input type="button" name="button" value="認証" onClick="forms[0].submit()">
でした。
0260nobodyさん02/03/08 00:57ID:???
普通に鯖においてあるcgiの中身は何とかして見れないもんですかね?
0261nobodyさん02/03/08 01:13ID:???
>260
板違い
0262nobodyさん02/03/08 09:05ID:???
フォームから読み込んだ"文字列"を”%95%B6%8E%9A%97%F1”のように変換するにはどうすればいいのでしょうか?
0263nobodyさん02/03/08 09:20ID:???
>>262
受け取った時点で既にそうなってないか???
0264相撲車02/03/08 09:39ID:ol/NmE/5
telnetで自分のプロバの自分のいつも使ってるメール鯖にアクセスしてメール送る
CGIをperlで書いて、実験には成功したけど、これ設置したら不正アクセス禁止法に
触れますか?
取り合えず、プロバの契約内容には言及してなかったんだけど。
0265nobodyさん02/03/08 09:43ID:???
>>264
法律勉強しな。

一応それはsendmailで第三者中継させるのと大して変わらないね。

後、一般に自分のSMTPのアカウント晒して大丈夫なのか?と。
■ このスレッドは過去ログ倉庫に格納されています