※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

※wikiの編集が分からなくて、追加してほしい項目がある場合はページ下の「コメント」から誰かに頼んで下さい。

ランダムPOSTを●分おき、リプライを▲分おきにしたい! [#ra5d511d]

ここではランダムPOSTを30分おき、リプライを2分おきで考えます(※cronは2分間隔設定にする。)

リプライ [#c8e65725]

リプライ間隔はcronの間隔と同じなので、何か条件付けるということはしなくてOKです。
bot.phpに
$response = $eb->reply(2,"data.txt","reply_pattern.php");
を追加してあげましょう。

ランダムPOST [#nd87a60d]

bot.php内でも解説されている通り
//bot.phpを実行したときに、0分、15分、30分、45分だったら実行される
if(date("i") % 15 == 0){
	$response = $eb->postRandom("data.txt");
}
を使っていきます。

date("i")と言うのは、現在の時刻・○時△分の△部分を表します。
ほかにもdate("G")やdate("Y")等色々な現在時刻を表すものがあります。
詳しくは各自ここで調べて下さい。(外部リンク:http://www.php.net/manual/ja/function.date.php)
% 15 == 0 と言うのは、事前のdate("i")が15で割り切れることを意味します。
ここはifなので、bot.phpへアクセスした時、15で割り切れる時間(分)のみ{}の中身を実行します。
bot.phpへアクセスした時の時間が0分(60分)と15分、30分、45分だった時、いずれも15で割り切ることが出来ますね。

では今回は30分おきに設定したかったので
if(date("i") % 30 == 0){
	$response = $eb->postRandom("data.txt");
}
と書いてみます。こうすると0(60)分と30分の時のみ実行されます。1時間に2回実行させることになります。
目的達成です!
ここで注意したいのは、リプライの記述をif{}内に入れないことです。
リプライの記述まで{}へ入れてしまっては、リプライまで30分おきになってしまいます。


時間別にリプライorPOSTを分けたい! [#b7bf333f]

上の「ランダムPOSTを●分おき、リプライを▲分おきにしたい!」でdate("i")が現在の時刻○時△分の△部分だというのは分かりました。
今回は朝(6~10時)morning.txtと昼(11~15時)noon.txt、夜(16~0時)evening.txt、深夜(1~5時)night.txtそれぞれ別のPOSTをさせてみましょう。
ただし今回は△分ではなく○時なので、date("i")は使えません。○時はdate("G")を使用します。
24時間表記ですが、24という数値はありません。24時は0時扱いになります。

まずは朝の部分。現在の時刻・○時の○部分が6~10の時。
if(date("G") > 5 && date("G") < 11){
	$response = $eb->postRandom("morning.txt");
}
これは「もし、現在時刻が5時より大きく、11よりも小さい時」と言うifの条件式になります。
「&&」は「and」でも構いません。英字の通り「かつ」と言う意味があります。

注意したいのは不等号!これは算数レベルで考えてください。
全角 説明
A>5 A>5 Aは5より大きい。つまり6~23。
A<5 A<5 Aは5より小さい。つまり0~4。
A>=5 A≧5 Aは5以上。つまり5~23。
A<=5 A≦5 Aは5以下。つまり0~5。

次に昼の部分。現在の時刻・○時の○部分が11~15の時。
if(date("G") > 10 && date("G") < 16){
	$response = $eb->postRandom("noon.txt");
}
でも良いのですが…
if(date("G") > 5 && date("G") < 11){
	$response = $eb->postRandom("morning.txt");
}else if(date("G") > 10 && date("G") < 16){
	$response = $eb->postRandom("noon.txt");
}
とelseを付けて朝の部分とくっ付けてあげるとすっきりします。
elseは、先のif条件(朝)に合わなかった場合else以降を実行しようとします。

次に夜の部分。現在の時刻・○時の○部分が16~24の時。
if(date("G") > 15 && date("G") < 1){
	$response = $eb->postRandom("evening.txt");
}
ここまで来ると、やってしまいがちですが…これは 大きな間違い!!!
これでは「15より大きくて、1より小さい」というありえない条件になってしまいます。
if(date("G") > 15 || date("G") < 1){
	$response = $eb->postRandom("evening.txt");
}
としてやることで「現在時刻が15より大きい、または1より小さい場合」となります。
「||」は「or」でも構いません。英字の通り「または」と言う意味があります。
if(date("G") > 5 && date("G") < 11){
	$response = $eb->postRandom("morning.txt");
} else if(date("G") > 10 && date("G") < 16){
	$response = $eb->postRandom("noon.txt");
} else if(date("G") > 15 || date("G") < 1){
	$response = $eb->postRandom("evening.txt");
}
繋げるとこんな感じです。

次に深夜の部分。現在の時刻・○時の○部分が1~5の時。
if(date("G") > 0 && date("G") < 6){
	$response = $eb->postRandom("night.txt");
}
としてあげてもいいのですが…今まで6~10,11~15,16~24時までは指定してきました。
残りの時間はこの1~5時しかないので、わざわざ条件を書いてやることはないのです。
if(date("G") > 5 && date("G") < 11){
	$response = $eb->postRandom("morning.txt");
} else if(date("G") > 10 && date("G") < 16){
	$response = $eb->postRandom("noon.txt");
} else if(date("G") > 15 || date("G") < 1){
	$response = $eb->postRandom("evening.txt");
} else {
	$response = $eb->postRandom("night.txt");
}
で完成です!

リプライも同様に条件付けてあげることで、時間別パターン可能です。


落とし穴に注意 [#rf62e452]

if(date("i") % 30 === 0){
はdate("i")が30で割り切れる分数、というのを解説しました。

これを30分おき等、分数ではなく1時間毎にしたい。
if(date("G") % 1 === 0){
と書く人をよく質問スレで見かけます。
これは大きな間違いです。

詳しく書くと………
if(date("i") % 30 === 0){
は0,30分に動くことになりますね。
ここでもしcronが2分毎ではなく10秒毎にアクセスするとしたら。
毎時0分(30分)の0秒、10秒、20秒、30秒、40秒、50秒すべての秒数で作動してしまうのです。
これは、cronが分数おきだからこそ使える書き方なのです。
if(date("G") % 1 === 0){
と書いてしまうと、cronが2分毎だった場合、毎時の0,2,4,6,,,,,,,,,,,,58分と2分毎に作動してしまいます。

0分きっちりに作動させたいなら、難しく考えず
if(date("i") == "0"){
としてしまえばオッケーです。


落とし穴に注意2…CRONと設置サーバーの時間がズレている

掲示板でも多い質問の一つに「リプライは動いてるけど時間分け指定をしたら通常ポストしなくなった」というものがあります。
特に見られる理由は下記3点です。
 1:if・switchなどの内容が間違っている
   ……慣れた人でも凡ミスをすることがあるので一つずつ再確認しましょう
 2:CRONがbot.phpにアクセスする時間外を指定している
   ……「CRONは2分毎なのにbot.phpでは3分毎の設定」などちぐはぐでは?指定時間を揃えましょう
 3:CRONと設置サーバーの時間がズレている
   ……どのくらいのズレがあるのか確認して適切に処置しましょう
ここでは3番の対処を説明します。

ズレを知る

CRONと設置サーバーの時間のズレを確認するための下準備をします。
(data.txtやbot.phpの内容を既に変更している場合は適宜ファイル名を変更して対応してください)

data.txtの内容(この1行のみ)
{hour}時{minute}分{second}秒

bot.phpの実行内容(下記以外のリプライ・TL反応・ポスト・フォロー返し等はコメントアウトする)
$response = $eb->postRandom("data.txt");

CRONの設定
5分毎、10分毎など、CRON提供側で許容されている範囲内で設定します。
1分毎・2分毎での設定はズレを計るのに向きません、できれば0分・5分・10分…という0分始まりの5分毎をオススメします。

ここまでが下準備です。
実際にCRONを起動させ、「●時●分●秒」というポストが数回行われるまで待ちます。
文字化けするようであれば文字コード・改行コードを確認、ポストが行われないようであれば指定したbot.phpが正しいURLか確認します。

0分始まりの5分毎の場合、「分」は0もしくは5の倍数でなければなりませんが、これ以外の場合にはズレが生じていることになります。
また、「分」が0もしくは5の倍数であっても「秒」が59秒……など数秒のラグで「分」が変わってしまうような値では不安が残ります。
何分のズレなのか、ズレが生じるのはどの程度の頻度か、等をチェックしたら次の段階です。

ズレに対処する

一番簡単なのはCRONの実行時間をずらして、サーバーの実行時間に合わせてやることです。
しかしこの方法では更にズレが生じたり、時間ズレと関係なくサーバーが不安定で実行に時間がかかった場合などに対処しきれません。
そこでbot.phpの時間指定を厳密なものではなく余裕をもった書き方に変えます。

毎時0分にランダムポストしたい場合は下記のように書きますが、
if(date("i") == 0){
	$response = $eb->postRandom("data.txt");
}

ズレが生じている場合は下記のように余裕をもった時間指定に書き換えます。
//以下は毎時0分~1分の間に実行(2分未満の範囲で遅い場合)
if(date("i") <= 1){
	$response = $eb->postRandom("data.txt");
}
//以下は毎時59分か0分に実行(2分未満の範囲で早い場合)
if(date("i") == 0 || date("i") == 59){
	$response = $eb->postRandom("data.txt");
}

このように余裕をもたせることで多くの場合は解決します。
しかし、bot.phpの実行内容を増やしていくと、時には「CRONと設置サーバーにズレがないのに実行されてない?」という事があります。
これについても過去に同様の事例が多くありましたが、多くは下記3つに当てはまります。
 1:処理落ち・タイムアウト……設置サーバーの能力を越えているかtwitterが重い場合など
 2:ifやswitchの書き方の問題……閉じ忘れや勘違いがないか再確認
 3:実行中に指定した時間を過ぎてしまった……bot.phpの書き方や改造で対応
次の項目では3番に当てはまる事例への対処を説明します。

指定した時間に実行の処理が終わらない

EasyBotterに慣れてくると、単純な機能だけでなく様々な機能を時間別で組み合わせて実行することも多くなります。
一回に処理する機能が増えれば処理時間は長くなります。
また初期は気にならない処理時間でも、フォロー・フォロワーの増加などで処理時間が長くなることもあります。

まずはbot.phpで指定できる機能がどのような動きをしているかを考えてみましょう。
設置サーバー内の処理だけで済む
  ・ランダムポスト
  ・ローテーションポスト
   ……設置サーバー内のファイルからデータから選んでtwitterに送る
twitterから情報を呼び出さなければならないもの
  ・リプライ
  ・タイムライン反応
  ・自動フォロー返し
   ……初めにtwitterから情報を呼び出し、その内容を設置サーバー内のファイルと照らし合わせて処理を行い、その結果をtwitterに送る。
     twitterが重い場合は呼び出し時点で処理時間を食う。
     またリプライ数・タイムラインの速度やフォロワー数などで処理時間が大きく変わる。

上記を踏まえて下記のようなbot.phpを見てみましょう。
//毎回リプライ返し
$response = $eb->reply(2,"data.txt","reply_pattern.php");
//毎時0分にランダムポスト
if(date("i") == 0){
	$response = $eb->postRandom("data.txt");
}

この書き方に全く問題はありません、CRONと設置サーバーの時間ズレがなければうまく動くことでしょう。
しかし、時間ズレはないのに定期ポストが不安定になることも予想される書き方でもあります。
その理由は「プログラムの常識」にあります。

プログラムは上から順に実行されていきます。
つまり毎時0分には、「リプライ返しを全て終えてからランダムポストをする」という順番になります。
「リプライ返し」は先に説明した通り「ランダムポスト」よりtwitterと情報をやり取りする回数が多く、twitterの重さや送られてくるリプライの量によって処理にかかる時間が左右されやすいものです。
つまりCRONが0分ちょうどにbot.phpを叩いたとしても、「リプライ返し」の処理に時間がかかり過ぎてしまい「ランダムポスト」の処理にとりかかった時点で0分を過ぎている、という事態が予想できるのです。
つまり
//毎時0分にランダムポスト
if(date("i") == 0){
	$response = $eb->postRandom("data.txt");
}
//毎回リプライ返し
$response = $eb->reply(2,"data.txt","reply_pattern.php");
このような書き方にすると、ランダムポストから処理が始まるので、CRONが定刻通りであれば順当に処理が行われるのです。

ただし、レンタルサーバーによっては「●秒以上実行し続けているプログラムは処理途中であっても終了させる」という機能や規約が設定されている場合もあります。
また、処理量がサーバーの処理能力を越えてしまうとダウンする可能性もあります。
このような場合にはプログラム自体を軽くしたり、処理を分散させる努力、またはサーバーを変更する必要が求められます。

脱初心者してから考える事

ifやswitchでの時間わけ設定が増えてくるとどうしても処理時間が長くなりがちです。
脱初心者したら処理の効率化ができるよう、bot.phpの書き方を工夫してみましょう。

脱初心者したばかりの方にとって最も簡単で有効な処理の効率化は「date関数の呼び出し回数を減らす」ことです。
date関数は時間を呼び出すdate("G")やdate("i")だけでなく、月を呼び出すdate("n")、日にちを呼び出すdate("j")など様々なものがあります。
年月日・曜日・時間などを多用することで様々な指定ができる代わりに、逐一date関数の内容をサーバーに問い合わせ呼び出す動作が増えてしまうので処理速度が低下します。
また、bot.phpの記述内容が増えるに従って一番下の方に書かれたものが時間外になってしまう可能性も高くなります。
そこで、処理を指定する前に時間をEasyBotterに記憶させて処理速度を上げてみましょう。

//date("i")を$minuteに代入する
$minute = date("i");
//毎回リプライ返し
$response = $eb->reply(2,"data.txt","reply_pattern.php");
//毎時0分にランダムポスト
if($minute == 0){
	$response = $eb->postRandom("data.txt");
}
代入演算子「=」は、''「A = B」の時「BをAに代入する」''という意味を持ちます。
比較演算子である「==」「===」とはまったく異なるので注意が必要です。
この場合date("i")、つまり分を$minuteという関数に代入しています。
同様の方法でdate関数は全て代入することができます、$minute・$hour・$monthなどのように重複しない範囲で関数の名前をつけることができます。

date関数を他の処理より先に関数へ代入することで、CRONがbot.phpを叩いた時刻や日付等をその処理が終わるまでの間記憶してくれます。
つまり、先に時間がかかる処理をした後や大量のifやswitchを経た最下部の処理でも、「CRONがbot.phpを叩いた時点」の時刻として処理を進めることが可能となるのです。

動作テストにも使える代入演算子

上記で説明した代入演算子を利用することで、「12月31日限定で動くか」というようなテストもできます。
$month = date("n");
$day = date("j");
本来は上記のようにdate関数を代入しますが、
$month = 12;
$day = 31;
このように、ダイレクトな値を代入することで仮想の12月31日の状況にすることができますし、違う値を入れれば「12月31日以外では動かないか」のテストもできます。

いずれの場合も初心者のうちに手を出すべきものではありません、ある程度EasyBotterの挙動そしてPHPに慣れた上ですべきことですが、これらを理解しこなせるようになれば中級者の仲間入りの第一歩です。


落とし穴に注意3…演算子「%」の理解

さて、これまでの内容を理解したら構文の中身をもう少し分解してみましょう。
if(date("i") % 15 == 0){
	$response = $eb->postRandom("data.txt");
}
これまで上記について「15分ごとにランダムポストを実行」と書いていましたが、実際は若干異なり、正確には「0分・15分・30分・45分にランダムポストを実行」となります。
なぜでしょうか、……それは演算子「%」を正しく理解することによって解明できます。

if(date("i") % 15 == 5){
	$response = $eb->postRandom("data.txt");
}
このように書いても「15分ごとにランダムポストを実行」しますが、「0分・15分・30分・45分にランダムポストを実行」はされません
なぜでしょうか、……これこそが演算子「%」を使いこなすポイントです。

演算子「%」とは?

演算子「%」はただの割り算ではなく剰余なのです。
剰余と聞くと耳慣れないかもしれませんが、算数的な言い換えをすると「割り算をした時の余り」を求める場合に使う演算子です。
つまり
if(date("i") % 15 == 5){
上記は「分を15で割って余りが5の時」という意味で、「5分・20分・35分・50分の時」という指定となります。

演算子「%」の有効活用

演算子「%」を正しく理解することで活用方法が増えます。

奇数・偶数の振り分けは一々指定しなくても、「% 2」の値が0か1か、という考え方で簡単になります。
//偶数時は、0分始まりで15分ごとに、guusuu.txtからランダムポスト
if(date("G") % 2 == 0 && date("i") % 15 == 0){
	$response = $eb->postRandom("guusuu.txt");
}
//奇数時は、5分始まりで10分ごとに、kisuu.txtからランダムポスト
else if(date("G") % 2 == 1 && date("i") %10 == 5){
	$response = $eb->postRandom("kisuu.txt");
}

CRONと設置サーバーで時間にズレがある場合でも
if(date("i") % 15 == 5 || date("i") % 15 == 6){
このようにすることで「5分・6分・20分・21分・35分・36分・50分・51分」と余裕をもたせた指定にすることができます。



コメント [#n0b1997d]

  • 時間別にリプライorPOSTと同じような感じで、時間別にPOSTしないようにしたいです。何方かよろしくお願いします。 -- 沢谷 (2010-07-26 02:19:00)
  • 沢谷さん>その場合、時間別POSTの応用で$response = $eb->postRandom("");とすればPOSTしません -- 通りすがりのねこ (2010-08-01 21:09:11)
  • もし、if(date("i") == "0"){を使う場合、cronの実行間隔は1分にしなければなりませんか? -- 名無しさん (2010-09-07 16:56:00)
  • >もし、if(date("i") == "0"){を使う場合、cronの実行間隔は1分にしなければなりませんか? 回答:その必要はありません -- 通りすがりのねこ (2010-09-09 21:15:34)
  • 時間別POSTを15分おきにしたい場合、例えば時間別は6~10時のみの設定のを15分おき実行だと、if(date("G") > 5 && date("G") < 11 date("i") % 30 === 0) で良いのでしょうか? -- たに (2010-09-19 01:21:04)
  • 夜だけ違うリプライ。bot.php(2) http://livbot.sblo.jp/  の記事が参考になりました。サンプルコード書いてあります。 -- 2時間おきに作動させたい場合 (2010-12-10 05:27:08)
  • 何回かの間隔で、実行したい場合は、カウンターファイルを作る手もあるぞ。パーミッションは666のこと。bot.phpの例で10回間隔で順次投稿したい場合。1間隔1分だと10分間隔です。
function seqnum(){
$iseq = 0;
$fname = "count.dat";
$iseq = file_get_contents($fname);
if ($iseq >= 60) {
	$iseq = 0;
}
$iseq = $iseq + 1;
file_put_contents($fname,(string)$iseq); //SEQカウンター書き込み
echo "参照シーケンス番号 = ".$iseq."<br />";
return $iseq;
}$iseq = seqnum();
if (($iseq % 10) == 0) {
$response = $eb->postRotation("data.txt");
} - koziki_bot (2011-01-28 10:08:59)

  • リプを2分置き、呟きを15分置きにしたかったので「if(date("i") % 15 == 0){ $response = $eb->postRandom("data.txt"); }」と「$response = $eb->reply(2,"data.txt","reply_pattern.php");」を書き込んだのですが上手く動きません。ちなみに「$response = $eb->reply(2,"data.txt","reply_pattern.php");」だけですと正常に動くようです。初心者ながら色々調べてみましたが解決できませんのでもしよければ教えてください。 -- 千紘 (2011-02-20 20:44:36)
  • 千紘さん> cron部分の詳細がないのでわからないですがcronが2分おきなら15分にはcronは起動しないのは分かる? -- 名無しさん (2011-02-20 21:38:41)
  • ランダムPOSTを●分おき~と時間や曜日別にツイートを分ける方法を個別には理解できたのですが、組み合わせ方がわかりません・・・。●曜日の●時から●時まで、●分ごとにツイート(リプライ)という風にしたいのですが・・・何方かよろしくお願いします。 -- 番 (2011-02-21 00:39:31)
  • そーでした、PHPのファイルを時間ごとに自動的に叩くアプリを使っているのでcronは使ってないです。このアプリは自分で作ったのですがどうしようかなあ??興味ある方、ツイッターで質問してみてください。scネームはハンドル名と同じです。 -- koziki_bot (2011-02-21 00:49:39)
  • 回答ありがとうございます。理解しました!2分に合わせたいなら10分置き、15分に合わせたいなら3分置きにするなどどちらでも割れるような値にしなくてはならないということですね。 -- 千紘 (2011-02-21 07:58:19)
  • すみません。曜日と時間で分けて30分ごとにツイートさせたいのですが、 -- 番 (2011-03-08 22:45:13)
  • 途中で切れてしまいましたすみません・・・。曜日と時間で分けて30分ごとにツイートさせるには if(date("i") % 30 === 0){ で30分ごとにツイートするように指定して、switch(true)で case (date("w") == "1″ && date("G") > "6″ && date("w") == "1" && date("G") < "12"):としても出来ないでしょうか? すみませんとても困ってます・・・よろしくお願いします。 -- 番 (2011-03-08 22:52:52)
  • bot.phpはいじってないのですが、2分置きどころかリプライを返してくれません…どうすれば良いのでしょうか? -- 翔 (2011-06-01 22:45:03)
  • bot.phpはそのままで、リプはreply_patternから返すようにしているのに、なぜかdate.txtの言葉から拾って返してしまいます。対処方法を教えて下さい…。 -- 名無しさん (2011-06-02 02:29:36)
  • @pagesかな?Twitterが重いか@pagesの鯖が重かったり障害があるときになるよ。これは@pagesが正常になるのを待つしか無いね -- 名無しさん (2011-07-18 20:26:51)
  • 30分とか割り切れる話をするだけで、40分や90分間隔などの場合を書かないあたり不十分なwikiだなと感じる -- 名無しさん (2011-10-29 13:11:12)
  • ↑40分や90分なら応用でいくらでもやりようがあるし、普通はcronでどうとでもなる。返信が返せないじゃないかならファイルを分ければいいだけのこと -- 名無しさん (2011-11-14 00:53:22)
  • まあ40分は確かにめんどいかもねー。前回のツイート時刻を取得できればちょっと楽かもしれないけど。 -- 名無しさん (2012-04-21 17:59:52)
  • 時間別リプライをしようと思い、「リプライも同様に条件付けてあげることで、時間別パターン可能です」とあるので時間別ランダムポストと同様にこのように時間分けをしたのですがどうも上手く動いてくれません【if( date("G") >=1 && date("G") <= 6 ){$response = $eb->reply(3,"","reply_pattern_night.php");} else{$response = $eb->reply(3,"","reply_pattern.php");}】(ランダムポストは時間分けに成功してます)。ほんとうにこれで動くのでしょうか? -- むー (2012-05-20 05:07:43)
  • ↑bot.phpの記述の順序を入れ替えたら成功しました、お騒がせしてすみません -- むー (2012-05-28 01:05:28)
  • 何時~何時、何曜日~何曜日とpostさせないようにしたいのですが上手く行きません。randompostの上にいかの構文を付け足しました。  "if(date("G") > 15 || date("G") < 1){ $response = $eb->postRandom("data.txt");" -- PON (2013-06-24 20:01:19)
  • 時間別のリプですが、たとえば6時30分に0630.txtを呟かせたい場合は、 if(date("G:I") > 6,29 && date("G:I") < 6,31){ $response = $eb->postRandom("0630.txt");   とすればいいのでしょうか? -- MOG (2013-09-22 15:56:03)
名前:
コメント: