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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2009/09/03(木) 23:51:12ID:???
Perlのコーディングで困ってる人のスレです。

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

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

最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

お勧めサイトは >2 以降

前スレ http://pc11.2ch.net/test/read.cgi/php/1234752149/
0052nobodyさん2009/09/16(水) 11:56:01ID:???
ロックしてないし(この構造でロックしてもロックにならないけど)、
複数のプロセスが一度にアクセスして、ファイルが壊れてるとかなら考えられるけど。

まー、情報が少なすぎて、分からん。
0053nobodyさん2009/09/16(水) 12:03:46ID:???
キャッシュ表示してるだけじゃないの?
ランダムに変わる長さの文字列を表示させるようにしてみるか
IE なら CTRL+リロード、Firefox なら Shift+リロードしてみて
0054402009/09/16(水) 12:36:56ID:???
>>53
ランダムのヤツはもうやってあって、ちゃんとランダムに毎回変わりました。

windowsでactiveperl+apacheなんですが
activeperlとapacheはCDから本と同じバージョンだし、
httpd.confもCDからまんまコピーだし

もう何がなんだか
0055nobodyさん2009/09/16(水) 12:54:14ID:???
open(IN, "<./count.dat") or die "cannot open";
こうやって、ちゃんとファイルを開けてるかみるとか
0056nobodyさん2009/09/16(水) 13:02:45ID:???
ブラウザでのキャッシュ無視リロードはやったの?
複数提案があったら出来る限り全部試せよ
0057402009/09/16(水) 13:02:53ID:???
>>55

読み込みとして開くのはできてるようなんですけど

書き込みのときうまくいっていないようです

なぜかというとcount.datの中身を
11
にしとくと

ファイルを開いて値を読み込む
↓
インクリメント
↓
「あなたは……11番目の訪問者です。」

と表示されるからです。
ホント、なんででしょう。
0058402009/09/16(水) 13:06:24ID:???
まちがえました

「あなたは……12番目の訪問者です。」
ですね

>>56
やりました
0059nobodyさん2009/09/16(水) 13:08:15ID:???
エラーログ晒してみてよ
もうなんの情報もなしにこれでは辛い
0060402009/09/16(水) 13:12:53ID:???
>>59


apacheのerror.logのでいいんでしょうか?それともほかのperlとかのログでしょうか?
ごめんなさい 知識が少ないもので、わからないんです。
0061nobodyさん2009/09/16(水) 13:16:05ID:???
apacheのerror.log で OK
0062nobodyさん2009/09/16(水) 13:19:59ID:???

[Wed Sep 16 12:01:14 2009] [error] [client 127.0.0.1] File does not exist: C:/ApacheGroup/Apache2/htdocs/favicon.ico, referer: http://127.0.0.1/tendays/3-3.cgi
[Wed Sep 16 12:01:15 2009] [error] [client 127.0.0.1] File does not exist: C:/ApacheGroup/Apache2/htdocs/favicon.ico, referer: http://127.0.0.1/tendays/3-3.cgi
[Wed Sep 16 12:01:15 2009] [error] [client 127.0.0.1] File does not exist: C:/ApacheGroup/Apache2/htdocs/favicon.ico, referer: http://127.0.0.1/tendays/3-3.cgi
[Wed Sep 16 12:01:15 2009] [error] [client 127.0.0.1] File does not exist: C:/ApacheGroup/Apache2/htdocs/favicon.ico, referer: http://127.0.0.1/tendays/3-3.cgi
[Wed Sep 16 12:01:15 2009] [error] [client 127.0.0.1] File does not exist: C:/ApacheGroup/Apache2/htdocs/favicon.ico, referer: http://127.0.0.1/tendays/3-3.cgi

アイコンのエラーだけずっとです。count.datは引っかかりませんでした。
アンチウイルスソフトは止めてあるし、再起動は何度もしました。
0063nobodyさん2009/09/16(水) 13:24:08ID:???
use CGI::Carp qw(fatalsToBrowser);
use warnings;
use strict;

を2行目に追記してみて
0064402009/09/16(水) 13:26:06ID:???
Software error:
Global symbol "$count" requires explicit package name at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 9.
Global symbol "$count" requires explicit package name at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 12.
Global symbol "$count" requires explicit package name at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 16.
Global symbol "$count" requires explicit package name at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 20.
Execution of C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi aborted due to compilation errors.

For help, please send mail to the webmaster (webmaster@localhost), giving this error message and the time and date of the error.
0065nobodyさん2009/09/16(水) 13:34:24ID:???
my $countにしたらエラー無く実行されました。
0066402009/09/16(水) 13:39:00ID:???
ですが、ブラウザで実行してもカウンタが回りません
0067nobodyさん2009/09/16(水) 13:42:03ID:???
_count.datが生成されなかった時点でもう根本的におかしいんだが。
CDからコピーしたということは、何らかのファイルがまだ読み取り属性になっている可能性があるな。
Apacheをインストールした*フォルダ*のプロパティを開いて、読み取り属性に灰色の「レ」がついて無いか確認。
スクリプトを置いているフォルダのプロパティを開いて、同様に確認。

