Twitterの昨日のツイートを取得するクラス

提供:wiki - PCスキルの小技・忘却防止メモ
移動: 案内, 検索

Twitterの昨日のツイートを取得するクラス

目次

概要

制限回数があるらしいので、最初はAPIを叩いてJSON書き出し。2回目以降はAPIを叩かずにJSONを読むって感じ。

twitteroauthは必要(※「Twitter APIとの連携」を元にしている)

ソース

<?php
	/**
	 * class_twitter_api_support.php
	 * curl()のサポートクラス
	 * 
	 * 公式:ヘルプ
	 * https://dev.twitter.com/docs/api/1.1
	 * 
	 * ■挙動例
	 * 1回目(2014/04/18)実行する
	 *    ->APIを叩いてブラウザとJSONファイル出力
	 * 
	 * 2回目(2014/04/18)実行する
	 *    ->JSONファイルからブラウザ出力
	 * 
	 * 3回目(2014/04/19)実行する
	 *    ->JSONファイルの「id_str」以降のツイートを対象にして
	 *      APIを叩いてブラウザとJSONファイル出力
	 * 
	 * 4回目(2014/04/20)実行する:ツイートが無かったとき
	 *    ->対象日のツイートが無かった場合「id=0」にしている。
	 *      ※JSONの「id_str」は前回の4/19分を入れておく。
	 * 
	 * 5回目(2014/04/18)実行する:想定していない動作
	 *    ->前回のJSONの「id_str」以降が対象のためツイートは見つからない
	 *      ※APIを叩く:想定していない動作のため
	 * 
	 * ■他人のツイートを指定したいとき
	 * 制限回数の絡みに注意すること。通常は気にしなくて良いと思う。
	 * 
	 */
	require_once(dirname(__FILE__) . "/twitteroauth/twitteroauth.php");
	class ClassTwitterApiSupport{
		
		private $_apiKey;
		private $_apiSecret;
		private $_accessToken;
		private $_accessTokenSecret;
		
		private $_runApi = false;
		
		private $_scriptUri;
		private $_tweetFileName = "tweet_data.json";
		
		private $_tweetCount = 200;
		private $_tweetDay;
		private $_tweetUser = "";
		
		function __construct($apiKey, $apiSecret, $accessToken, $accessTokenSecret){
			ini_set("date.timezone", "Asia/Tokyo");
			
			$this->_apiKey            = $apiKey;
			$this->_apiSecret         = $apiSecret;
			$this->_accessToken       = $accessToken;
			$this->_accessTokenSecret = $accessTokenSecret;
			
			$this->_scriptUri = "http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER["REQUEST_URI"]) . "/";
			
			$this->setTweetDay( date("Y-m-d", strtotime("-1 day")) );
		}
		
		function __destruct(){}
		
		/**
		 * ファイル名のセット・変更
		 **/
		public function setFileName($tweetFileName) {
			$this->_tweetFileName = $tweetFileName;
		}
		
		/**
		 * 取得するツイート件数のセット・変更
		 **/
		public function setTweetCount($tweetCount) {
			$this->_tweetCount = $tweetCount;
		}
		
		/**
		 * 取得するツイート日のセット・変更
		 **/
		public function setTweetDay($tweetDay) {
			$this->_tweetDay = $tweetDay;
		}
		
		/**
		 * 取得するユーザ名のセット・変更
		 **/
		public function setTweetUser($tweetUser) {
			$this->_tweetUser = $tweetUser;
		}
		
		/**
		 * JSONファイルがあっても無視してAPIを叩く
		 **/
		public function setRunApi($runApi=false) {
			$this->_runApi = $runApi;
		}
		
		/**
		 * ツイートを取得。
		 * since_id   :以降のツイート:「4以降のツイート」が欲しいとき「3」を指定
		 * max_id     :以前のツイート:「4以前のツイート」が欲しいとき「4」を指定
		 **/
		public function getTweet($since_id=false, $max_id=false) {
			$twObj = new TwitterOAuth($this->_apiKey, $this->_apiSecret, $this->_accessToken, $this->_accessTokenSecret);
			
			$apiUrl = "https://api.twitter.com/1.1/statuses/user_timeline.json";
			
			$condition = array();
			$condition["count"] = $this->_tweetCount;
			
			if ($since_id != false) {
				$condition["since_id"] = $since_id;
			}
			
			if ($max_id != false) {
				$condition["max_id"] = $max_id;
			}
			
			if ($this->_tweetUser != "") {
				$condition["screen_name"] = $this->_tweetUser;
			}
			
			$req = $twObj->OAuthRequest($apiUrl, "GET", $condition);
			
			return json_decode($req);
		}
		
		/**
		 * id_strから-1した値を返す
		 * $id_str
		 **/
		private function makeMaxId($id_str) {
			$tmp = "";
			
			$charNum = strlen($id_str);
			
			$need = 1;
			do {
				$tmpNum = substr($id_str, $charNum-$need);
				
				if (0 < (int) $tmpNum) {
					$fst = substr($id_str, 0, $charNum-$need);
					$lst = (int) $tmpNum - 1;
					$tmp = (string) $fst . (string) $lst;
				}
				
				if ($charNum < $need) {
					break;
				}
				$need++;
			}
			while($tmp == "");
			
			return $tmp;
		}
		
		/**
		 * ツイートから使う値だけ抜き出して返す
		 * $tweetObj : ツイート
		 **/
		private function pullTweetData($tweetObj) {
			$tmpObj = array();
			$tmpObj["id"]          = $tweetObj->id;
			$tmpObj["id_str"]      = $tweetObj->id_str;
			$tmpObj["text"]        = $tweetObj->text;
			$tmpObj["created_at"]  = $tweetObj->created_at;
			$tmpObj["_created_at"] = date('Y-m-d', strtotime($tweetObj->created_at));
			
			return (object) $tmpObj;
		}
		
		/**
		 * ツイートが対象日より古いかチェック
		 * $tweetObj :ツイートのオブジェクト
		 **/
		private function checkOlderDay($tweetDay) {
			$diff = ( strtotime($tweetDay) - strtotime($this->_tweetDay) ) / ( 3600 * 24 );
			if ($diff < 0) {
				return true;
			}
			else {
				return false;
			}
		}
		
		/**
		 * ツイート一覧から指定日を抜き出し、最後のIDを返す
		 * $tw_arr : ツイート一覧
		 **/
		private function pullTweetForDate($tw_arr) {
			$tmpObj = array();
			
			$oldTweet = false;
			
			$tmpObj["tweet"] = array();
			foreach ($tw_arr as $idx => $val) {
				$created_at = date('Y-m-d', strtotime($tw_arr[$idx]->created_at));
				// echo $created_at . " - " . $tw_arr[$idx]->id_str . "<br>";
				
				// 対象日より古いツイートだったら終了
				if ( $this->checkOlderDay($created_at, $this->_tweetDay) ) {
					$oldTweet = true;
					break;
				}
				
				if ($created_at == $this->_tweetDay) {
					array_push($tmpObj["tweet"], $this->pullTweetData($tw_arr[$idx]));
				}
			}
			// echo "<hr />";
			
			if ($oldTweet == true) {
				$tmpObj["lastTweet"] = false;
			}
			else {
				$tmpNum = count($tw_arr) - 1;
				$tmpObj["lastTweet"] = $this->pullTweetData($tw_arr[$tmpNum]);
			}
			
			return $tmpObj;
		}
		
		/**
		 * 指定日のツイートを取得
		 * $since_id - 指定ID以降のツイートを取得
		 * $max_id   - 指定ID以前のツイートを取得
		 **/
		public function getTweetTargetDay($since_id=false, $max_id=false) {
			$tweetAry = array(); // 指定日のツイート配列
			$endTweet = false;   // 
			$evasion  = 1;       // 強制脱出用
			
			do {
				// ツイートをまるっと取得
				$tw_arr = $this->getTweet($since_id, $max_id);
				
				// 取得したツイートから指定日のみ抜き出し
				$tmpTweetObj = $this->pullTweetForDate($tw_arr);
				
				// 指定日のツイートを追加
				if (0 < count($tmpTweetObj["tweet"])) {
					$tweetAry = array_merge($tweetAry, $tmpTweetObj["tweet"]);
				}
				
				// 前のツイートを調査する必要があるかチェック
				if ($tmpTweetObj["lastTweet"] == false) {
					break;
				}
				else {
					$max_id = $this->makeMaxId($tmpTweetObj["lastTweet"]->id_str);
				}
				
				// 最後までチェック完了したとき:200件取得できないとき
				if (count($tw_arr) < $this->_tweetCount) {
					$endTweet = true;
				}
				
				if (15 <= $evasion) {
					break;
				}
				$evasion++;
		  	}
			while($endTweet === false);
			
			return $tweetAry;
		}
		
		/**
		 * ツイートファイルがあれば返す、無ければ諸々処理して返す
		 **/
		public function getTweetData() {
			if ($this->_runApi == false) {
				$contents = @file_get_contents($this->_scriptUri . $this->_tweetFileName);
			}
			else {
				$contents = false;
			}
			
			$since_id = false; // 指定ID以降のツイートを取得
			$created_at = "";  // ツイートの投稿日
			
			if ($contents !== false) {
				$contentsAry = json_decode($contents);
				
				$since_id   = $contentsAry[0]->id_str;
				$created_at = $contentsAry[0]->_created_at;
			}
			
			if ($created_at == $this->_tweetDay) {
				// 対象日のツイート出力済み
				$tweetAry = $contentsAry;
			}
			else {
				$tweetAry = $this->getTweetTargetDay($since_id, false);
				
				if ( count( $tweetAry ) == 0) {
					// 対象日のツイートなし:ダミーデータをセット
					$tweetAry = array(array("id"=>0, "id_str"=>$since_id, "text"=>"対象日のツイートなし", "created_at"=>$this->_tweetDay, "_created_at"=>$this->_tweetDay));
				}
				
				$localPath = $this->_tweetFileName;
				$data = json_encode($tweetAry);
				
				$rsc = fopen($localPath, "w");
				flock($rsc, LOCK_EX);
				fwrite($rsc, $data);
				flock($rsc, LOCK_UN);
				fclose($rsc);
			}
			return $tweetAry;
		}
	}

