PHPでTwitter(現・X)に画像付きメッセージ投稿

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

(2025年8月22日).pahooEnv 導入

目次

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

PHPでTwitterに画像付きメッセージ投稿
本プログラムは、パラメータをGET渡すことで実行することもできる。
たとえば、"putTweetMedia.php?msg=%E5%B0%8F%E7%94%B0%E5%8E%9F%E5%9F%8E%E3%81%AF%E9%9B%A3%E6%94%BB%E4%B8%8D%E8%90%BD+https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttps%2Fwww.pahoo.org%2Fathome%2Falbum%2F2019%2Fimg20190907-173131e.jpg&reply=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttps%2Ftwitter.com%2Fpapa_pahoo%2Fstatus%2F123456789" のようにすると、"https://twitter.com/papa_pahoo/status/123456789" にリプライ(返信)する形で、メッセージ「小田原城は難攻不落」と画像ファイル "/athome/album/2019/img20190907-173131e.jpg" を付けることができる。

サンプル・プログラム

圧縮ファイルの内容
putTweetMedia.phpサンプル・プログラム本体
pahooTwitterAPI.phpTwitter APIに関わるクラス pahooTwitterAPI。
使い方は「PHPでTwitterに投稿(ツイート)する」などを参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
putTwitter.php 更新履歴
バージョン 更新日 内容
5.2.0 2025/08/22 .pahooEnv 導入
5.1.0 2024/05/18 twitter.com → x.com 変更対応
5.0.0 2023/07/02 Twitter API v2対応
4.1 2022/01/04 PHP8対応,リファラ・チェック改良
4.0 2016/02/11 pahooTwitterAPIクラスを分離
pahooTwitterAPI.php 更新履歴
バージョン 更新日 内容
5.6.0 2025/08/13 .pahooEnv導入
5.5.1 2024/11/23 __construct() -- PHP8.4における応急処置
5.5.0 2024/06/21 TwitterOAuth 7.0.0 対応
5.4.0 2024/05/18 twitter.com → x.com 変更対応
5.3.0 2023/08/15 tweet3() -- メディアのシャフル機能
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加

準備:PHP の https対応

クラウド連携や相手先サイトのデータを読み込むのに https通信を使うため、PHPに OpenSSLモジュールが組み込まれている必要がある。関数  phpinfo  を使って、下図のように表示されればOKだ。
OpenSSL - PHP
そうでない場合は、次の手順に従ってOpenSSLを有効化し、PHPを再起動させる必要がある。

Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dll
Linuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順

これで準備は完了だ。

準備:pahooInputData 関数群

PHPのバージョンや入力データのバリデーションなど、汎用的に使う関数群を収めたファイル "pahooInputData.php" が同梱されているが、include_path が通ったディレクトリに配置してほしい。他のプログラムでも "pahooInputData.php" を利用するが、常に最新のファイルを1つ配置すればよい。

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。

準備:pahooTwitterAPI クラス