あとは>>55を参考に、出力側も
open(OUT, ">./count.dat") or die "cannot open";
にして試してくれ。

エラーログに痕跡がなかったら↓をenv.cgiとかの名前で実行して、結果を貼ってもらうくらいしか無いかな。
#! c:/perl/bin/perl
print "Content-type: text/plain\n\n";
foreach (sort keys (%ENV)) {
print "$_: $ENV{$_}\n";
}
0068402009/09/16(水) 14:07:10ID:???
open(OUT, ">./count.dat") or die "cannot open";
は

Software error:
cannot open at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 16.

For help, please send mail to the webmaster (webmaster@localhost), giving this error message and the time and date of the error.

となりました。

env.cgiの出力結果は

COMSPEC: C:\WINDOWS\system32\cmd.exe
DOCUMENT_ROOT: C:/ApacheGroup/Apache2/htdocs
GATEWAY_INTERFACE: CGI/1.1
HTTP_ACCEPT: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
HTTP_ACCEPT_CHARSET: iso-8859-1, utf-8, utf-16, *;q=0.1
HTTP_ACCEPT_ENCODING: deflate, gzip, x-gzip, identity, *;q=0
HTTP_ACCEPT_LANGUAGE: ja-JP,ja;q=0.9,en;q=0.8
HTTP_CONNECTION: Keep-Alive, TE
HTTP_HOST: 127.0.0.1
HTTP_REFERER: http://127.0.0.1/tendays/
HTTP_TE: deflate, gzip, chunked, identity, trailers
HTTP_USER_AGENT: Opera/9.80 (Windows NT 5.1; U; ja) Presto/2.2.15 Version/10.00
PATH: C:\Perl\bin\;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\;C:\Program Files\Borland\BDS\4.0\Bin;C:\WINDO
WS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\ATI Technologies\ATI.ACE\Core-Static;C:\tex\
bin;C:\gs\gs8.70\bin;C:\gs\gs8.70\lib;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Serv
er\100\DTS\Binn\;C:\Program Files\QuickTime\QTSystem\

次に続く
0069nobodyさん2009/09/16(水) 14:07:53ID:???
PATHEXT: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
QUERY_STRING:
REMOTE_ADDR: 127.0.0.1
REMOTE_PORT: 3349
REQUEST_METHOD: GET
REQUEST_URI: /tendays/env.cgi
SCRIPT_FILENAME: C:/ApacheGroup/Apache2/htdocs/tendays/env.cgi
SCRIPT_NAME: /tendays/env.cgi
SERVER_ADDR: 127.0.0.1
SERVER_ADMIN: webmaster@localhost
SERVER_NAME: 127.0.0.1
SERVER_PORT: 80
SERVER_PROTOCOL: HTTP/1.1
SERVER_SIGNATURE: <address>Apache/2.0.54 (Win32) Server at 127.0.0.1 Port 80</address>

SERVER_SOFTWARE: Apache/2.0.54 (Win32)
SYSTEMROOT: C:\WINDOWS
WINDIR: C:\WINDOWS

でした。
0070nobodyさん2009/09/16(水) 15:10:05ID:???
>cannot open at C:/ApacheGroup/Apache2/htdocs/tendays/3-3.cgi line 16.
やっぱり出力ファイルがopen出来てないな。
しかしそれが何故かというと、他のアプリにファイルハンドルを独占されているか、
書き込み禁止属性になっているとしか考えられないんだが。うーん・・・。

環境変数には問題は見当たらないね。
0071nobodyさん2009/09/16(水) 15:26:41ID:???
>>51でコマンドプロンプトからだとカウントアップされるということだから
ファイルが書込み禁止になっているわけじゃないんだよな。
あとはApacheの設定くらいか。
0072nobodyさん2009/09/16(水) 15:29:08ID:???
>>40
open(OUT, ">./count.dat") or die $!;
としてみて、失敗した原因を捕捉するのは鉄則。
openは失敗しても致命的エラーにならない(そのまま処理が進んでしまう)。
CD-ROMのファイルをコピーして使っているなら、read-only属性が付いているとしか考えられん。
読めもしないならパスの問題もあったかも知れんが。
0073nobodyさん2009/09/16(水) 21:51:49ID:???
コマンドプロンプトで
attrib -s -h -r count.dat
ってやって、データファイルの属性変更してみて
0074402009/09/16(水) 22:47:43ID:???
みなさん

