2つのif 構文が1つしか動作してくれない

このQ&Aのポイント
  • PHP修行中の者が、自分のTwitterのタイムラインをFC2ブログに投稿するスクリプトを書きたいと思っているが、if構文がうまく動作しないため困っている。
  • 具体的には、2つのif構文がうまく動作せず、1つしか動かない。また、最新のテキストのみ抽出し、昇順に並び替えたい。
  • 質問者は、if構文の改善方法やテキスト抽出の方法、テキストの並び替え方を知りたいとしている。
回答を見る
  • ベストアンサー

2つのif 構文が1つしか動作してくれない

唐突に質問失礼致します。PHP修行中の者です。 自分のTwitterのタイムラインをFC2ブログに投稿するスクリプトを書きたいと思い、ここ数ヶ月、PHPの本を片手に、200以上のPHPサイトのブラウザタブ開きながら試行錯誤しているのですが暗礁に乗り上げてしまって困っています。 恐縮ながら、どうか御教授いただけたら幸いに存じ上げます。 ブログに投稿することまではできるのですが、今できなくて困っていることは、 1、2つ設置しているif 構文が1つしか動いてくれないので2つ動かしたい。 2、1日分(昨日分=24時間前)の最新(更新分)のテキスト(ツイート)のみ抽出して1日毎に投稿するようにしたい。 3、テキスト(ツイート)の時間のならびを昇順(古い順)にしたい。 の3つです。 改善法をご存じの方がいらっしゃいましたら1~3のいずれか1つだけでもいいので御教授いただけたら幸いに存じ上げます。 今は下記のように書いています。↓ ///////////////////////////////// $url = "http://api.twitter.com/1/statuses/user_timeline.json?&include_rts=true&count=30&screen_name=(ユーザー名)&page=".$_POST['page']; $tweets = json_decode(file_get_contents($url)); $str = ''; $pat1='/^RT/'; $pat2='/@/'; $m1 = preg_match($pat1, $str); foreach ($tweets as $val) { if ($pat1 && $pat2){ echo $str .= $val->retweeted_status->text; } if (!$pat1){ echo $str .= $val->text; } $str .='<br />' .date('Y-m-d H:i:s', strtotime($val->created_at) + 9*3600) .'<br /><br />'."\n"; } var_dump($tweets); try{ $bm->postEntry("ユーザー名".date("Y年m月d日", $timestamp .= strtotime("-1 day"))."のつぶやきまとめ", " [". $str ."]"); ///////////////////////////////// これで実行すると、 1、if 構文に関しては、最初の「if ($pat1 && $pat2){echo $str .= $val->retweeted_status->text;」は読み込んでくれますが、次のif構文の「if (!$pat1){echo $str .= $val->text;」は読み込まれずに、「空白」が出力されてしまいます。 やりたいことは文頭がRTで始まる場合は$val->retweeted_status->textで、それ以外は$val->textにしたいのです。 (全てval->textに指定すれば空白なく全て表示できるのですが、RTが文頭につくval->textのものは文末が省略されてしまっているので、全文が書かれているretweeted_status->textに変えたいのです) 2、テキスト(ツイート)の最新のものを抽出するためには「$url = "http://api.twitter.com/1/statuses/user_timeline.json?&include_rts=true&count=30&screen_name=(ユーザー名)&page=".$_POST['page'];」のどこかを書き加えればいいとは思うのですが、どう書き加えれればいいか分からなくて困っています。 Twitter API仕様書によれば http://watcher.moe-nifty.com/memo/docs/twitterAPI20.txt (転載はじめ) //////////////////////////////// user_timeline 自分の過去24時間以内に update されたステータスから最大20件(count引数使用時は最大200件)を取得する。 引数 id を指定すれば、その id のユーザのステータスを取得できる URL: http://twitter.com/statuses/user_timeline.format http://twitter.com/statuses/user_timeline/id.format (format は xml, json, rss, atom のうちのいずれかを指定) since=日時 (オプション) 指定した日時以降に update されたステータスを取得する 指定した日時以降に update されたステータスを取得する 日時のフォーマットは RFC822(の「5. 日付と時刻仕様」) に従う なお、本オプションの代わりに http リクエストヘッダで If-Modified-Since を明示することで、日時を指定することもできる 例: http://twitter.com/statuses/user_timeline.rss?since=Tue%2C+27+Mar+2007+22%3A55%3A48+GMT 2007年3月27日22時55分48秒GMT以降に update されたステータスを RSS 形式で取得する //////////////////////////////// (転載終わり) …と記載してありますが、実際に.jsonでフォーマットしてデフォルトで20件分の取得だったとしても、「過去24時間以内」ではなく、それより前(1日以上前)のものまで取得されてしまいます。 これをどのように書き変えればいいのでしょうか? 3、最後にこの上記のテキスト(タイムライン)を昇順(古い順)で出力したいのですが、urlからの入力書き換えで可能でしょうか? あるいは今回だと降順(新しい順)しか出力できず、昇順にするためには後から並び替えなければならないのでしょうか? その並び替え方を教えていただきたいです。 質問が多くて誠に申し訳ございません。 改善法をご存じの方がいらっしゃいましたら1~3のいずれか1つだけでもいいので御教授いただけたら幸いに存じ上げます。

  • walsch
  • お礼率89% (224/250)
  • PHP
  • 回答数3
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • 4017B
  • ベストアンサー率73% (1305/1776)
