PHPでTwitterに画像付きメッセージ投稿

(1/1)
今回は、PHP で「Twitter API」を利用し、画像付きのメッセージを投稿する。画像は最大 4 つまで。動画を投稿することもできる。

サンプル・プログラム:実行例

PHPでTwitterに画像付きメッセージ投稿
「メッセージ」に送信したいテキストを入力し、「画像(ローカル)」に送信したい画像ファイルを選択し、「画像(URL)」に送信したい画像ファイルの URL を入力する。画像は、ローカルと URL を合わせて最大 4 個まで指定できる。それ以上は入力しても無視される。
「ツイート」ボタンを押すと、ツイートし、結果メッセージが表示される。

サンプル・プログラム

サンプル・プログラムの流れ

PHPでTwitterに画像付きメッセージ投稿
まず、画像ファイルを 1 つずつ取りだし、「Twitter API:POST media/upload」を使ってアップロードする。画像 URL から直接アップロードするため、組み込み関数  file_get_contents  が http通信に対応していることが必須である。
アップロードに成功すると、メディア ID を返す。これはツイートの時に必要になるので、配列 $media_ids に格納しておく。
1 つのツイートに含めることができる画像の数は 4 つなので、この作業を最大 4 回繰り返す。

次に、「PHP で Twitter に投稿(ツイート)する」と同じ要領で、「Twitter API:POST statuses/update」を使ってツイートする。オプションに配列 $media_ids を追加することで、先ほどアップロードした画像が付いたメッセージとなる。

解説:準備

Twitter API を利用する関数群はクラス pahooTwitterAPI として別ファイル "pahooTwitterAPI.php" に定義してある。このファイルを  require_once  できるパスに配置すること。

OAuth認証を利用するため、プログラムを Twitter に登録する必要がある。その手順については「PHP で Twitter に投稿(ツイート)する」を参照のこと。取得したパラメータは、クラス pahooTwitterAPI 冒頭にあるクラス定数に記載すること。

https通信を使うため、PHP から OpenSSL を利用できるようにしておく必要がある。その手順は「PHP の https 対応」を参照のこと。
プログラムがうまく動かなかったら、「Twitter への再登録が必要な場合も」を参照のこと。

Twitter API:POST media/upload

画像を含むメディア・ファイルをアップロードするための Twitter API である。
Twitter API (POST)
URL
https://upload.twitter.com/1.1/media/upload.json

入力パラメータ
項目名 フィールド名 内  容
メディアデータ(バイナリ) media string 【mediaまたはmedia_dataが必須】メディアデータ(バイナリ)。
メディアデータ(base64) media_data string 【mediaまたはmedia_dataが必須】メディアデータ(base64形式)。
応答データ(json) media_id メディアID media_id_string メディアID(文字列) size データサイズ image w 幅(ピクセル) h 高さ(ピクセル) image_type 形式

Twitter API:POST statuses/update

ツイートするための API である。
Twitter API (GET)
URL
https://api.twitter.com/1.1/statuses/update.json

入力パラメータ
項目名 フィールド名 内  容
投稿文 status string 【必須】投稿文。UTF-8でエンコードされたテキストで、140文字以下。
画像ID media_ids string 【任意】複数ある場合はカンマで区切る。
応答データ(一部)(json) id_str 投稿ID created_at 投稿日時 text 投稿文 user screen_name ユーザー名 retweet_count リツイート回数

解説:画像アップロード