apache2.0系の最新版を入れたら直りました。

いろいろとご迷惑をおかけし、またたくさんの返答ありがとうございました。
0075nobodyさん2009/09/16(水) 22:57:57ID:???
まぁApache側の何かがRead Onlyな所為なのだろうなとは思っていたよ
真相は闇の中だが
0076nobodyさん2009/09/18(金) 13:08:12ID:???
LWP で GET するときって、取得中のファイルってオンメモリなんですか?
もし一時ファイルに保存されているなら、その場所の調べ方と変更の仕方って提供されてるんでしょうか?

10分ぐらいググってみたけど見つかりませんでした
0077nobodyさん2009/09/18(金) 13:08:46ID:???
>>76
ソース読んだら?
0078nobodyさん2009/09/18(金) 18:38:19ID:???
>>76
一気読みもできるし、少しずつコールバック呼びながら読むこともできる。
0079nobodyさん2009/09/18(金) 18:41:26ID:???
>>77
> ソース読んだら?

その前にマニュアルを読め
0080nobodyさん2009/09/19(土) 13:40:04ID:???
Rubyだと配列の任意の位置から最後までを、[n..-1]で取り出せますが、Perlではどうするのでしょうか?

arr = [0, 1, 2, 3, 4]
p arr[2..-1] #=> [2, 3, 4]
0081nobodyさん2009/09/19(土) 14:16:15ID:weAFKNKD
perl CPAN モジュールのSutatistics::Suggestがインストールできなくて困っています。

ttp://search.cpan.org/~ihara/Statistics-Suggest-0.01/lib/Statistics/Suggest.pm
上記のサイトからlinux版ダウンロードして解凍し、以下の文を実行しようとしたのですが、

perl Makefile.PL [LIBS='-L/where/to/find/libsuggest.a -lsuggest']

解凍した中身に「Makefile.PL」がありません。また後ろに続く[LIBS='-L/where/to/find/libsuggest.a -lsuggest']もよく意味が分かりません。
よろしくお願いします。

<環境>
OS:Fedora9
0082nobodyさん2009/09/19(土) 14:40:29ID:???
>>80
http://0xcc.net/blog/archives/000043.html
0083nobodyさん2009/09/19(土) 14:47:11ID:???
>>81
> 解凍した中身に「Makefile.PL」がありません。

「Linux版」の意味が不明だが、いずれにせよ、Makefile.PLはある。

また後ろに続く[LIBS='-L/where/to/find/libsuggest.a -lsuggest']もよく意味が分かりません。

"/where/to/find/"をlibsuggest.aをインストールしたディレクトリに置き換える。
0084nobodyさん2009/09/19(土) 15:03:34ID:???
>>82
ありがとうございます。
すごく参考になるサイトです。