呼出し

呼出しというかサンプルというか…そんなヤツ。

<?php
	require_once(dirname(__FILE__) . "/class_twitter_api_support.php");
	
	define("API_KEY",                           "xxxx");
	define("API_SECRET",                     "xxxx");
	define("ACCESS_TOKEN",               "xxxx");
	define("ACCESS_TOKEN_SECRET", "xxxx");
	
	$tweetObj = new ClassTwitterApiSupport(API_KEY, API_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
	
	//$tweetObj->setTweetDay("2013-10-09"); // 昨日以外のときはコメント解除+日にち指定
	//$tweetObj->setTweetUser("sake_wiki");    // 他人のツイートのときはコメント解除+ユーザー指定
	//$tweetObj->setRunApi(true);                     // デバッグ用に何回もAPIを叩く。
	
	$tweetAry = $tweetObj->getTweetData();
	
	echo "<html>";
	echo "<head>";
	echo '<meta charset="UTF-8" />';
	echo "<body>";
	
	if ($tweetAry[0]->id != 0) {
		echo "ツイートある。";
	}
	else {
		echo "ツイートない。";
	}
	
	echo "<hr />";
	echo "<pre>";
	print_r($tweetAry);
	echo "</pre>";
	
	echo "</body>";
	echo "</html>";

関連項目