- ベストアンサー
2つのif 構文が1つしか動作してくれない
- PHP修行中の者が、自分のTwitterのタイムラインをFC2ブログに投稿するスクリプトを書きたいと思っているが、if構文がうまく動作しないため困っている。
- 具体的には、2つのif構文がうまく動作せず、1つしか動かない。また、最新のテキストのみ抽出し、昇順に並び替えたい。
- 質問者は、if構文の改善方法やテキスト抽出の方法、テキストの並び替え方を知りたいとしている。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
回答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」という前提で話してますんで、そのつもりで。
その他の回答 (2)
- 4017B
- ベストアンサー率73% (1336/1814)
>エラー "Warning: preg_match() expects parameter 2 to be string" ~て言うのは意訳すると、「警告: preg_match() を実行したら、2番目の変数にPHP的に期待した物じゃない変なのがあるよ?」って意味。いちいちウルサイ奴と思われるでしょうが、エラー表示には全て意味があり、そこには最も役に立つ手掛かりと答えがある。ちゃんと自分の目で見て聞いて考えるべし。 PHPに限らず、プログラム側から表示されるエラーは、非常に簡単な中学英語レベルです(世界中の技術者に向けて書いてあるので、非英語圏のネイティブじゃない人の事も考慮してる)。PHPみたいなメジャーな開発言語なら、エラーをそのままコピペしてGoogle検索するだけで2秒以内にエラーの意味くらい分ります。 ちなみに上記エラーはテンプレみたいな物で、だいたいは引数(この場合は第2変数)の中身がnull値になってる時に良く表示されます。多分、回答文をそのままコピペしたんじゃないかな?ちゃんとアレンジしろと書いて置いたのに…。見てないケド、$tweets の中身が空っぽなんで、そこから引っ張って来る $val の中身も空になってて、それでエラーになってると思われ…。 P.S. 補足でもお礼にでも良いので、何をどうしたいのか箇条書きでお願いします。優先順位も付けて。 前にも言った通り、こちらはあくまでも手弁当なので、そちらの都合に合わせては回答出来ない。この質問を締めずに開けて置いてくれれば、そのうち暇を見て回答するかもしれないし、これっきりかもしれない。他の誰かが通りすがりに回答してくれるかもしれない。
お礼
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% (1336/1814)
え~っと、とりあえず Q.1 に関しては当たり前。 つ~か if文の前で、条件式に使ってる変数 $pat1 と $pat2 にそれぞれ値が事前に代入されてるから。従って何をどうやっても、このプログラム内では常に、 > $pat1 == '/^RT/' == true ~となり、常に if(!$pat1){...} が "偽(false)" となるので if文自体が意味を持たない。同様にその前の if($pat1 && $pat2){...} も意味無し(やはり常に "真(true)" となる)。 P.S. 全部、答えてあげたいけど。他人の書いたコードは常に意味不明瞭なので、解読に時間が掛かる。手弁当なので勘弁。 プログラム系の質問は面倒でも常に一問一答の形で。複数の質問を混ぜると、回答者側も無用の混乱誤解を招くだけなので。またそうする事によって、質問者側も自身の問題点が整理し易くなるので。 と言う訳で当然ながら質問文は前半しか読んでないのであしからず…
補足
4017Bさん。コメントありがとうございます。 なるほど。御指摘のおかげでTrueになってしまっている現状が分かりました。ありがとうございます。 とりあえず構文が間違っているということが分かったのでよかったです。
補足
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で通りませんでした。 もしお手数でなければ、後見の方のことも含めて引き続き加筆していただけたら幸いに存じ上げます。