2008/04/21

Seednet 廣告信判斷規則

突然接到 Seednet 的通知,說公司的某個 IP 一直狂發廣告信,要我盡快處理,不然會被擋掉。
但是這個 IP 就是專門用來發送會員電子報的伺服器,而且當初申請的就是企業專用的 ADSL,哪有叫企業不能寄送電子報的道理。
溝通了一會兒之後,Seednet 告知他們判定廣告信的方式,調整一下發送頻率就可以避免被擋信。
Seednet 的廣告信判斷規則:
  • 一個 IP 五分鐘內不可超過 250 次 connection。

  • 一個帳號五分鐘內不能超過 150 封信。

  • 如果超過上述的限制,就會被擋 20 分鐘,20 分鐘之後才會接受寄信。
    如果再超過上述限制,就再擋 20 分鐘(不會累加,一樣是 20 分鐘後再開放寄信)。

    2008/04/01

    strtotime() + month 要小心!

    因故需要找出當月的最後一天,一開始是用以下語法:
    $last_day_of_this_month = date("Y-m-d", (mktime(0, 0, 0, date("m", 
    strtotime("next month")), 1, date("Y", strtotime("next month")))) - 86400);


    由於每個月的天數不一樣,最後一天可能是 28、29、30、31,因此作法是先找出下個月第一天的 unix timestamp,然後減去 86400 秒(一天),再利用 date() 去調整成想要的日期格式。

    但是這寫法在今天 2008-03-31 卻出問題,跑出來的結果是 2008-04-30,不是預期的 2008-03-31。
    仔細追查,發現問題是出在 strtotime("next month") 這段程式碼。

    測試程式碼:

    echo date("Y-m-d", strtotime("today")); // 2008-03-31
    echo date("Y-m-d", strtotime("+1 month")); // 2008-05-01
    echo date("Y-m-d", strtotime("next month")); // 2008-05-01

    從這個結果來看,感覺 strtotime() 在處理 +1 month 時,是直接把月份 +1,像是 3 月 31 日就直接變成 4 月 31 日,由於 4 月只有 30 天,就變成 5 月 1 日。

    既然 strtotime() 不能用,就換個寫法:
    $last_day_of_this_month = date("Y-m-d", (mktime(0,0,0,
    (((date("n")+1)>12) ? 1 : date("n")+1),1,date("Y", strtotime("next month"))))-24*60*60);

    還是自己算月份比較保險...

    附帶一提,在官方手冊上有提到,在 PHP 4.4.0 以前的版本,next 會誤判成 +2,建議使用 +1 取代 next。但我在 4.4.8 和 5.2.5 下測試,結果都是一樣錯。