☆ショッピングカートのCGIを作りたい!Perlで☆ (517レス)
前次1-
抽出解除 レス栞

リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
297
(5): 259 [sage] 02/02/07 15:02 ID:??? AAS
>296

open (READ,$filename);
 @data = <READ>;
close (READ);
#@dataに対して必要な処理
open (WRITE,">$filename");
 print WRITE @data;
close (WRITE);

式でやると、.datの件数が増えると負荷もかかるしメモリも喰う。
これは鯖屋さんに嫌われる。(警告が来たり、いきなり垢止められたりする)

open (READ,$filename);
open (WRITE,">$tempfile");
 while($line = <READ>){
  #$lineに対して必要な処理
  print WRITE $line;
 };
close (WRITE);
close (READ);
rename ($tempfile, filename);

式でやるなら、1セッション中に(検索と在庫デクリメント程度であれば)
複数回処理かけても大した負荷(プロセス時間)にはならないし、メモリも
喰わない。この方式で数百〜1万件(行)程度の処理しつつHTMLを吐かせる
CGIを一般の複数件のレン鯖に置いているけれど、苦情は来たことがないぞ。

この場合、.datはTABまたはSPACE区切りテキストがいいな。
一般配布のCGIにはカンマ区切りが多いけど、UNIX育ちのPerlのsplitは/\t/
や/\s+/に対し最適化されているから、行数が大きくなったときの処理時間の
差は結構馬鹿にならない。

カンマ区切りだと例外処理がウザい(書き込み時にデータにカンマがないか
チェックするか、Excelなcsvにすべくクオート処理せねばならん。後者の場
合、単純にsplit出来なくなる)しね。

プチECとしてはデータ内に半角スペースも含まれるだろうから、TAB区切りが
一番いいだろう。
330
(1): 297 [sage] 02/02/11 23:52 ID:??? AAS
そうか、上手く逝ったか。漏れこのスレ、検証してないやつばっか(297とか^^;)
書いてるから、ちょっと心配してるんだな。

> で変数が$_に入ってるってのがすっかり頭から飛んでました・・
慣れると便利なんだよ、デフォルト変数$_。
はまると怖いけどね。

で、正規表現検索は相手が文字列でも
if ($price =~ /\D/)・・・
だよ。
333: 297 [sage] 02/02/12 00:02 ID:??? AAS
>>330
うわ、とっくに話題が過ぎ去ってやがる。リフレ忘れた。鬱打

&jcode::tr(\$price, '0-9', '0-9'); #全角数字を半角に変換
if ($price !~ /0-9/){
  print "価格はカンマ無しの半角数字で入力してください";
}
あたりではどうかな?
349: 297 [sage] 02/02/13 12:22 ID:??? AAS
@files=glob "$dir/*.dat"; # $dirはディレクトリ名。*.datのlistを得る
foreach $file(@files){
 open FILE,$file or &error;
 while(<FILE>){
 my($no, $hinmei, $zaiko・・・) = split /\t/; #左辺のmyのリストは適当に
 $zaiko{"$file::$hinmei"} = $zaiko;
 }
 close FILE;
}
とかやって%zaiko{"ファイル名::品名"}(%zaiko{"ファイル名::商品番号"}?)に
代入して、%zaikoに対しデクリメント。
>>347さんの言うとおりhashならサーチ用にループしなくてイイからね。
で、

foreach $file(@files){
 open FILE,$file or &error;
 open TMP,">$temp" or &error;
 while(<FILE>){
 my(@dummy) = split /\t/;
  @dummy[2] = $zaiko{"$file::$hinmei"} if exists $zaiko{"$file::$hinmei"}; #$dummy[2]は適宜変更
 print TMP @dummy;
 }
 close FILE;
 close TMP;
 rename $temp,$file;
}

とかやって戻してやるってのはどうかな?

あ、ここまでやって思いついたが、カートの中身を
%cart{ファイル名::商品名}=注文数
ってハッシュにして、後者の書き戻しループで在庫チェックさせればイッパツだ。
そのほうがイイや。速いし。
350
(1): 297 [sage] 02/02/13 18:52 ID:??? AAS
えーと、ちょっとヒマがあったんで上の追記を。

カートの中身を
$cart{ファイル名::商品名}=注文数 (注文がない場合は0でなくハッシュを生成しない)
ってハッシュにしてあるとして、

@files=glob "$dir/*.dat";
foreach $file(@files){
 open FILE,$file or &error;
 open TMP,">$temp" or &error;
 while(<FILE>){
  my(@data) = split /\t/;
  my $key = "$file::$data[2]"; # $data[2]は商品名ね
  if (exists $cart{$key}){
   if ($data[1] < $cart{$key}){ #$dummy[1]は在庫
    print "$data[2]は在庫が不足しています";
   }else{
    $data[1] -= $cart{$key};
   }
  }
  print TMP @data;
 }
 close FILE;
 close TMP;
 rename $temp,$file;
}

で、読み出し→在庫チェック→在庫デクリメント→書き戻し
が1回で終わると思うんだな。

まあ例によって書きなぐりだから、globでファイルリストを取り出し、
cartをexistsで調べて在庫チェックとデクリメント処理する、
という流れだけ理解してもらえれば。
354: 297 [sage] 02/02/15 01:39 ID:??? AAS
おお、自力で実装できたか。ガンガン腕を上げていますね。
あとは欲張って機能拡張しすぎてスパゲッティにならんようにね。

statで得られるのはtimeとおなじ*1970年からの*通算秒だよ。
最終更新からの経過だけ調べるだけなら、ファイルテスト演算子-Mで
最終更新からの*経過日数*が得られるよ。
foreach(glob("./cart/*.dat")){
 unlink if -M $_ > $time; # $timeは日数、0.5なら12時間
}
とか。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.024s