2009年11月3日火曜日
PHPで記述されたプログラムをcronで定期的に実行する方法
TwitterとGoogle Mapを活用したウェブアプリ(http://www.communitycast.jp/)、Twitterとパノラマを活用したウェブアプリ(http://www.francis-hope.jp/lab/panorama_tweet/)では、ウェブサーバーに設置したPHPプログラムでTwitterの投稿を定期的に取得し、MySQLに投稿内容を格納している。PHPと言うと、クライアント側のウェブブラウザからGet、Postでアクセスする際に使われるケースが多いが、サーバー側でのプログラムとしても利用することができる。その方法を以下に紹介しよう。
ウェブサーバーに設置したプログラムは以下の通りだ。ファイル名はabc.phpとしよう。
ユーザー名、パスワード、IPアドレスは*とさせて頂いた。
ここで重要なのは、1行目の #!/usr/local/Zend/Core/cgi-bin/php -q だ。※サーバー環境に応じてディレクトリは変更してください。
通常は2行目以降のようなPHPを記述していると思うが、サーバーでcronから実行させるためには1行目を追加する必要がある。このあたりは、shellプログラムのファイルの1行目にプログラムへのパスを記述するのと同じ感覚だ。
続いて、cronの設定方法。
上記コマンドをlinuxのコマンドプロンプトで実行する。/etc/cron.dディレクトリ配下にabcというファイルが生成される。ファイルの中身は */2 * * * * root /usr/local/Zend/Core/cgi-bin/php /abc.php となる。2分置きにrootユーザーで/abc.phpというプログラムを実行するという意味だ。ディレクトリ、実行ユーザー、時刻、または時間間隔の設定は必要に応じて変更してください。
ウェブサーバーに設置したプログラムは以下の通りだ。ファイル名はabc.phpとしよう。
#!/usr/local/Zend/Core/cgi-bin/php -q
<?php
$mysqlDatabase = "***.***.***.***";
$mysqlUsername = "***";
$mysqlPassword = "******";
$databaseName = array("***");
$enc_disp = "UTF-8";
$enc_db = "UTF-8";
// データの文字コードを変換する関数
function cnv_enc($string, $to, $from) {
$det_enc = mb_detect_encoding($string, "auto");
if ($det_enc and $det_enc != $to) {
return mb_convert_encoding($string, $to, $det_enc);
} else {
return $string;
}
}
// MySQLへ接続する
$link = mysql_pconnect($mysqlDatabase, $mysqlUsername, $mysqlPassword) or die("データベースへの接続に失敗しました。");
// MySQLへの接続をUTF-8に設定する
mysql_query("SET NAMES UTF8", $link);
// MySQLデータベースを選択する
mysql_select_db($databaseName[0], $link) or die("データベースの選択に失敗しました。");
// MySQLクエリを生成する
$q1 = "SELECT MAX(ID) AS MAX_ID FROM TWEET_PANORAMA";
// MySQLクエリを実行する
$r1 = mysql_query($q1, $link) or die("クエリの実行に失敗しました。SQL:".$q1);
$maxId = 1;
if (mysql_num_rows($r1) > 0) {
$row = mysql_fetch_object($r1);
$maxId = $row->MAX_ID + 1;
}
mysql_free_result($r1);
$user = "******";
$pwd = "******";
// Twitterに問い合わせる
$ch = curl_init();
if ($maxId < 4000000000) { $host = "http://twitter.com/statuses/friends_timeline.xml?count=100"; } else { $host = "http://twitter.com/statuses/friends_timeline.xml?since_id=".$maxId."&count=100"; } curl_setopt($ch, CURLOPT_URL, $host); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_USERPWD, "$user:$pwd"); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); $result = curl_exec($ch); curl_close($ch); $xml = simplexml_load_string($result) or die("XMLパースエラー"); // 値を参照する foreach ($xml->status as $status) {
$CREATED_AT = sprintf('%s', mysql_real_escape_string(cnv_enc($status->created_at, $enc_db, $enc_disp), $link));
$ID = sprintf('%s', mysql_real_escape_string(cnv_enc($status->id, $enc_db, $enc_disp), $link));
$TEXT = sprintf('%s', mysql_real_escape_string(cnv_enc($status->text, $enc_db, $enc_disp), $link));
$USER_ID = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->id, $enc_db, $enc_disp), $link));
$USER_NAME = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->name, $enc_db, $enc_disp), $link));
$USER_SCREEN_NAME = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->screen_name, $enc_db, $enc_disp), $link));
$USER_PROFILE_IMAGE_URL = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->profile_image_url, $enc_db, $enc_disp), $link));
$USER_DESCRIPTION = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->description, $enc_db, $enc_disp), $link));
// MySQL文を生成する
$q4 = "INSERT INTO TWEET_PANORAMA (";
$q4 .= "CREATED_AT, ";
$q4 .= "ID, ";
$q4 .= "TEXT, ";
$q4 .= "USER_ID, ";
$q4 .= "USER_NAME, ";
$q4 .= "USER_SCREEN_NAME, ";
$q4 .= "USER_PROFILE_IMAGE_URL, ";
$q4 .= "USER_DESCRIPTION";
$q4 .= ") VALUES (";
$q4 .= "'".$CREATED_AT."', ";
$q4 .= "'".$ID."', ";
$q4 .= "'".$TEXT."', ";
$q4 .= "'".$USER_ID."', ";
$q4 .= "'".$USER_NAME."', ";
$q4 .= "'".$USER_SCREEN_NAME."', ";
$q4 .= "'".$USER_PROFILE_IMAGE_URL."', ";
$q4 .= "'".$USER_DESCRIPTION."'";
$q4 .= ")";
// MySQL文を実行する
$r4 = mysql_query($q4, $link) or die("クエリの実行に失敗しました。SQL:".$q4);
}
?>
<?php
$mysqlDatabase = "***.***.***.***";
$mysqlUsername = "***";
$mysqlPassword = "******";
$databaseName = array("***");
$enc_disp = "UTF-8";
$enc_db = "UTF-8";
// データの文字コードを変換する関数
function cnv_enc($string, $to, $from) {
$det_enc = mb_detect_encoding($string, "auto");
if ($det_enc and $det_enc != $to) {
return mb_convert_encoding($string, $to, $det_enc);
} else {
return $string;
}
}
// MySQLへ接続する
$link = mysql_pconnect($mysqlDatabase, $mysqlUsername, $mysqlPassword) or die("データベースへの接続に失敗しました。");
// MySQLへの接続をUTF-8に設定する
mysql_query("SET NAMES UTF8", $link);
// MySQLデータベースを選択する
mysql_select_db($databaseName[0], $link) or die("データベースの選択に失敗しました。");
// MySQLクエリを生成する
$q1 = "SELECT MAX(ID) AS MAX_ID FROM TWEET_PANORAMA";
// MySQLクエリを実行する
$r1 = mysql_query($q1, $link) or die("クエリの実行に失敗しました。SQL:".$q1);
$maxId = 1;
if (mysql_num_rows($r1) > 0) {
$row = mysql_fetch_object($r1);
$maxId = $row->MAX_ID + 1;
}
mysql_free_result($r1);
$user = "******";
$pwd = "******";
// Twitterに問い合わせる
$ch = curl_init();
if ($maxId < 4000000000) { $host = "http://twitter.com/statuses/friends_timeline.xml?count=100"; } else { $host = "http://twitter.com/statuses/friends_timeline.xml?since_id=".$maxId."&count=100"; } curl_setopt($ch, CURLOPT_URL, $host); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_USERPWD, "$user:$pwd"); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); $result = curl_exec($ch); curl_close($ch); $xml = simplexml_load_string($result) or die("XMLパースエラー"); // 値を参照する foreach ($xml->status as $status) {
$CREATED_AT = sprintf('%s', mysql_real_escape_string(cnv_enc($status->created_at, $enc_db, $enc_disp), $link));
$ID = sprintf('%s', mysql_real_escape_string(cnv_enc($status->id, $enc_db, $enc_disp), $link));
$TEXT = sprintf('%s', mysql_real_escape_string(cnv_enc($status->text, $enc_db, $enc_disp), $link));
$USER_ID = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->id, $enc_db, $enc_disp), $link));
$USER_NAME = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->name, $enc_db, $enc_disp), $link));
$USER_SCREEN_NAME = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->screen_name, $enc_db, $enc_disp), $link));
$USER_PROFILE_IMAGE_URL = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->profile_image_url, $enc_db, $enc_disp), $link));
$USER_DESCRIPTION = sprintf('%s', mysql_real_escape_string(cnv_enc($status->user->description, $enc_db, $enc_disp), $link));
// MySQL文を生成する
$q4 = "INSERT INTO TWEET_PANORAMA (";
$q4 .= "CREATED_AT, ";
$q4 .= "ID, ";
$q4 .= "TEXT, ";
$q4 .= "USER_ID, ";
$q4 .= "USER_NAME, ";
$q4 .= "USER_SCREEN_NAME, ";
$q4 .= "USER_PROFILE_IMAGE_URL, ";
$q4 .= "USER_DESCRIPTION";
$q4 .= ") VALUES (";
$q4 .= "'".$CREATED_AT."', ";
$q4 .= "'".$ID."', ";
$q4 .= "'".$TEXT."', ";
$q4 .= "'".$USER_ID."', ";
$q4 .= "'".$USER_NAME."', ";
$q4 .= "'".$USER_SCREEN_NAME."', ";
$q4 .= "'".$USER_PROFILE_IMAGE_URL."', ";
$q4 .= "'".$USER_DESCRIPTION."'";
$q4 .= ")";
// MySQL文を実行する
$r4 = mysql_query($q4, $link) or die("クエリの実行に失敗しました。SQL:".$q4);
}
?>
ユーザー名、パスワード、IPアドレスは*とさせて頂いた。
ここで重要なのは、1行目の #!/usr/local/Zend/Core/cgi-bin/php -q だ。※サーバー環境に応じてディレクトリは変更してください。
通常は2行目以降のようなPHPを記述していると思うが、サーバーでcronから実行させるためには1行目を追加する必要がある。このあたりは、shellプログラムのファイルの1行目にプログラムへのパスを記述するのと同じ感覚だ。
続いて、cronの設定方法。
echo "*/2 * * * * root /usr/local/Zend/Core/cgi-bin/php /abc.php" > /etc/cron.d/abc
上記コマンドをlinuxのコマンドプロンプトで実行する。/etc/cron.dディレクトリ配下にabcというファイルが生成される。ファイルの中身は */2 * * * * root /usr/local/Zend/Core/cgi-bin/php /abc.php となる。2分置きにrootユーザーで/abc.phpというプログラムを実行するという意味だ。ディレクトリ、実行ユーザー、時刻、または時間間隔の設定は必要に応じて変更してください。
ご質問のある方は気楽に問い合わせてください。
有限会社フランシスホープ 岡田 治
okadao@francis-hope.jp
パノラマの撮影制作サービスのフランシスホープ
Follow okadao on Twitter
有限会社フランシスホープ 岡田 治
okadao@francis-hope.jp
パノラマの撮影制作サービスのフランシスホープ
Follow okadao on Twitter
登録:
投稿 (Atom)