0200: 
0201: /**
0202:  * Twitter API:メディアアップロード
0203:  * @param string $url    TwitterAPIのリクエストURL
0204:  * @param string $method GET|POST
0205:  * @param string $type   メディアタイプ(image|banner|media_data)
0206:  * @param string $data   メディアデータ(バイナリ)
0207:  * @return string メディアID/NULL:失敗
0208: */
0209: function upload($url$method$type$data) {
0210:     //キー生成
0211:     $signature_key = $this->_rawurlencode($this->TWTR_CONSUMER_SECRET) . '&' . $this->_rawurlencode($this->TWTR_ACCESS_SECRET);
0212: 
0213:     //メディアデータ
0214:     $media_data = ($type == 'media_data') ? base64_encode($data) : $data;
0215:     $option = array($type => $media_data);
0216: 
0217:     //パラメータ
0218:     $params = array(
0219:         'oauth_token'             => $this->TWTR_ACCESS_KEY,
0220:         'oauth_consumer_key'     => $this->TWTR_CONSUMER_KEY,
0221:         'oauth_signature_method' => 'HMAC-SHA1',
0222:         'oauth_timestamp'         => time(),
0223:         'oauth_nonce'             => microtime(),
0224:         'oauth_version'         => '1.0'
0225:     );
0226:     ksort($params) ;
0227: 
0228:     //バウンダリー生成
0229:     $boundary = 'p-a-h-o-o---------------' . md5(mt_rand());
0230: 
0231:     //POSTフィールド生成
0232:     $request_body  = '';
0233:     $request_body .= '--' . $boundary . "\r\n";
0234:     $request_body .= 'Content-Disposition: form-data; name="' . $type . '"; ';
0235:     $request_body .= "\r\n";
0236:     $request_body .= "\r\n" . $media_data . "\r\n";
0237:     $request_body .= '--' . $boundary . '--' . "\r\n\r\n";
0238: 
0239:     //リクエストヘッダー生成
0240:     $request_header = "Content-Type: multipart/form-data; boundary=" . $boundary ;
0241: 
0242:     //リクエスト文字列生成
0243:     $request_params = http_build_query($params, '', '&');
0244:     $request_params = $this->_rawurlencode($request_params);
0245:     $encoded_request_method = $this->_rawurlencode($method);
0246:     $encoded_request_url = $this->_rawurlencode($url);
0247: 
0248:     //シグネチャ生成
0249:     $signature_data = $encoded_request_method . '&' . $encoded_request_url . '&' . $request_params;
0250:     $hash = hash_hmac('sha1', $signature_data$signature_keyTRUE);
0251:     $signature = base64_encode($hash);
0252:     $params['oauth_signature'] = $signature;
0253: 
0254:     //ヘッダ文字列生成
0255:     $header_params = http_build_query($params, '', ',');
0256: 
0257:     //リクエスト用コンテキスト
0258:     $context = array(
0259:         'http' => array(
0260:             'method' => $method,         // リクエストメソッド
0261:             'header' => array(           // ヘッダー
0262:                 'Authorization: OAuth ' . $header_params,
0263:                 'Content-Type: multipart/form-data; boundary= ' . $boundary,
0264:             ),
0265:             'content' => $request_body,
0266:         ),
0267:     );
0268: 
0269:     // cURLを使ってリクエスト
0270:     $curl = curl_init() ;
0271:     curl_setopt($curl, CURLOPT_URL, $url);
0272:     curl_setopt($curl, CURLOPT_HEADER, 1); 
0273:     curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $context['http']['method']);
0274:     curl_setopt($curlCURLOPT_SSL_VERIFYPEERFALSE);   //証明書は無視
0275:     curl_setopt($curlCURLOPT_RETURNTRANSFERTRUE) ;   //結果を文字列で
0276:     curl_setopt($curl, CURLOPT_HTTPHEADER, $context['http']['header']);
0277:     curl_setopt($curl, CURLOPT_POSTFIELDS, $context['http']['content']);
0278:     curl_setopt($curl, CURLOPT_TIMEOUT, 5 );
0279:     $res1 = curl_exec($curl);
0280:     $res2 = curl_getinfo($curl);
0281:     curl_close($curl);
0282: 
0283:     //結果処理
0284:     $this->webapi = $url;
0285:     $json = substr($res1$res2['header_size']);
0286:     $this->responses = json_decode($json);
0287: 
0288:     //メディアID
0289:     if (isset($this->responses->media_id_string)) {
0290:         $res = (string)$this->responses->media_id_string;
0291:     } else if (isset($this->responses->errors)) {
0292:         $this->error   = TRUE;
0293:         $this->errmsg  = $this->responses->errors[0]->message;
0294:         $this->errcode = $this->responses->errors[0]->code;
0295:         $res = NULL;
0296:     } else if (isset($this->responses->id_str)) {
0297:         $res = $this->responses->id_str;
0298:     } else {
0299:         $res = NULL;
0300:     }

基本的には、「PHP で Twitter に投稿(ツイート)する」とで解説したリクエスト関数 request_user と同じである。バウンダリーを生成する部分が追加となっている。

解説:画像付き投稿

0329:     return $this->request_user($url$method$option);
0330: }
0331: 
0332: /**
0333:  * メディア付き投稿
0334:  * @param string $message 投稿メッセージ(UTF-8限定)
0335:  * @param array  $fnames  メディアデータのファイル名(配列)
0336:  * @return bool TRUE:リクエスト成功/FALSE:失敗
0337: */
0338: function tweet_media($message$fnames) {
0339:     static $url_upload    = 'https://upload.twitter.com/1.1/media/upload.json';
0340:     static $url_tweet     = 'https://api.twitter.com/1.1/statuses/update.json';
0341:     static $method        = 'POST' ;
0342: 
0343:     //メディアのアップロード
0344:     $media_ids = '';
0345:     $cnt = 0;
0346:     foreach ($fnames as $fname) {
0347:         $data = @file_get_contents($fname);
0348:         $media_id = $this->upload($url_upload, 'POST', 'media_data', $data);
0349:         if ($media_id == NULL)      break;
0350:         if ($cnt > 0)   $media_ids .= ',';
0351:         $media_ids .= $media_id;
0352:         $cnt++;
0353:         if ($cnt > 3)   break;       //最大4つまで
0354:     }
0355: 
0356:     //ツイート
0357:     if (! $this->error) {
0358:         $option = array('status' => $message, 'media_ids' => $media_ids);
0359:         $res = $this->request_user($url_tweet$method$option);
0360:     } else {
0361:         $res = FALSE;
0362:     }

基本的には、「PHP で Twitter に投稿(ツイート)する」とで解説したツイート関数 tweet と同じである。前半で、upload を呼び出して画像をアップし、メディア ID を配列 $media_ids に格納している。

参考サイト

(この項おわり)
header