2009年11月8日日曜日

テスト


日本丸メモリアルパークから観覧車を眺めるパノラマ

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としよう。

#!/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);


}
?>

ユーザー名、パスワード、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