pahooTwitterAPI.php

  11: // TwitterOAuth クラスをロードする.
  12: $version = explode('.', phpversion());
  13: if ($version[0>8) {
  14:     require __DIR__ . '/vendor/autoload.php';
  15: }
  16: use Abraham\TwitterOAuth\TwitterOAuth;
  17: 

Twitter API」を利用するためのクラスファイルが "pahooTwitterAPI.php" である。同梱のクラス・ファイル "pahooTwitterAPI.php" は include_path が通ったディレクトリに配置してほしい。他のプログラムでも pahooTitterAPIクラス を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。

Twitter API」を利用するために、API keyAPI key secretAccess TokenAccess Token secret が必要で、入手方法は「Twitter API - WebAPIの登録方法」を参照されたい。

PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

OAuth認証 および Twitter API へのアクセスには、TwitterOAuth を利用する。導入方法は公式サイトにあるように composer を使うことを推奨している。
TwitterOAuth 7.0.0PHP 8.4(2024年11月21日リリース)でいくつかのエラーが発生する。これは、引数に暗黙の null を指定することが非推奨になったためで、プログラムの改修が行われるまでは PHP 8.3 で利用することをおすすめする。

TwitterOAuth クラスをロードする。composer でインストールされたフォルダ "\vendor" を "pahooTwitterAPI.php" と同じフォルダへコピーすること。

pahooTwitterAPI.php

  37: /**
  38:  * コンストラクタ
  39:  * @param   なし
  40:  * @return  なし
  41: */
  42: function __construct() {
  43:     if (isset($_ENV['PAHOO_TWTR_CONSUMER_KEY'])) {
  44:         $this->TWTR_CONSUMER_KEY = $_ENV['PAHOO_TWTR_CONSUMER_KEY'];
  45:     }
  46:     if (isset($_ENV['PAHOO_TWTR_CONSUMER_SECRET'])) {
  47:         $this->TWTR_CONSUMER_SECRET = $_ENV['PAHOO_TWTR_CONSUMER_SECRET'];
  48:     }
  49:     if (isset($_ENV['PAHOO_TWTR_ACCESS_KEY'])) {
  50:         $this->TWTR_ACCESS_KEY = $_ENV['PAHOO_TWTR_ACCESS_KEY'];
  51:     }
  52:     if (isset($_ENV['PAHOO_TWTR_ACCESS_SECRET'])) {
  53:         $this->TWTR_ACCESS_SECRET = $_ENV['PAHOO_TWTR_ACCESS_SECRET'];
  54:     }
  55: 
  56:     // プロパティを初期化する.
  57:     $this->responses = array();
  58:     $this->webapi    = '';
  59:     $this->error     = FALSE;
  60:     $this->errmsg    = '';
  61:     $this->errcode   = 0;
  62: 
  63:     $this->connection = new TwitterOAuth($this->TWTR_CONSUMER_KEY, $this->TWTR_CONSUMER_SECRET, $this->TWTR_ACCESS_KEY, $this->TWTR_ACCESS_SECRET);
  64:     // v2使用を宣言
  65:     $this->connection->setApiVersion('2');
  66: 
  67:     // PHP8.4で暗黙的にnullableを指定することが非推奨になったため
  68:     // TwitterOAuthが対応するまでの応急処置
  69:     error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
  70: }

TwitterOAuth クラスは pahooTwitterAPI のコンストラクタでインスタンス化しておく。

pahooTwitterAPI.php

  30:     // OAuth用パラメータ
  31:     // https://apps.twitter.com/
  32:     public $TWTR_CONSUMER_KEY    = '';      // Cunsumer key
  33:     public $TWTR_CONSUMER_SECRET = '';      // Consumer secret
  34:     public $TWTR_ACCESS_KEY      = '';      // Access Token (oauth_token)
  35:     public $TWTR_ACCESS_SECRET   = '';      // Access Token Secret (oauth_token_secret)
  36: 

TwitterAPI を利用するために、クラスファイル "pahooTwitterAPI.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。

事前にプログラムを登録しておく必要があり、その方法は「Twitter API - WebAPIの登録方法」を参照されたい。入手したパラメータを、上述の変数に代入しておくこと。

Twitter API:POST /2/tweets

ツイートするには、「Twitter API:POST /2/tweets」を用いる。
WebAPIのURL
URL
https://api.twitter.com/2/tweets

入力パラメータ
フィールド名 要否 内  容
text 必須 投稿文。UTF-8でエンコードされたテキストで、140文字以下。
media media_ids 任意 メディアID。最大4つ。
reply in_reply_to_tweet_id> 任意 リプライID。
応答データ(json) id 投稿ID text 投稿文

Twitter API:POST media/upload

画像を含むメディア・ファイルをアップロードするAPIはv.1.1のままで、「Twitter API:POST media/upload」を用いる。
Twitter API (POST)
URL
https://upload.twitter.com/1.1/media/upload.json

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

解説:メディア付きツイート

メディア付きツイート
まず、リプライ先のIDとスクリーンネームを取り出す。
続いて、メッセージの中からユーザー関数 extractMediaURL( を使ってメディアURLを取り出す。
メディアURLが1つでもあれば、「Twitter API:POST media/upload」を使ってアップロードする。
アップロードに成功すると、メディアIDを返す。これはツイートの時に必要になるので、配列 $media_ids に格納しておく。
1つのツイートに含めることができる画像の数は4つなので、この作業を最大4回繰り返す。

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

pahooTwitterAPI.php

 839: /**
 840:  * 指定したテキストをツイートする.
 841:  * リプライ(返信)先を指定したり,メディアを投稿できる.
 842:  * Tweetet API v2 を使用する.
 843:  * @param   string $message 投稿メッセージ(UTF-8限定);メディアを指定するときは 'http(s)://' または 'file:/// ' を含める.メディアが5つ以上あるときにはランダムに4つを選ぶ.
 844:  * @param   string $reply   リプライ先のURL(省略可能)
 845:  * @return  bool TRUE:リクエスト成功/FALSE:失敗
 846: */
 847: function tweet3($message, $reply=NULL) {
 848:     $id    = NULL;
 849:     $name  = NULL;
 850: 
 851:     // リプライ先のidを取り出す.
 852:     if ($reply !NULL) {
 853:         if (preg_match('/\/([0-9]+$)/i', $reply, $arr> 0) {
 854:             $id = (string)$arr[1];
 855:         } else {
 856:             $this->error  = TRUE;
 857:             $this->errmsg = 'リプライ先のURLが間違っています';
 858:             return FALSE;
 859:         }
 860:     }
 861:     // スクリーンネームを取り出す
 862:     if ($reply !NULL) {
 863: //      if (preg_match('/https\:\/\/twitter\.com\/([^\/]+)\// i', $reply, $arr) > 0) {
 864:         if (preg_match('/https\:\/\/x\.com\/([^\/]+)\// i', $reply, $arr> 0) {
 865:             $name = (string)$arr[1];
 866:         } else {
 867:             $this->error  = TRUE;
 868:             $this->errmsg = 'リプライ先のURLが間違っています';
 869:             return FALSE;
 870:         }
 871:     }
 872: 
 873:     // メディアURLを取り出す.
 874:     $mediaURLs = array();
 875:     $str = $this->extractMediaURL($message, $mediaURLs);
 876:     // メディアが5つ以上あるときにはシャフルする.
 877:     if (count($mediaURLs>5)     shuffle($mediaURLs);
 878: 
 879:     // スクリーンネームを追加する.
 880:     if ($id !NULL) {
 881:         $str = '@' . $name . ' ' . $str;
 882:     }
 883: 
 884:     // メディア付きリプライを行う.(Tweetet API v2 を使用する)
 885:     if (count($mediaURLs> 0) {
 886:         $media_ids = array();
 887:         $cnt = 0;
 888:         // メディアのアップロード.
 889:         // Tweetet API v1.1 を使用する(v2にメディアアップロードが未実装のため)
 890:         $this->connection->setApiVersion('1.1'); 
 891:         foreach ($mediaURLs as $fname) {
 892:             $tmpname = $this->media2temp($fname);
 893:             if ($tmpname == FALSE) {
 894:                 echo 'failure';
 895:                 exit(1);
 896:             }
 897: //          $media = $this->connection->upload('media/upload', ['media' => $tmpname]);
 898:             $media = $this->connection->upload('media/upload', ['media' => $tmpname], ['chunkedUpload' => true]);   // twitteroauth 7.0.0 対応
 899:             unlink($tmpname);
 900:             if (! isset($media->media_id_string))       break;
 901:             $media_ids[] = (string)$media->media_id_string;
 902:             $cnt++;
 903:             if ($cnt > 3)   break;      // 最大4つまで
 904:         }
 905: 
 906:         // メディア付きリプライ
 907:         $this->connection->setApiVersion('2'); 
 908:         $option = [
 909:             'text' => $str,
 910:             'media' => [
 911:                 'media_ids' => $media_ids
 912:             ]
 913:         ];
 914:         if ($id !NULL) {
 915:             $option = array_merge($option, [
 916:                 'reply' => [
 917:                     'in_reply_to_tweet_id' => $id
 918:                 ]
 919:             ]);
 920:         }
 921: 
 922:     // メディアなしリプライを行う.
 923:     } else {
 924:         $option['text'] = $str;
 925:         if ($id !NULL) {
 926:             $option = array_merge($option, [
 927:                 'reply' => [
 928:                     'in_reply_to_tweet_id' => $id
 929:                 ]
 930:             ]);
 931:         }
 932:     }
 933: //  $status = $this->connection->post('tweets', $option, TRUE);
 934:     $status = $this->connection->post('tweets', $option, ['jsonPayload' => true]);  // twitteroauth 7.0.0 対応
 935:     $this->webapi = 'https://api.twitter.com/2/tweets';
 936: 
 937:     // 処理に成功した.
 938:     if ($this->isSuccess()) {
 939:         $this->responses = $status->data;
 940:         $this->errcode   = NULL;
 941:         $this->errmsg    = '';
 942:         $this->error     = FALSE;
 943:         $res = TRUE;
 944:     // 処理に失敗した.
 945:     } else {
 946:         if ($this->isAuthError() == FALSE) {
 947:             $this->errmsg = $status->detail;
 948:             $this->error  = TRUE;
 949:         }
 950:         $res = FALSE;
 951:     }
 952:     return $res;
 953: }

参考サイト

(この項おわり)
header