CGIについての質問です。以下は登録者に誕生日の前月28日にメールを配信するCGIの一部です。これを誕生日の当月25日に配信するにはどこを修正すればよいでしょうか?お力をお借りできれば幸いです。


($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time + ($timediff * 60 * 60));
$mon++;
#if ($mon < 10) { $mon = "0$mon"; }
#if ($mday < 10) { $mday = "0$mday"; }
$tday = "$mon/$mday";
$tday2 = "$mon月$mday日";

open (DATA,"$datefile");
$setday = <DATA>;
($mondata,$daydata,) = split(/\,/,$setday);
$day= "$mondata/$daydata";
close (DATA);

if ($day eq "$tday") {
open (DATA,">$datefile");
flock(DATA,2);
$mondata++;
if($mondata eq "13"){$mondata = 1;}
$regday="$mondata\,$daydata\,";
print DATA $regday;
close (DATA);
flock(DATA,8);
&sub1;
}

print "Content-type: image/gif\n\nGIF89a\1\0\1\0\200\0\0\0\0\0\0\0\0!\371\4\1\0\0\0\0,\0\0\0\0\1\0\1\0\0\2\2D\1\0\n";

exit;


sub sub1{
open(DF,"$mailcontents");
@DATAM = <DF>;
close(DF);
foreach $linem (@DATAM) {
$mailtext ="$mailtext$linem";
}
open (DB,"$database");
@DATA = <DB>;
close(DB);
foreach $line (@DATA) {
($name,$email,$birth1,$birth2,) = split(/\,/,$line);
if ($mondata eq "$birth1") {
&mailcheck;
if ($errorh eq "0") {&sub2;}
}
}
&sub3;
}

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2007/09/07 22:33:42
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答4件)

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント100pt

実際の期間を決めているのは提示されたコード外にある部分だと思います。

   localtime(time + ($timediff * 60 * 60));

  $datefile 内の DATA

を比較して同じだったら処理をするようになっているので、$timediff [時間] がキーかと思います。


ただ28日というのは、このコードだけではできないように思うのですが、その機能は動いているのでしょうか。

($timediff が変化しながらこの処理が呼ばれていればできなくもないとは思いますが。)


それから確認ですが、誕生日の当月25日ということは誕生日が過ぎてから送られるという仕様でいいのでしょうか。

id:icta

500文字の制限があるため全てを記載できませんでした。誕生日の当月25日に送る仕様で間違いありません。以下が全CGIです。

CGI

----

require './jcode.pl';

require './conf/conf.pl';

$datefile = "./monthdate.txt";

$mailcontents = './conf/monthmail.txt';


($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time + ($timediff * 60 * 60));

$mon++;

#if ($mon < 10) { $mon = "0$mon"; }

#if ($mday < 10) { $mday = "0$mday"; }

$tday = "$mon/$mday";

$tday2 = "$mon月$mday日";

open (DATA,"$datefile");

$setday = <DATA>;

($mondata,$daydata,) = split(/\,/,$setday);

$day= "$mondata/$daydata";

close (DATA);

if ($day eq "$tday") {

open (DATA,">$datefile");

flock(DATA,2);

$mondata++;

if($mondata eq "13"){$mondata = 1;}

$regday="$mondata\,$daydata\,";

print DATA $regday;

close (DATA);

flock(DATA,8);

&sub1;

}

print "Content-type: image/gif\n\nGIF89a\1\0\1\0\200\0\0\0\0\0\0\0\0!\371\4\1\0\0\0\0,\0\0\0\0\1\0\1\0\0\2\2D\1\0\n";

exit;


sub sub1{

open(DF,"$mailcontents");

@DATAM = <DF>;

close(DF);

foreach $linem (@DATAM) {

$mailtext ="$mailtext$linem";

}

open (DB,"$database");

@DATA = <DB>;

close(DB);

foreach $line (@DATA) {

($name,$email,$birth1,$birth2,) = split(/\,/,$line);

if ($mondata eq "$birth1") {

&mailcheck;

if ($errorh eq "0") {&sub2;}

}

}

&sub3;

}

sub sub2{

open(MAIL,"|$sendmail $email");

&jis("Subject: $mailtitle"); print MAIL "$msg\n";

print MAIL "To: $email\n";

print MAIL "From: $myaddress\n";

print MAIL "\n";

$message = <<END_OF_MESSAGE;</p>

$name様

$mailtext

END_OF_MESSAGE

&jcode'convert(*message,'sjis');

print MAIL "$message";

close(MAIL);

$tosendall="$tosendall$name,$email,誕生日:$birth1/$birth2\n";

}

