TwitterOAuthをComposerでインストールして使う

iconDecotterはTwitterOAuthというライブラリを利用してTwitter認証を行っていますが、このライブラリはだいぶアップデートされていたようなので、この機に新しいものに差し替えることにしました。
以前はライブラリのソースをアップロードしてrequireしていましたが、Composerでインストール出来るようになっていたので、今回はそちらでインストールするようにしました。

というか、そもそもComposer自体を使うのが初めてだったので、実はそこからでした。

Composerとは

Composerは、PHPライブラリの依存関係管理ツールだそうです。
Composer ドキュメント日本語訳

プロジェクト単位でライブラリ間の依存関係等を自分で定義しておけば、必要なパッケージを探しだしてインストールしてくれるツールのようです。

多数のライブラリを扱う場合には有用なようで、今回のように1個のライブラリが欲しくて導入するメリットはそんなに無いと思いますが、簡単に出来そうだったのでやってみることにしました。

Composerのインストール

Composer ドキュメント日本語訳

公式の日本語訳サイトに書いてありますが、curlでpharファイルを落として実行するだけで良いようです。
インストールしたいユーザーでログインし、下記のcrulコマンドを実行すると
composer.pharというファイルが出来るので、/usr/local/bin/composerに移動させます。

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

ユーザーのホームディレクトリにそのまま入れてよければ、このままcomposerを実行します。
※プロジェクトごとに変える時はディレクトリを移動します。

自分でcomposer.jsonを作成し、ライブラリ名の指定をしてからcomposer installというのが普通らしいのですが、今回は1個のライブラリを入れたいだけなので、下記のコマンドでOKでした。

composer require abraham/twitteroauth

実行するとこんな感じのメッセージが出て、インストール完了です。

Using version ^0.6.2 for abraham/twitteroauth
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing abraham/twitteroauth (0.6.2)
Downloading: 100%

Writing lock file
Generating autoload files

ユーザーのホームディレクトリにcomposer.jsonが作成されていて、更にvendorディレクトリも出来ているはずです。
composer経由でインストールしたライブラリは、vendorディレクトリ以下にインストールされていきます。

TwitterOAuthを使う

Composer使う場合の特徴として、requireはvendorディレクトリに作成されるautoload.phpを1個指定すれば、あとはuseでnamespaceを登録するところで自動的に必要な物をrequireしてくれるところがあります。

ですので、ライブラリを使用するための記述はこれだけでOKです。
※仮にインストールユーザー名を[user]としています。

require '/home/user/vendor/autoload.php';
use Abraham\TwitterOAuth\TwitterOAuth;

実際に認証したりAPIを利用したりする部分については、記事が充実しているのでここでは割愛します。
下記、参考にさせていただきました。

公式:TwitterOAuth PHP Library for the Twitter REST API

新 PHPでのTwitterOAuthの使い方と流れ(ログインの変わりに使う方法) | CODE COPILOT

abraham/twitteroauthを使う – Qiita

TwitterOAuthでプロフィール画像を変更する

以前の記事では、ライブラリに少々手を加えてアイコン画像の変更を行っていましたが、新しい方のライブラリでは特に変更せずとも、下記のようにすれば問題なく同様の操作が行えました。

//変更したい画像のBlobデータ
$imgblob = file_get_contents("test.png");
//画像BlobをBase64変換する
$imgblob_b64 = base64_encode($imgblob);

// OAuthオブジェクト生成
// ※各パラメータは定義済みということで。
$to = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);

//変更をリクエスト
$res = $to->post('account/update_profile_image', array('image' => $imgblob_b64));

if( $to->getLastHttpCode() == 200 ){
  //成功
  echo "update success";
} else {
  //失敗
  echo "update failed";
}

account/update_profile_image のリファレンスはこちら。
POST account/update_profile_image | Twitter Developers

TwitterOAuthの方のリファレンスにもありますが、POSTが上手くいったかどうかの判定は、getLastHttpCode()が200になっているかどうかを確認するのが良いようです。

TwitterOAuthでたまに発生するPHP Fatal errorについて

TwitterOAuthをこの環境で使用していると、たまにPHP Fatal errorが発生していることがあります。
詳細はわかりませんが、ライブラリがTwitterにリクエストするところでタイムアウトしているエラーのようです。

sample.phpというスクリプトからTwitterOAuthを使用していたとして、例えばこんなエラーログが出ることがありました。

PHP Fatal error:  Uncaught Abraham\\TwitterOAuth\\TwitterOAuthException: Operation timed out after 5001 milliseconds with 0 out of -1 bytes received in /home/user/vendor/abraham/twitteroauth/src/TwitterOAuth.php:400\nStack trace:\n#0 /home/user/vendor/abraham/twitteroauth/src/TwitterOAuth.php(334): Abraham\\TwitterOAuth\\TwitterOAuth->request('https://api.twi...', 'GET', 'Authorization: ...', Array)\n#1 /home/user/vendor/abraham/twitteroauth/src/TwitterOAuth.php(305): Abraham\\TwitterOAuth\\TwitterOAuth->oAuthRequest('https://api.twi...', 'GET', Array)\n#2 /home/user/vendor/abraham/twitteroauth/src/TwitterOAuth.php(179): Abraham\\TwitterOAuth\\TwitterOAuth->http('GET', 'https://api.twi...', 'users/show', Array)\n#3 /var/www/html/sample.php(49): Abraham\\TwitterOAuth\\TwitterOAuth->get('users/show', Array)\n#4 {main}\n  thrown in /home/user/vendor/abraham/twitteroauth/src/TwitterOAuth.php on line 400\n'

users/showを使う部分で、タイムアウトエラーしています。
外部サーバーへの通信なので、そういうことがあるのもおかしくないですが、ちょくちょくかなり長文のエラーログが出てしまうし、スクリプトは止まっているはずなので、あまりよろしくありません。

こうしたエラーが発生してしまうこと自体は仕方ないとして、回避策としては、getやpost、oauthのメソッドを使うところは全部tryで囲んでしまうようにします。

$to = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);
try {
  $res = $to->get( 'users/show', array('user_id' => $_SESSION['user_id']) );
} catch(Exception $e) {
  $res = false;
}

これで、Fatal errorで止まってしまうことはなくなるので、リクエスト自体が失敗していた場合のエラー表示をすればよいだけになります。

コメント

タイトルとURLをコピーしました