開発環境整備する Zendでtwitterに接続します

twitterは気持ちよくつなげていると接続制限を食らうのでイラッ☆。

curlをインストール、pearのパスとか

curlが動きません。インストールします。

apt-get install curl php5-curl

phpinof()で逐次確認しましょう。
pearがどうも、見えてないみたい。

include_path = ".:/usr/share/php:ここにZendのパス"

twitter関連のライブラリをつかう

zendにあるみたいなので利用します。
動くまでapt-getとpearとinclude_pathの調整です。
php.iniがapache用とcli用と分かれていたりと
ちょこちょこワナがあるので冷静になることが必要です。
まちがっても奇声をあげてはいけません。
隣の人が心配してくれてムフフ画像をくれたりしますが、
うごかないという残念な状況は好転しないのでむなしくなるだけです。

require_once('./aa.php');
require_once './ii.php';

//とりあえずラッパーを作って安心するの巻
class myTwitter{
  //todo:アカウントを決めうちはまずい
  private $user1 = 'hoge';  private $pass1 = 'fuga';
  private $user2 = 'foo';  private $pass2 = 'bar';
  private $_twitter = null;

  public function __construct($num){
        if($num == 1){
          $this->_twitter = new Zend_Service_Twitter($this->user1, $this->pass1);
        }else{
          $this->_twitter = new Zend_Service_Twitter($this->user2, $this->pass2);
        }
  }

  //private
  private  function getTwitter(){
    if($this->_twitter == null){
          $this->_twitter = new Zend_Service_Twitter($this->user0, $this->pass0);
    }
    return $this->_twitter;
  }
  private function getAccount(){
    return $this->getTwitter()->account;
  }
  private function getStatus(){
    return $this->getTwitter()->status;
  }
  private function getUser(){
    return $this->getTwitter()->user;
  }
  private function getFavorite(){
    return $this->getTwitter()->favorite;
  }

  //public
  public function getVerifyCredentials(){
    return $this->getAccount()->verifyCredentials();
  }
  public function getFriendsTimeLine($user){
    return $this->getStatus()->friendsTimeline(array('id'=>$user));
  }
  public function getUserFriends($user){
    return $this->getUser()->friends(array('id'=>$user));
  }
  public function getUserFollowers(){//idうごかないっぽい
    return $this->getUser()->followers();
  }
  public function getFavorites($user){
    return $this->getFavorite()->favorites(array('id'=>$user));
  }
}

$twit = new myTwitter(1);
var_dump($twit->getFollowers());

大丈夫そうですね。

DBにデータを置く

あとはDBにデータを置いていくだけですね。
ここからは破綻しないように調整していく作業ですね。
イケてるSEさんがいてくれたらうまいこと設計してくれるのでしょうけど。
そんなものはいるわけないので試行錯誤していくことになります。
一応、一回つないだら45秒休む、それでもダメなら10分休む、という仕組みと
try-catchでくるみまくることで止まらずに動き続ける仕組みを考えます。

while(true){
  try{
    try{
      接続
      45秒休憩
      db処理
      }catch(Exception $e){echo $e;/*握る*/}
  }catch(Exception $e){echo $e;sleep(600);/*握って眠る*/}
}

無限ループして様子を見ることにします。
どうも、データをとるのに時間がかかりすぎな気がするので

  1. アカウントを100本ぐらい作って回す
  2. twitterにmailして制限を緩めてもらう
  3. WEBをパースしてみる

という方法を考え中です。
一個目はめんどくさいですね。DBにid/pass/貸し出し中管理カラムを持つのだと思います
二個目はどこまでも大胆ですね。
三個目はキモすぎるので避けたいですね。


DB部分は例えば↓のように馬鹿正直に突っ込んで後から再度集め直すという方法を考えています。
必要な接続が重複しまくりですが、プロセスを分けてCPUを最大に使う(並行処理)するためには
処理を細切れにしていく必要があると思います。
最終はphpが100本ぐらい立つのかもしれません。そのために必要な分離を今のうちから
仕込んでおかないといけないと考えます。だた、うまくいかない。

<? 
class myMap2DBfavo{
  private $db = null;/*DBを保持する*/
  private $twit = null;/*Twitterを保持する*/
  private $conectionlimit = null;/*接続制限をかけるかも?*/
  private $targetover = null; //この以上のお気に入りを持っているAccountを対象に調査する
  private $targlist = null;

  public function __construct($climit,$targover,$num){
        $this->twit = new myTwitter($num);
        $this->db   = MyDb::getDb();
        $this->connectionlimit = $climit;
        $this->targetover = $targover;
        $this->setFavoriteTarget();
  }
  
  //public
  public function run(){
        $this->getFavos();
  }

  //private
  private function EchoandLog($string){
        echo $string . "\n";
        Mylogger::logInfo($string);
  }

  private function setFavoriteTarget(){
        $sql = 'hoge' 
        try{
        $this->targlist = $this->db->fetchAll($sql);
        }catch(Exception $e){$this->EchoandLog( $e);}
        $this->EchoandLog( var_dump($this->targlist));
  }
  
  private function getFavos(){
        foreach($this->targlist as $id_){
          if($this->connectionlimit-- > 0){//接続制限未満なら。。。
                try{
                $response = $this->twit->getFavorites($id_["ACCOUNT"]);
                $this->EchoandLog( "お気に入りに接続したので45秒寝ます");sleep(45);
                foreach($response->status as $item){
                  $data = array( 'fuga');
                  try{
                        $this->db->insert('Fa',$data);
                  }catch(Exception $e){echo $e;}
                  $data = array('p');
                  try{
                        $this->db->insert('Fat',$data);
                  }catch(Exception $e){$this->EchoandLog( "既に取得済みお気に入り連関");}
                  $data = array('La' => date('Y/m/d H:s:i'));
                  try{
                        $this->db->update('T',$data,'A = '. $id_["A"]);
                  }catch(Exception $e){$this->EchoandLog( "反映失敗");}
                }
                }catch(Exception $e){$this->EchoandLog( $e);}
          }
        }
  }
}
?>

明日以降

API制限をクリアしたら、DB上にはデータが既にできている状態です。
WEB表示はcronで定期的にファイルに落としておいたものをAJAXで取り込んでいく方式
にしようかなと思っています。
DB群/PHPのクローラのサーバー群/WEB側と分けて、sshでWEB側に投げ込み、
AJAX->phpでwebブラウザに配布するという方式を考えています。
負荷的にもセキュリティー的にも楽かなと、思うわけです。
リアルタイムではありませんが、取得データがリアルタイムでは無いのでかまわないと考えています。


ということで明日以降データをテキストファイルに仕込むことを
かんがえようとおもいます。このプログラム全体がTwitterのfilter/map処理ですが、
明日以降の処理はまさにmapそのものです。
とはいえ、SQL一発をforeachでjsonにmapして置いておくだけだろうな、とは思います。
jsonがいまいち分かりませんので楽しみではあります。



ところで、Zendの中身のソースがとてもきれいです。
これを読むのも楽しそうです。