sub sub3{

open(MAIL,"|$sendmail $myaddress");

&jis("Subject: $mon月の誕生日処理完了"); print MAIL "$msg\n";

print MAIL "To: $myaddress\n";

print MAIL "From: $myaddress\n";

print MAIL "\n";

$message = <<END_OF_MESSAGE;</p>

$mon月($birth1月に誕生日を迎える方)の誕生日処理正常に終わりました

【送信日】

$tday2

【メール送信先】

$tosendall

【メール文】

$mailtext

END_OF_MESSAGE

&jcode'convert(*message,'sjis');

print MAIL "$message";

close(MAIL);

}

sub mailcheck{

$errorh = "0";

$xx =$email;

&transmail;

$email = $xx;

@email2 = split(/\@/,$email);

@email3 = split(/\./,@email2[1]);

unless($email =~ /.+\@.+\..+/){$errorh = "1";}

if($email =~ /[^a-zA-Z0-9_\@\.\-]/){$errorh = "1";}

if($email =~ /[^a-zA-Z]$/){$errorh = "1";}

if(@email3[0] eq "") {$errorh = "1";}

if(@email3[1] eq "") {$errorh = "1";}

if(@email3[4] ne "") {$errorh = "1";}

if(@email3[2] ne "") {

if(@email3[2] =~ /[^a-zA-Z]/){$errorh = "1";}

}

if(@email3[3] ne "") {

if(@email3[3] =~ /[^a-zA-Z]/){$errorh = "1";}

}

if ($email eq "") {$errorh = "1";}

}

sub transmail{

$from='[@01-9A-Za-z._-]';

$to='[@01-9A-Za-z._-]';

&jcode'convert(*xx, 'euc');

&jcode'convert(*from, 'euc');

&jcode'convert(*to, 'euc');

&jcode'tr(*xx, $from, $to);

&jcode'convert(*xx, 'sjis');

}