回答No.2

回答No.1に補足。 とりあえず Q.1 に関しては… ━ ココから ━━━━━━━━━━━━━━━━━━━━━━━━ foreach ( $tweets as $val ) { /* 文頭に「RT」が含まれる */ if ( 1 === preg_match( "/^RT/s", $val ) ) { echo "<p>これはRTです。</p>\n"; } /* 文内に「@」が含まれる */ else if ( 1 === preg_match( "/\B@\w+/", $val ) ) { echo "<p>これは@です。</p>\n"; } /* 上記のいずれにも属さない */ else { echo "<p>これはその他です。</p>\n"; } } ━ ココまで ━━━━━━━━━━━━━━━━━━━━━━━━ ~こんな感じの振り分けでOKなはず( $tweets が事前に配列化されてるという条件で)。実際の具体的な処理内容は、そちらでアレンジしてください。 すごく長ったらしい正規表現じゃなければ、直に関数内に正規表現は含んでいた方が、後々のメンテとか楽だと思うかな??後、理由は不明だけど、正規表現を変数にして扱うと、物によっては動作が変になるんで。直書きの方が間違いない(キリッ! P.S. 特筆してない場合は「PHP:v5.3x」という前提で話してますんで、そのつもりで。

walsch
質問者

補足

4017Bさん。再度の丁寧なコメントありがとうございます。 本当に初心者の私にも分かりやすく見やすく頂いて恐悦至極の極みです。 そしてメンテの考慮や直書きのアドバイス、とても参考になります。 バージョンを書き忘れていて申しわけございません。v5.3.5です。 御教授頂いたように下記のように書き直し、実行しましたところ、誠に残念ながら状況は同じく変わらず、「/* 文頭に「RT」が含まれる */」も「/* 文内に「@」が含まれる */」の処理が拾われずに「Warning: preg_match() expects parameter 2 to be string」のエラーを出して飛ばされ、「/* 上記のいずれにも属さない */」の処理のみが実行されました。 foreach ($tweets as $val) { /* 文頭に「RT」が含まれる */ if ( 1 === preg_match( "/^RT/s", $val ) ) { echo $str .= $val->retweeted_status->text; } /* 文内に「@」が含まれる */ else if ( 1 === preg_match( "/\B@\w+/", $val ) ) { echo $str .= $val->retweeted_status->text; } /* 上記のいずれにも属さない */ else { echo $str .= $val->text; } おそらく、4017Bさんがカッコ書きで仰られていたように「( $tweets が事前に配列化されてるという条件で)」ということなのかな…? と思い、foreach の前に、$tweets = array( );を書き加えて配列化しようとしているのですが、array( )内を、($str)や($val)や($val->retweeted_status->text)や($val->retweeted_status->text, $val->retweeted_status->text)等々を入れて試したのですが、どれも 1 => nullで通りませんでした。 もしお手数でなければ、後見の方のことも含めて引き続き加筆していただけたら幸いに存じ上げます。

その他の回答 (2)

  • 4017B
  • ベストアンサー率73% (1305/1776)
回答No.3

>エラー "Warning: preg_match() expects parameter 2 to be string" ~て言うのは意訳すると、「警告: preg_match() を実行したら、2番目の変数にPHP的に期待した物じゃない変なのがあるよ?」って意味。いちいちウルサイ奴と思われるでしょうが、エラー表示には全て意味があり、そこには最も役に立つ手掛かりと答えがある。ちゃんと自分の目で見て聞いて考えるべし。 PHPに限らず、プログラム側から表示されるエラーは、非常に簡単な中学英語レベルです(世界中の技術者に向けて書いてあるので、非英語圏のネイティブじゃない人の事も考慮してる)。PHPみたいなメジャーな開発言語なら、エラーをそのままコピペしてGoogle検索するだけで2秒以内にエラーの意味くらい分ります。 ちなみに上記エラーはテンプレみたいな物で、だいたいは引数(この場合は第2変数)の中身がnull値になってる時に良く表示されます。多分、回答文をそのままコピペしたんじゃないかな?ちゃんとアレンジしろと書いて置いたのに…。見てないケド、$tweets の中身が空っぽなんで、そこから引っ張って来る $val の中身も空になってて、それでエラーになってると思われ…。 P.S. 補足でもお礼にでも良いので、何をどうしたいのか箇条書きでお願いします。優先順位も付けて。 前にも言った通り、こちらはあくまでも手弁当なので、そちらの都合に合わせては回答出来ない。この質問を締めずに開けて置いてくれれば、そのうち暇を見て回答するかもしれないし、これっきりかもしれない。他の誰かが通りすがりに回答してくれるかもしれない。

walsch
質問者

お礼

4017Bさん本当にありがとうございます! 更に半月ほど格闘して、やっと自力で解決しました。 「どうしたいか」は質問文にて優先順位も箇条書きで明確に書いてありましたが、 >答えてあげたいけど他人の書いたコードは常に意味不明瞭なので、解読に時間が掛かる。勘弁。 >当然ながら質問文は前半しか読んでないので >何をどうしたいのか箇条書きでお願いします。優先順位も付けて。 と4017Bさん自身が仰るように、4017Bさんは問題に対して「面倒なので質問文は読まない」という前提(癖?)があるのに、二度も同じこと(質問文にある箇条書きと優先順位)を重複して書いても、読まないつもりなら仕方ないと思いました。 「警告」に関しても、もちろん先んじて調べていましたが、せっかく4017Bさんがif (preg_match())の書き方を教えて下さったにも関わらず、 それでエラーが出たこと自体の方(次の警告文の英語が読めるかどうかではなく、4017Bさんの最初の御教授がなぜ間違っていたのか)が気になって補足で質問した次第です。 まず1に関しては foreach ($tweets as $val) のすぐ後に if(isset(($vall->)) $val = でisset()は引数に指定した変数が定義されているかどうか調べ、定義されていればTRUEを返すようにすることで解決しました。 2に関してはif (preg_match())を参考にstrtotime()とdate()でタイムスタンプを取得してその文字列をcreated_atから拾うことで解決しました。 3に関しては、先んじてarray_reverse()を用いて順番をひっくり返すことで解決しました。 if (preg_match()は配列でなくて、文字列でなくてはならないので、通りでif (preg_match()で$valをそのまま入れても動かないはずでした。エラーでの「警告文」はこれが原因です。 しかし、私は、手弁当でありながらも、きっかけとしてのif (preg_match)のヒントを下さった4017Bさんに心より感謝しております。 動機がなんであれ、求めるものに与えようとする姿勢は素晴らしいと思います。 今後の人生においても大切になさってください。磨けば身を結ぶものであると思います。 重ねますが報告も兼ねて御礼申し上げます。

  • 4017B
  • ベストアンサー率73% (1305/1776)
回答No.1

え~っと、とりあえず Q.1 に関しては当たり前。 つ~か if文の前で、条件式に使ってる変数 $pat1 と $pat2 にそれぞれ値が事前に代入されてるから。従って何をどうやっても、このプログラム内では常に、 > $pat1 == '/^RT/' == true ~となり、常に if(!$pat1){...} が "偽(false)" となるので if文自体が意味を持たない。同様にその前の if($pat1 && $pat2){...} も意味無し(やはり常に "真(true)" となる)。 P.S. 全部、答えてあげたいけど。他人の書いたコードは常に意味不明瞭なので、解読に時間が掛かる。手弁当なので勘弁。 プログラム系の質問は面倒でも常に一問一答の形で。複数の質問を混ぜると、回答者側も無用の混乱誤解を招くだけなので。またそうする事によって、質問者側も自身の問題点が整理し易くなるので。 と言う訳で当然ながら質問文は前半しか読んでないのであしからず…

walsch
質問者

補足

4017Bさん。コメントありがとうございます。 なるほど。御指摘のおかげでTrueになってしまっている現状が分かりました。ありがとうございます。 とりあえず構文が間違っているということが分かったのでよかったです。

関連するQ&A

  • twitterのツイート取得について

    自分のHPにツイートを表示させているのですが、 自分が公式リツイートしたツイートのみを取得するにはどうしたらよいのでしょう? var dateObj = new Date; $.getJSON('http://twitter.com/statuses/user_timeline/[ userID ].json?callback=?', function (json) { for(var i in json){ ......... 上記の指定だと普通に通常のツイートが表示されます。 リツイートのみで表示したいのですが、どのように取得したらよいか教えてくださいませ。 初心者のため、足りない記述があるかもしれません、、、 どうぞご回答宜しくお願い申し上げます。

  • PHPでtwitterAPI利用時のサーバー設定

    TwitterAPI(ver1.1)を利用して自分のつぶやきをPHPで取得したいと思います。 認証は「OAuth.php」「twitteroauth.php」の外部ライブラリを利用しています。 下記のファイル構成でレンタルサーバーで試したところ、つぶやきのデータが取得できました。 しかし自分で構築したVPSのサーバーで実行しようとしたところ、処理に長く時間がかかり、「取得できません」という表示になってしまいます。 「OAuth」「twitteroauth」を使うにあたり、サーバーで設定すべき項目はあるのでしょうか? また、下記のプログラムで変数 $twObj にはAPIキーなどが配列で入られているのはわかったのですが、 $req 以降の変数はvar_dumpをしても何も表示されません。 TwitterAPIからどのようなメッセージが返ってきているかを表示させるには、どのようなプログラムを書けばよいのでしょうか? 以上、ご回答よろしくお願いいたします。 環境 ----------------------------- PHP 5.3.3 apach 2.2.3 CentOS 5.4(VPSで構築したLinuxサーバー) ----------------------------- ファイル構成 OAuth.php twitteroauth.php tweet.php を同じディレクトリに配置。 tweet.php ------------------------------------------------------------------------------ require_once 'twitteroauth.php'; $twObj = new TwitterOAuth($ConsumerKey,$ConsumerSecret,$AccessToken,$AccessTokenSecret); //APIのキーは取得したものを代入しています。(記載は省略) $req = $twObj->OAuthRequest('https://api.twitter.com/1.1/statuses/user_timeline.json','GET',array('count'=>'10')); $tweets = json_decode($req); if (isset($tweets) && empty($tweets->errors)) { echo '<dl>'; foreach ($tweets as $val) { echo '<dd>' . $val->text . ''; } echo '</dd></dl>'; } else { echo '取得できません。'; } -----------------------------------------------------------------------

    • ベストアンサー
    • PHP
  • twitterをRSSリーダで読む方法

    twitterのサービスに関して、あるユーザのtweetをRSSフィードを取得してRSSリーダで読む方法はないでしょうか ※ https://twitter.com/statuses/user_timeline/ユーザ名.rss や https://twitter.com/users/show/ユーザID.xml では、RSSフィードを取得できませんでした。

  • 最後1行だけ…どのように書き直せばいいのでしょうか

    唐突に質問失礼致します。PHPの初心者です。 1ヶ月ほど試行錯誤した結果、暗礁に乗り上げてしまって困っているので教えて頂きたいです。 下記を参考にPHPでFC2ブログに投稿するスクリプトを書いているのですが、 FC2ブログに記事を投稿するスクリプト http://blog.ishitoya.info/entry/20080330/1206907632 投稿文を自分のTwitterのタイムラインにしたいと思っています。 そこで上のスクリプトの上方の一部に少しだけ下記のように書き加えました。 ///////////////////////// $url = "http://api.twitter.com/1/statuses/user_timeline.json?&include_rts=true&screen_name=(Twitterユーザー名)&page=".$_POST['page']; $tweets = json_decode(file_get_contents($url)); foreach ($tweets as $tweet) { echo "<li>".$tweet->text."</li>"; } try{ $bm = new FC2BlogManager($fc2_host, $fc2_xmlrpc_path); $bm->setUser($fc2_user); $bm->setPassword($fc2_passwd); $bm->postEntry("PHPから投稿テスト4-Title", "テスト4-Dsescription [".$tweet->text."]<br/>改行コード埋め込み \n なんかいけてそう"); var_dump($bm->getBlogs()); }catch(Exception $e){ echo $e->getMessage(); } ///////////////////////////////////// ↓のようにすることでブラウザ上のphp実行画面では、Twitterのタイムラインがテキスト化されて表示されるのですが、 $bm->postEntry(" [".$tweet->text."]"); 実際に投稿されるのはTwitterをテキスト化した時の一番下のツイート(一番古くしたツイート)のみなのです。 [ ]内をどのように書き直せば、タイムライン(.jsonのテキスト化内)がすべて拾えるでしょうか? また、記事タイトルをその日のものに自動指定したり、時間を指定して(例えば24時間など)その時間内にしたツイートを限定して拾える方法、ツイート内にURLがあった場合自動リンクする書き方もお手数でなければ、教えていただけたら幸いに存じ上げます。 誠に勝手で稚拙な質問で恐縮ですが、教えていただけたら幸いに存じ上げます。

    • ベストアンサー
    • PHP
  • Twitterフォロワー数 取得 API xml

    【 Twitterフォロワー数 取得 API xml 】 twitterのフォロワー数を取得しwebsiteに表示したいです。 下記のcodeを記述したのですが、 取得出来ない場合があります。 (Aのサイトですと表示されBのサイトですと表示されない) <?php $urlt = str_replace(0xefbbbf, '', file_get_contents('http://api.twitter.com/1/statuses/user_timeline.xml?id=□□□□□□')); $xmlt = simplexml_load_string($urlt); print $xmlt->status->user->followers_count; ?> ※上記の □□□□□□ 部分には 表示させたいtwitterのscreen_nameかidをいれます。 どうしてもわからずこちらに質問させて頂きました。。。 よろしくお願いいたします。。

    • 締切済み
    • PHP
  • Twitter APIについて

    PHP初心者です。 https://github.com/sizaki30/TwitterAppOAuth を使って https://syncer.jp/twitter-api-matome/get/statuses/user_timeline のようなものを作ることは可能でしょうか? 回答よろしくお願いします。

    • ベストアンサー
    • PHP
  • AJAXの計算式の中にIF文を入れて表示したい

    下記の2つのファイルで、フォームから入力した数値同士の「足し算の結果」をAJAXで表示できます。 ******************************************** 【HTMLフォーム】 <script language="JavaScript" type="text/javascript" src="js/culc.js"></script> <form name="f1"> <input type="text" id="text1" name="text1" size="10" maxlength="10" /> + <input type="text" id="text2" name="text2" size="10" maxlength="10" /> <input type="button" value="足す" onclick="readText()" /> </form> <p id="message"></p> ******************************************* 【JAVASCRIPT(culc.js)】 function readText() { var text1 = document.getElementById("text1"); var text2 = document.getElementById("text2"); var message = document.getElementById("message"); var str_val1 = text1.value; var str_val2 = text2.value; var sum; if (isNaN(str_val1) || str_val1 == "" || isNaN(str_val2) || str_val2 == "") { textMessage = "数値以外の文字が入っています"; } else { //sum = str_val1 + str_val2; sum = parseFloat(str_val1) + parseFloat(str_val2); textMessage = "合計は、" + sum + "です"; } message.innerHTML = textMessage; } ************************************************ 【質問】 このjavascriptを改造し、入力した数値についての「足し算の結果」が正の数だった場合には「正の数」、負の数だった場合は「負の数」と表示すべく改造しております。下記の改造を施したのですが、うまく表示されません。 下記の文のどこが誤りか修正頂けませんでしょうか? 宜しくお願い致します。 【JAVASCRIPT(culc2.js)】 function readText() { var text1 = document.getElementById("text1"); var text2 = document.getElementById("text2"); var message = document.getElementById("message"); var str_val1 = text1.value; var str_val2 = text2.value; var sum; if (isNaN(str_val1) || str_val1 == "" || isNaN(str_val2) || str_val2 == "") { textMessage = "数値以外の文字が入っています"; } else { //sum = str_val1 + str_val2; sum = parseFloat(str_val1) + parseFloat(str_val2); textMessage = "(if((sum > 0) { document.write("正の数"); } else((sum <= 0) { document.write("負の数"); } ))"; } message.innerHTML = textMessage; }

    • ベストアンサー
    • AJAX
  • twitterのタイムラインの全文表示について

    Twitterクライアントのプログラミングについての質問です。 home_timeline.jsonを取得し、textを表示したのですが 長文ツイートのRTに関しては「...」という形で省略されてしまいます。 こういった長文ツイートのRTに関しても全文表示した場合は どのように取得すれば良いのでしょうか? ご教授ください。よろしくお願い致します。

  • Javascript フォントサイズ変更

    Twitterのつぶやきを外部表示したらフォントサイズが大きくフォントの色も黒いままだったので、 <FONT size="1" color="#ff0000"> <div id="twitter_div"><ul id="twitter_update_list"></ul></div> <script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script> <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/○○(ID).json?callback=twitterCallback2&amp;count=2"></script> </FONT> とフォントタグで囲んだところ、IEとSafariでは小さくなったのですが、 Firefoxでは表示がそのままでした。 Firefoxでもちゃんと表示できるようにするにはどうしたらいいでしょうか。

  • VB初心者です

    計算結果が"7"の時に限り、「当たり!」と表示される、ちょっと意味不明な計算機を作っています。 現在、下記のように書いてますが、何故かうまくいきません。(当たりが表示されない 何故でしょうか?お助けください。。m(_ _)m Private Sub Command1_Click() Label1.Caption = Str(Val(Text1.Text) + Val(Text2.Text)) Label3.Caption = "+" Label4.Visible = False '画像を隠す。 'いずれかの数字が「7」のとき、メッセージを表示する。 If Label1.Caption = "7" Then Label4.Visible = True End If End Sub Private Sub Command2_Click() End End Sub Private Sub Command3_Click() Label1.Caption = Str(Val(Text1.Text) * Val(Text2.Text)) Label3.Caption = "*" End Sub Private Sub Command4_Click() Label1.Caption = Str(Val(Text1.Text) - Val(Text2.Text)) Label3.Caption = "-" End Sub Private Sub Command5_Click() Label1.Caption = Str(Val(Text1.Text) / Val(Text2.Text)) Label3.Caption = "/" End Sub

専門家に質問してみよう