でも自分の質問に対する答えは見つからないような。。。
0085nobodyさん2009/09/19(土) 16:52:19ID:???
>>80
my @arr = (0, 1, 2, 3, 4);
print @arr[2..$#arr];

または

my $arr = [0, 1, 2, 3, 4];
print @{$arr}[2..$#{$arr}];
0086nobodyさん2009/09/19(土) 17:01:18ID:???
>>80
print @a[5 .. $#a];
0087nobodyさん2009/09/19(土) 17:07:19ID:???
>>85-86
�d
できました。
0088812009/09/19(土) 17:32:49ID:02Qx22rD
>>83
レスありがとうございます。win版等があったので・・・

「Makefile.PL」はありませんが、「Makefile」なら解凍した中にあります・・・
ttp://search.cpan.org/~ihara/Statistics-Suggest-0.01/
ここに、「Makefile.PL」があったので、これを利用しようと思います

[LIBS='-L/where/to/find/libsuggest.a -lsuggest']はこのまま実行しないで
自分の環境に合わせて変更する必要があるんですね。ありがとうございます

最後に「libsuggest.a」は、通常何処にあるのでしょうか?よろしくお願いします。
0089nobodyさん2009/09/19(土) 20:01:27ID:???
>>88
Linuxなんだろ?
find /usr -name libsuggest.a
で探せるだろ。最近は一瞬で全ファイルシステム探せるから便利だよな。
昔はこんなことしたら怒られる上に何十分もかかった。

っていうか
http://glaros.dtc.umn.edu/gkhome/suggest/download
から
suggest-1.0-linux.tar.gz
をダウンロードしたら、その中にlibsuggest.aがあるじゃん。これインスコすれば
いいんじゃねーの?README読んだらテスト方法書いてあるからテストしろよ。
テストは大事だからな。インスコ先は/usr/local/lib/辺りでいーだろ、で、

perl Makefile.PL [LIBS='-L/usr/local/lib/libsuggest.a -lsuggest']

こーだろ。
0090nobodyさん2009/09/20(日) 09:40:10ID:WC9uameU
他WEBの質問版でも書き込みさせて頂いておりますが、こちらでも質問させて頂きます
現在、初心者ながら、PerlでCSVファイルを使って簡易的なDBを作っています
その際、下記の方法でCSVファイルの部分修正していますが、うまくいきません><
申し訳ありませんが、お知恵をお借りできますでしょうか?
困っております(泣)

◆下記プログラム内容
 CSVを読み込み、一致する部分があればそこを修正し、新たなCSVとして書き出す

◆マスターDB(カンマ区切りのCSVファイルにて作成)
 ・DBは横230×縦max2000程度(現行は横200×縦100程度)
 ・先頭、横20までは日本語で、最大でも全角50文字程度(改行、カンマは事前に除外(置き換え)しています)
 ・その後は「1 or 空白」。(フラグが立っているか、いないかだけ)

◆発生する不具合?
 (1)修正箇所の後ろの2〜3行が、修正行の後ろにそのまま追加される(欠落する場合もあり)
 (2)DBの一番最後の最後の行に不明なデータが追加される
  例1:,,,,,1,,,,,,,,1,,,,,,,,1,,,,,,,,1,,,,,,,,1
  例2:,,,,
  例3:0行目がコピーされる
  例4:改行のみ
 (3)上記、(1),(2)は基本的に同時発生
 (4)上記、(1),(2)が毎回ではなく時々発生(と言うか、かなり頻繁に… 10回に8回程…)

〜長文のため、私のソースは↓に書きます〜
0091nobodyさん2009/09/20(日) 09:44:13ID:???
>>90
まずやること。

その1、マルチをやめる
その2、もっと簡潔に記載する
その3、もっと勉強する
0092902009/09/20(日) 09:45:53ID:WC9uameU
#読み込み、及び修正
open (write_db,"+<db.csv");
flock write_db,2;
$i=0;
while(<write_db>){
@master = split(/,/, $_);
if( $master[0] == $data[0] ) {
$master[1] = $FORM{'textfield62'};
〜略〜
$master[15] = $FORM{'textfield5'};
#修正前の”1”のフラグ情報をクリア
for( $m = 21 ; $m <= $#master ; $m++ ){
$master[$m]=""; }
#修正情報の入っている@dataに基づいて@masterを変更(新しいフラグを立てる)
for( $k = 8 ; $k < $end_num ; $k++ ){
$master[$data[$k]] = 1; }
}
$write_data[$i] = join(',',@master);
$i++;
}
seek write_db,0,0;
close (write_db);

#書き出し操作
open (OUT,"+<db.csv");
flock OUT,2;
foreach my $ii ( @write_data ){
print OUT $write_data[$ii]; }
seek OUT,0,0;
close (OUT);
0093nobodyさん2009/09/20(日) 10:11:43ID:???
>>92
それ、DBD::CSVでできるから。CSVファイルに対して

SELECT * FROM table WHERE id > 1 ORDER BY id

とかできちゃうから。なんでそんなもの作ってるのか謎すぎる。
0094nobodyさん2009/09/20(日) 10:36:14ID:???
デバッグという概念も失われつつある
0095902009/09/20(日) 10:49:27ID:WC9uameU
>>93
理由があり、DBD::CSVは使えませんでした。
今後はそれも視野に入れ行っていきたいと思いますが、
まずはDBD::CSVを使わない場合での解決を目指しております。

>>94
実行時に修正前データ、修正後データ、書き込みデータの表示を行い
データ内容の確認を行っておりますが、その時点では問題はありません。
(CSVファイルとして書き出され、それをエディタ等で見た場合にデータがおかしくなっております)
上記に加え、確認する方法もご指摘頂けると幸いです。
0096nobodyさん2009/09/20(日) 11:16:04ID:???
>>95
>まずはDBD::CSVを使わない場合での解決を目指しております。
間違った判断だな。
理由って大した理由じゃないだろ。言ってみろ。自分でやってみたいとかそんなんだろ。
絶対これ直すよりDBI::CSVの方が早い。

このままじゃ無理。全面書き直し。
コードに定数が入れるな。機能をモジュールに分けろ。Test::Moreでテストを書きまくれ。
0097nobodyさん2009/09/20(日) 12:09:18ID:???
> 理由って大した理由じゃないだろ。言ってみろ。自分でやってみたいとかそんなんだろ。
> 絶対これ直すよりDBI::CSVの方が早い。
自分でやることの大切さは早いとか遅いとか関係ない、分かってないな。
0098nobodyさん2009/09/20(日) 13:11:31ID:???
本日は、弊店ガラガラ
----------------------------------------------------------------------
0099nobodyさん2009/09/20(日) 13:15:31ID:???
>>97
一度検討したくらいだから早さが大事なんだろ。
まあ確かに最近の風潮として、大したコードでもないのに
useが10〜20行くらい並んでるの見ると萎えるな。
0100nobodyさん2009/09/20(日) 13:19:29ID:???
テキストファイルはテキスト中に文字を
挿入しようとしても挿入にはなりません
上書きされるのが正常動作です


意味不明な文字が現れるのは、日本語
2バイトのうち1バイト分が上書き
されてしまうので
0101nobodyさん2009/09/20(日) 17:35:24ID:???
環境はWindows、使ってるのはActivePerl、文字コードはCP932とエスパーしてみる。
しかし、%FORMが謎。

とりあえず、Text::CSV_XSを使ってみて。
0102nobodyさん2009/09/20(日) 18:40:24ID:???
DBIが入ってない連鯖で使いたいとかじゃないの理由って
0103nobodyさん2009/09/20(日) 23:49:07ID:???
突っ込みどころ満載だが、デバッグの初歩、use strictを使ってコーディング!
ていうか、わざわざ"+<"でopenしているのに書き込む前にcloseしたら意味ないし!
seek FH,0,0;をcloseの直前に書いても無駄だし!
以前のデータを置き換えるなら、書き込むときのopenは">"で開く。さもなくば、closeせず、truncateする。
でないと、書き込んだ@write_dataの各要素のバイト長の合計が、書き込む前の
db.csvのファイルサイズより少ないとき、その差のバイト長だけ、以前のデータの末尾が残る!
不具合ってそのせいじゃないの?
0104nobodyさん2009/09/21(月) 00:29:33ID:???
いつも大漁ですね。
0105nobodyさん2009/09/21(月) 00:43:00ID:???
マスターファイルを読む「だけ」の所から根気良くやるしかないでしょ。
モジュールで済ませられるところはモジュールを使うと。
秘密が多すぎて、ダメかも分からんが。

で、釣りなの?
0106nobodyさん2009/09/21(月) 00:47:23ID:???
釣りとか大漁とか言ってるのは2ch初心者か?
質問スレでそんなの気にするな。
0107nobodyさん2009/09/21(月) 16:03:31ID:???
perlの中からRスクリプトを実行するスクリプトを作ってます。
以下の様に、Rスクリプトを一時的にファイルに落としてそれを実行すれば上手くRを呼び出せます。
ここで、一時ファイルを作らずに$r_script_strを直接使う方法はあるのでしょうか?

my $r_script_str = sprintf << 'EORS'
cat("Hello, world!")
EORS
;

open my $r_script_fh, '>', "./tmp_r_script.r";
print $r_script_fh $r_script_str;
close $r_script_fh;

system "R --vanilla --slave < ./tmp_r_script.r";
0108nobodyさん2009/09/21(月) 16:13:55ID:???
>>107
openでRに食わせればいい。
01091072009/09/21(月) 16:44:53ID:???
>>108
早速のレスありがとうございます。
一時ファイルを作らずにできるようになりました。
0110nobodyさん2009/09/25(金) 09:36:36ID:wSkBdlIW
どなたか詳しい方教えて頂けませんか
perl+MySQLで
$table_data[0]の真偽で分岐後、else{}は期待通りの結果ですが、if(){}が接続エラーとなってしまいます。
ど素人のため完全にはまってしまって

$dbh = DBI -> connect ($dns, $username, $password)
or
&err;
$sth = $dbh->prepare( qq{ SELECT code FROM client WHERE so = "$so" });
$sth -> execute()
or &err;
@table_data = $sth -> fetchrow_array();
$sth -> finish();
if(!$table_data[0]){
$sth = $dbh->prepare( qq{ UPDATE client SET condition=1 WHERE so = "$so" });
$sth -> execute()
or &err;
}
else{ $sth = $dbh->prepare( qq{ UPDATE client INNER JOIN afdb2 ON afdb2.code = client.code
SET afdb2.fix=afdb2.fix+client.price*100,
afdb2.occur=afdb2.occur-client.price*100,
client.condition=1 WHERE client.so = "$so" });
$sth -> execute()
or &err;
}
$sth -> finish();
$dbh -> disconnect();
exit;

よろしくお願いします。
0111nobodyさん2009/09/26(土) 11:16:39ID:???
> if(){}が接続エラーとなってしまいます。

って何なの? &err となっている部分を

$dbh->errstr;

に変更して、エラーの中身をはれ。

> $sth = $dbh->prepare( qq{ SELECT code FROM client WHERE so = "$so" });

プレースホルダ使いな。
SQLインジェクションするよw
0112nobodyさん2009/09/28(月) 04:42:47ID:???
MENTAっていうフレームワーク使いたいんだけど、本家サイトが落ちてるみたい
最新版のリファレンス的なものが置いてあるサイトとかブログないかな
0113nobodyさん2009/09/28(月) 11:00:48ID:???
本家というかYappoさんとこのcodereposにあるんじゃないの?
0114nobodyさん2009/09/28(月) 19:26:50ID:MFzb2dw4
どなたか詳しい方お教えください。
メールフォームを作ろうとしています。

form部品の、checkboxとradioとselectは、
textとかtextareaと違って、未選択の場合にキーを送信しないのですが、
これを未選択時にも、値が空のキー送信するようにすることはできますか?

cgi.pmのparam()メソッドでキーと値を受け取っているのですが、
上記が未選択時に受け取れないために、メールフォームの確認画面で、
つじつまが合わなくなってます(配列を使って自動的に生成しているため)。

どうかよろしくお願いします。
0115nobodyさん2009/09/28(月) 19:51:52ID:???
送られてくるキーが分かってるんなら、そのキーを defined で確認すりゃいいだけじゃないの?
0116nobodyさん2009/09/28(月) 20:04:40ID:???
>>115
早速のレスありがとうございます。
キーは分かってるんですが、それを毎回(メールフォームの項目が変わるたびに)Perlに記述していくのは面倒なので、
自動的にできないかと思って、メールフォームを作り直してます。

しかし、未選択のradioとかcheckboxのキーが送信されないという、
思わぬところでつまづいてしまいました。
0117nobodyさん2009/09/28(月) 20:16:08ID:???
考え方が、根本的に違っている気がする。
0118nobodyさん2009/09/28(月) 20:42:32ID:???
>>116
Perlとは直接関係ないけどさ、そうゆう場合はフォームのHTMLで、
全てのradioとかcheckboxにデフォルトの項目作って
checked="checked" とかしとくんじゃないのかな。

ただ、逆の使い方するほうが一般的な気がする。
例えば、必ず入れないといけないcheckやradioをあえて空にしといて、
そこをcheckしないと次のステップに進めないようにするとか、
"規約に同意「する」「しない」"で、「しない」にデフォルトでcheck入れとくとか。

これで、ある程度だけど自動スクリプトやロボットなんかの連投や、
一般ユーザーのボタン連打(いや、ほんとにいるんだって、極たまにだけど)
とかで、不意に高負荷になったりしないで済むし、なによりユーザーに
ちゃんとした入力を促すほうが大事かと思うが・・・。
0119nobodyさん2009/09/28(月) 20:47:50ID:???
sendmailで送信した宛先不明のメールをfromに指定したアドレスに返信したいのですが、
どのように設定したらいいのでしょうか? サーバーはlolipopです。
01201142009/09/28(月) 20:52:28ID:???
レスありがとうございます。

>>117
そうかもしれませんね。

>>118
おっしゃられることは分かります。

しかし、デフォルトでcheckedは設定してますが、checkboxやmultipleなselectは、
チェックを外すことができるんです(radioを除く)。

チェックを外すと、キー自体が送信されないので、
(キーをPerlに直接明示しない場合は)Perlでエラーを吐き出すことすらでません(JavaScriptでは可能ですが)。

PerlからメールフォームのHTMLを読み込んで、
nameを上から順に抽出して配列に代入する方法しかないかもしれませんね。
01211142009/09/28(月) 21:02:56ID:???
最終的に何がやりたかったかと言うと、Perl内の記述を一切いじることなく、
HTMLを変えるだけでメールフォームが簡単に作れるものを作りたかったんです。

そのHTML内の項目を読み取って、自動的にエラー画面・確認画面・自動返信メールが生成される感じです。
必須項目とか再入力が必要な項目とかもHTMLのみの変更で完結できるものです。
0122nobodyさん2009/09/28(月) 21:47:25ID:???
色々フレームワークをあたれば、そんなのもあるんじゃないか。
普通はデータベースのテーブルからフォームを起こすと思うけど。
0123nobodyさん2009/09/28(月) 22:09:35ID:Abs+b0wT
BBSのcgiについて質問です
海外からの書き込みを拒否にしたいです
多分このファイルがアクセスチェックのファイルだと思うのですが…
↓のプログラムで国内のみを通すにはどういじったら良いのでしょうか?
まだまだ勉強中なので指導していただけないでしょうか
よろしくお願いいたします

次レスにプログラムです
0124nobodyさん2009/09/28(月) 22:11:47ID:???
(^ω^)
0125nobodyさん2009/09/28(月) 22:13:49ID:Abs+b0wT
すみません、長すぎると出たので斧にあげました

ttp://www1.axfc.net/uploader/File/so/31637
0126nobodyさん2009/09/29(火) 00:16:08ID:???
>>116
スレちの希ガス。
毎回記述が面倒といっても、毎回記述するしかないのでは。
条件設定をするファイルを外部txtデータに書いておくとか。コード本体は変えないで済むように。
HTML::Parserなどを使って、htmlを丸ごと読み込んで、どんな入力項目があるかを解析するプログラムを外部で作ったらいかが。
htmlの中に条件指定をすると、いくらでも改ざんできてしまう。PCに保存してソースを書き替えて送信するとかできる。HTTP_REFERRERで確認しようにもクライアント側でどうとでも名乗れる。

>>119
envelopeアドレスを指定したらよろしい。
sendmailコマンドなら-fアドレス、Net::SMTPなら$smtp->mail(アドレス);
Mail::Sendmailならsendmail(Sender=>アドレス)のキーを渡すとセットされるみたい。
0127nobodyさん2009/09/29(火) 01:44:13ID:l3KIzeZ6
>>120のスクリプトに関するポリシーが間違ってるに一票。

>>118
チェックボックス外されたらアウトだし、
checkboxでF5回避できるとか、脳内で書いてるだろ。

> ちゃんとした入力を促すほうが大事かと思うが・・・。

チェックボックスのチェックを外すのはちゃんとした入力です。
で、キーは帰ってきません。

>>126
つYAML/JSON

パーサなんか使わなくても
perl -pe 's/</\n</g' foo.html | grep -i '\<input' | perl -ne '/<(?:input|select|textarea) [^>]*?\s+name=([^ >]+)/i; $M=$1 ; $M =~ tr/"//d ; print "$M\n";'

とかで充分じゃね?

渡された値のキーに依存するのは気持ち悪いというのは同意。
0128nobodyさん2009/09/29(火) 01:47:48ID:???
あ、grepいらねーな。print "$M\n" if $1でいけるかな?脳内ですまん。
0129nobodyさん2009/09/29(火) 01:50:43ID:???
ついでにtr/'\''"//dだし。これ以上修正するのめんどいからあとは任せた(誰に?)
0130nobodyさん2009/09/29(火) 02:05:25ID:???
結局ヒマだから書き直した。うざくてすまん。

perl -ln074e '/(?:input|select|textarea) [^>]*?\s+name=([^ >]+)/i; $_=$1 ;tr/'\''"//d;print if $1' foo.html
0131nobodyさん2009/09/29(火) 04:08:59ID:???
その辺はHTML::Formで取れるよ。
0132nobodyさん2009/09/29(火) 12:39:33ID:???
Module を作るのも手かもね

$form = HTMLFrom->new('POST', './test.cgi');
$form->setfield('hidden', 'action', '1');
$form->setfield('checkbox', 'sel', '1000');
$form->setfield('checkbox', 'sel', '1500');

ってやって、
$form->printform;
で表示するとか。

で、受け取りのときには
$form にはキーが保存されてるようにして、それを見れば一目瞭然みたいな感じ。



HTML::From がそうなのかもしれないけどw
0133nobodyさん2009/09/29(火) 19:44:30ID:AG6/8zJV
質問です。
$hogeにいろいろ含まれる<input type="text" name="iroiro" />のiroiroを
$q->param($1)に置換したいんですが可能でしょうか?($1はいろいろ変わります)

※$q->param($1)には、そのnameのvalueが入ってます。

while ($hoge =~ s/<input.*?type=\"text.*?name=\"(.*?)\".*?\/>/$q->param($1)/s) {
}

こうやっても、当たり前ですが$q->param($1)が入ってるのでエラーになります。
でも、$value = $q->param($1)のようにしてから、その後の正規表現をどうすればいいのか分からないんです。
どうかお願いします。
0134nobodyさん2009/09/29(火) 20:00:59ID:AG6/8zJV
あ!すみません!できました!
while ($form =~ /<input.*?type=\"text.*?name=\"(.*?)\".*?\/>/s) {
$value = $q->param($1);
$form =~ s/<input.*?type=\"text.*?name=\"(.*?)\".*?\/>/$value/s;
}
0135nobodyさん2009/09/29(火) 20:09:10ID:???
>>133
$hoge =~ s|(<input.*?type=\"text.*?name=\")(.*?)(\".*?/>)|$1.$q->param($2).$3|egs;

- e (Eval) 修飾子 (modifier) を付けると、その中が「式」として解釈されます。
- g (Global) 修飾子 を付けると、何度でもマッチを繰り返します。
0136nobodyさん2009/09/30(水) 04:32:12ID:???
$qが気になるな。エスケープとかしとかなくていいのか。
0137nobodyさん2009/09/30(水) 12:15:20ID:???
>>136
つeオプション
0138nobodyさん2009/09/30(水) 16:57:25ID:???
ごめん、言葉が足りなかった。
$qがCGI.pmのオブジェクトだったら、XSS脆弱性に気をつけようってこと。
ただのお節介かも知れないけどさ。
0139nobodyさん2009/09/30(水) 19:03:47ID:???
ちょっとお尋ねします。

-環境
winXP IE8
AN HTTPD + perl 5.8.8 (active perl)
-----------
my $str = 'テスト';
print "Content-type: text/plain\n\n";
print $str;

IEの「ダウンロード出来ません」とかいうエラー発生
-----------
my $str = 'テスト';
print "Content-type: text/html\n\n";
print $str;

問題なし
-----------
もしかしてIE8ってtext/plain表示出来ないんでしょうか?
0140nobodyさん2009/09/30(水) 19:11:04ID:???
糞環境乙。
IE のせいにすれば解決すると思ってる?
0141nobodyさん2009/10/01(木) 04:28:26ID:???
AN HTTPD は棄てろ
0142nobodyさん2009/10/01(木) 09:22:24ID:???
いい加減Windows厨はAN HTTPDもActivePerlもゴミ箱に突っ込んで
CoLinux立てて環境作れ。サービス&自動起動にしてしまえば遠くにLinuxマシンが
あるのと全く区別がつかん。パフォーマンスもそっちのがずっと高い。
そろそろいい加減にしないと時代に取り残されるぞ。

ちなみに>>139のようなことで騒いでるやつが居たから見てやったら

Content-Type: text/plane

になってた。飛ぶ気か。
0143nobodyさん2009/10/01(木) 09:50:29ID:???
Windows環境でしか使わないしなあ。
0144nobodyさん2009/10/01(木) 10:58:18ID:???
>>139
ダウンロードしようとするのはIEの昔からの挙動だね。
確か512バイト未満はダウンロードするんじゃなかったかな。
リクエストするアドレスの最後にスラッシュをつければ回避できる。

IEは昔から問題を抱えてるブラウザだから、テストに使わない方がいい。
AN HTTPDも昔と変わってなければ問題を抱えてると思う。
設定が面倒だと思うだろうけど、Apache等で信頼性の高い環境を構築した方が
トータルで考えると楽だよ。
0145nobodyさん2009/10/01(木) 12:25:45ID:???
>>144
アドレスの最後にスラッシュ付けたら表示されました。
IEだと512バイト未満の不具合があるんですね。
Content-Type無視の方かなと思ってたんですが。

[無視できない]IEのContent-Type無視 − @IT
http://www.atmarkit.co.jp/fcoding/articles/webapp/02/webapp02a.html
2008/7/2 - Internet Explorer 8 のセキュリティ : 総合的な保護
http://msdn.microsoft.com/ja-jp/ie/dd218483.aspx
2008/9/3 - Internet Explorer 8 のセキュリティ Part VI: Beta 2 の更新項目
http://msdn.microsoft.com/ja-jp/ie/dd218497.aspx

AN HTTPDが古いっていうのも気になってたので
これを機にApache入れようと思います。
ありがとうございました。
0146nobodyさん2009/10/01(木) 12:28:42ID:???
IEって、昔、受け取ったデータの頭512バイトをちょんぎってしまう
バグがなかったっけか。あれの亜種かな?
0147nobodyさん2009/10/01(木) 12:44:02ID:???
$|=1
で解決出来たりねw
0148nobodyさん2009/10/01(木) 13:14:47ID:???
>>147
$|=1;
my $str = 'テスト';
print "Content-type: text/plain\n\n";
print $str;
$|=0;

これで使い方合ってますか?
これでもIEのエラーは変わりません。
Firefoxだと問題なく表示されます。
0149nobodyさん2009/10/01(木) 13:34:45ID:???
charset まで丁寧に指定してみては?
0150nobodyさん2009/10/01(木) 16:54:23ID:???
>>149
my $str = 'テスト';

#print "Content-type: text/html\n\n"; #OK
#print "Content-type: text/plain\n\n"; #NG
#print "Content-type: text/plain;charset=Shift_JIS\n\n"; #NG
print "Content-type: text/plain;charset=EUC-JP\n\n"; #NG

print $str;
#print "a" x 512; #NG
#print "a" x 1024; #NG
print "a" x 10240; #NG

charset指定しても変わらずです。
ついでに512バイト以上出力してもNGでした。
FirefoxはいずれもOK。
うちのIE周りがおかしいだけなんでしょうか?
0151nobodyさん2009/10/01(木) 18:10:20ID:???
>>150
my $str = 'テスト';
print "Content-type: text/plain; charset=Shift_JIS\n";
print "X-Content-Type-Options: nosniff\n\n";
print $str;

http://msdn.microsoft.com/ja-jp/ie/dd218497.aspx

IE8で、Content-typeに従わない機能が高性能化してるみたいだね。
Microsoftの製品だから、今度からは製造元のMicrosoftに聞いて欲しい。
IEに関わると不幸になるから。
■ このスレッドは過去ログ倉庫に格納されています