sub jis { $msg = $_[0]; &jcode'convert(*msg, 'jis'); }


conf.pl

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

$mailtitle = "誕生日おめでとうございます";

$myaddress = "abc\@abc.net";

$timediff = '0';

$database = './conf/member.txt';

$sendmail = '/usr/sbin/sendmail';


member.txt

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

織田 信長,aaa@bbb.com,6,11,

豊臣 秀吉,ccc@ddd.com,12,20,


monthdate.txt

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

9,28,

2007/09/07 18:52:31
id:KUROX No.2

回答回数3542ベストアンサー獲得回数140

ポイント100pt

monthdate.txt

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

9,28,

monthdate.txt

の中身を

9,25, に変更するだけのように見えます。

本番環境でなくて、あくまでテストできるのなら、

perlが動いているマシンの日付を9/25にして、

実行すれば、該当者にメールが送られ、

monthdate.txtの内容は以下のように書き換わると思います。

monthdate.txt

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

10,25,

きちんとソースを見てないので、実際にテストもらって

結果が予想通りなら、私の回答は正しいと思います。

id:icta

monthdate.txtは前月28日に配信した時点で翌月の28日の配信日に自動的に変更されます。

これがこのCGIの機能です。

この機能を活用して誕生日当月25日に自動配信するようにしたいのです。

monthdate.txtの内容を書き換えるのではなく、あくまでCGIを変更して毎月誕生日当月の25日に送るようにしたいと考えております。

従って現在9月であればmonthdate.txtの内容は8月25日に配信後9,25,に書き換わるようにしたいのです。

2007/09/07 19:55:13
id:Mook No.3

回答回数1314ベストアンサー獲得回数393

ポイント100pt

勘違いしていました。

先の回答はポイント不要です。


データ部分を提示していただいたおかげで、全容がわかりました。

対象となる日付は monthdate.txt に記載されており、今日がここに記載された日だったら、DB に記載された「日にち(誕生日)の月」と「今月」が同じだったメンバーにメールを送るようになっているのですね。


処理後に、monthdate.txt を1ヶ月後の日付に更新しているので、KUROX さんの指摘も誤っていません。

最初に、ここが25日になっていれば、25日に処理を実行し、ファイルも1ヶ月後の25日になります。

(あまりスマートなつくりではないですが、とりあえず目的どおりには機能するでしょう。)


なのでこのファイルの他に下記を変更します。

    foreach $line (@DATA) {
        ($name,$email,$birth1,$birth2,) = split(/\,/,$line);
#       if ($mondata eq "$birth1") {  --- 次月($mondata) と比較
        if ($mon eq "$birth1") {
            &mailcheck;
            if ($errorh eq "0") {&sub2;}
        }
    }




ただし、monthdate.txt に記載した日にこの CGI が動かなかったらそれ以降はこのファイルが更新されないので、次月以降の処理がされなくなります。なので「スマートでない」のですね。


月とは関係なく単純に毎月特定のに処理をしたいなら、下記のようにもできます。

その場合は mathdate.txt は不要になります。


conf.pl に下記を追加し

$sendDay = 25;

本体を

     :
     :
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time + ($timediff * 60 * 60));
if ( $mday == $sendDay ) {
    &sub1;
}
print "Content-type: image/gif\n\nGIF89a\1\0\1\0\200\0\0\0\0\0\0\0\0!\371\4\1\0\0\0\0,\0\0\0\0\1\0\1\0\0\2\2D\1\0\n";
exit;
sub sub1{
     :
     :
	foreach $line (@DATA) {
		($name,$email,$birth1,$birth2,) = split(/\,/,$line);
#          if ($mondata eq "$birth1") {    --- 次月($mondata) と比較
                if ( $mon == $birth1 ) { # --- 今月($mon) と比較
			&mailcheck;
			if ($errorh eq "0") {&sub2;}
		}
	}
     :
     :

のようにすれば、良いと思います。

id:icta

ご回答ありがとうございました。希望通りの動作を確認できました。大変感謝しております。

2007/09/07 22:31:51

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 yo-kun 220 205 30 2007-09-07 20:35:45
  • id:Mook
    勘違いしていました。
    提示していただいたデータのおかげで全容がわかりました。

    後ほど回答します。
  • id:KUROX
    わざわざ変更が容易なように
    monthdate.txtに日付を外出しにしてるので、
    CGIは触らすに、このTXTを変更すればいいです。

    一度目は、手動で書き換えるしかありません。
    二度目以降は、自動で25日になります。

    25に書き換えることで
    monthdate.txtは前月25日に配信した時点で翌月の25日の配信日に自動的に変更されるような汎用性の高いプログラムに
    なっているのです。
  • id:KUROX
    私が間違ってました。当月ですね。
  • id:KUROX
    とりあえずこんな感じかなとは思います。
    質問に答えられてないので、ポイントは要りません。
    ご迷惑かけました。

    ---------------------------------------
    monthdate.txtの28は25に書き換えてください。

    ■変更前
    open (DB,"$database");
    @DATA = <DB>;
    close(DB);
    foreach $line (@DATA) {
    ($name,$email,$birth1,$birth2,) = split(/\,/,$line);
    if ($mondata eq "$birth1") {
    &mailcheck;
    if ($errorh eq "0") {&sub2;}
    }

    ■変更後
    $mondata_t = $mondata;
    $mondata_t --;
    if($mondata_t eq "0"){$mondata_t = 12;}
    open (DB,"$database");
    @DATA = <DB>;
    close(DB);
    foreach $line (@DATA) {
    ($name,$email,$birth1,$birth2,) = split(/\,/,$line);
    if ($mondata_t eq "$birth1") {
    &mailcheck;
    if ($errorh eq "0") {&sub2;}
    }
  • id:Mook
    回答している間に、 KUROX さんのコメントがたくさん・・・。

    上記コメントについて一点だけ。
    今月は $mon があるのでそれを使用すれば簡単でしょう。

    KUROXさんのコメントで納得されていれば、開封は不要です。
  • id:yo-kun
    monthdate.txtについての説明を補足。

    コメントアウトされていない最初のifで
    今日がmonthdate.txtに記述されている日かどうかを確認してます。

    そうでなければ何もせずに終わります。

    そうであれば目的の処理を行って、
    monthdate.txtを来月の同日に書き換える処理をしてます。


    これにより同じ日に何度もこのCGIが走るのを防いでいるのでしょう。


    ただ、例えばmonthdate.txtに記述されている日にこのCGIが一度も実行されないと、それから一年間は何もしなくなってしまうような…。
  • id:Mook
    なるほど。

    1日に複数回このCGI が動く場合は、後半の私の方法はまずいですね。
    何らかのフラグが必要となりますね。
  • id:KUROX
    ポイントもらってしまいました(滝汗)。
    今回はごめんなさい。次回がんばらせていただきます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません