質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

twitterAPIを使ってbotを作成中 「Error: Cannot use object of type stdClass as array」が解決できない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,508

score 10

前提・実現したいこと

PHPでTwitterAPIを使って、botを作っています。

botでしたいことは、
指定した1つのアカウントのフォロワーの中で、
プロフィール文に指定したキーワード(経営者,社長,ceo等)を含んでいる人のツイートを最新順で数件取得し、
その中でいいね数が一定以上(このプログラムでは20件)のツイートを
リツイートする
というものです。

処理の流れは、
指定した1つのアカウントのフォロワーリストを取得する。
取得したフォロワーリストのツイートを取得する。
取得したツイートのいいね数が20以上だった場合ツイートを配列に格納する。
配列内に格納されたツイートをリツイートする。
という流れで作成しています。

■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

実行すると、下記エラーが出てきます。
stdClassのobject?をforeachで配列として使っているから怒られているっぽいです。
取得したmanagers_idsの中にいくつかstdClassが入っているらしく、
繰り返しの中でそのstdClassが来るとエラーが出て処理が終了してしまいます。

このstdClassが来た時に繰り返しをスキップする方法で解決したいのですが、
stdClassかどうかの判別方法が分からず苦戦しております...

PHP Fatal error:  Uncaught Error: Cannot use object of type stdClass as array in /home/vagrant/bot_php/twitter_bot.php:76
Stack trace:
#0 {main}
  thrown in /home/vagrant/bot_php/twitter_bot.php on line 76

該当のソースコード

<?php

require_once(__DIR__ . '/config.php');

use Abraham\TwitterOAuth\TwitterOAuth;

$connection = new TwitterOAuth(
  CONSUMER_KEY,
  CONSUMER_SECRET,
  ACCESS_TOKEN,
  ACCESS_TOKEN_SECRET);

$managers_ids = [];
$managers_friends_infos = [
  'id' => [],
  'description' => []
];
$managers_popular_tweets = [];

$first_manager = $connection->get("users/show", [
  'id' => '3145701020',
]);

for ( $i = 0; $i < ceil($first_manager->followers_count / 200); $i++ ) { // フォロワーの取得は一度に200人までしかできないので繰り返しで取得
  if ( $i !== 0 ) {
    $first_managers_friends = $connection->get("followers/list", [
      'id' => '3145701020',
      'cursor' => $cursor, // 二週目以降は$cursorでさっき取得した次の値から取得するようにする
      'count' => '200',
      'skip_status' => 'true'
    ]);
  } else {
    $first_managers_friends = $connection->get("followers/list", [
      'id' => '3145701020',
      'count' => '200',
      'skip_status' => 'true'
    ]);
  }
  for ( $t = 0; $t < count($first_managers_friends->users); $t++) { //取得したフォロワーのidとプロフィール分を1人ずつ格納する
    $managers_friends_infos['id'][] = $first_managers_friends->users[$t]->id;
    $managers_friends_infos['description'][] = $first_managers_friends->users[$t]->description;
  }
  $cursor = $first_managers_friends->next_cursor; //次に取得し始める場所を格納する
}


$search_words = array("経営者", "ceo", "CEO", "社長", "代表", "創業者", "創始者"); //プロフィールの中からor検索するキーワード

for( $i = 0; $i < count($managers_friends_infos['id']); $i++ ) { //フォロワーの人数分繰り返す
  foreach ($search_words as $search_word) { //search_wordsを1つづつ確認する
    if( strpos( $managers_friends_infos['description'][$i], $search_word ) !== false) { // $search_wordを含んでいるか確認
      array_push($managers_ids, $managers_friends_infos['id'][$i]); // 含んでいたらmanagaers_idsにidを格納
      break; //search_wordsの繰り返しを抜けて次の人に
    } else {
      continue; //別にこの処理はいらないな
    }
  }
}

// ここまでで、
// $managers_idsに、最初に指定したアカウントのフォロワーの中で、プロフィールの中に検索ワードを含むアカウントのidが格納されている

$count_managers = 1; //現在の繰り返しが何人目なのかを下で出力するために定義している

foreach ($managers_ids as $managers_id) { //$managers_idsを1つずつ繰り返す
  $managers_tweets = $connection->get("statuses/user_timeline", [ //この処理で、1人ずつ5件のツイートを取得する。
    'id' => $managers_id,
    'count' => '5',
    'exclude_replies' => 'true', //リプライを除外 5件取得して2件リプライだったら合計取得ツイート数は3件になる
    'include_rts' => 'false' //リツイートも除外 リプライと同様 先に5件取得してから、除外する為取得件数が5以下になることがある
  ]);

  $count_managers++;

    for ( $i = 0; $i < count($managers_tweets); $i++) { //現在の繰り返しのアカウントから取得したツイート数だけ繰り返す
      if ( $managers_tweets[$i]->favorite_count >= 20 ) { // いいねの数が20以上の場合
        $managers_popular_tweets[] = $managers_tweets[$i]->id; // $managers_popular_tweets[]にツイートidを格納する
      }
    }
}

if ($connection->getLastHttpCode() === 200) {
  print_r($managers_popular_tweets);
  foreach ($managers_popular_tweets as $managers_popular_tweet) { // $managers_popular_tweetの中のツイートを1つずつ繰り返す
    $managers_tweets_retweet = $connection->post("statuses/retweet/$managers_popular_tweet"); // $managers_popular_tweetに格納されているidに該当するツイートをリツイートする
    echo "成功" . PHP_EOL;
  }
}

試したこと

try catchで書いてみたり、ifで当てずっぽうでstdClassじゃないかどうかみたいなことを書いてみましたが、
もちろんできませんでした。

他の解決方法でも構いませんのでどなたかご教示いただけますと幸いです...
よろしくお願いいたします。

p.s. TwitterAPIって15分毎の使用回数制限みたいなのがある?ので開発テストが全然捗らないです...みなさんどうしてますか...?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kawax

    2019/02/03 19:59

    こういうスパムばかりだからAPIは制限され続けてもうまともに使えなくなった

    キャンセル

  • GakuNaito

    2019/02/03 20:06

    コメントありがとうございます。
    スパムという認識は持っていなかったのですが、申し訳ございません...。
    私自身が、有名な人(最初に指定するアカウント)がフォローする経営者達のツイートを
    効率よく拝見するために作成しようとしているのですが、
    これはスパム行為にあたってしまうことでしょうか...?

    キャンセル

回答 1

check解決した方法

0

下記処理を追加することでできました。

if ( !is_array ( $managers_tweets )) {
    continue;
} 


stdClass以外は配列で返ってくるので配列じゃなければスキップという形で解決しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る