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

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

ただいまの
回答率

87.78%

PHPでの複数のRSS取得表示について

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 441

score 0

前提・実現したいこと

phpで複数のrssを表示するものを作成したいと思い、他のサイトをほぼコピペして動作をさせてみたのですが
以下のようなエラーが出て、配列の一番最後のフィードだけが表示される状態になっています
どうすればいいのでしょうか。よろしくお願いします

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

Warning: simplexml_load_string(): Entity: line 2: parser error : Start tag expected, '<' not found in ●●.php on line 13

該当のソースコード

<?php
//フィード登録
$data['feedurl'][] = 'http://news.yahoo.co.jp/pickup/rss.xml'; //Yahoo!ニューストピックストップ
$data['feedurl'][] = 'http://rss.rssad.jp/rss/itmnews/2.0/news_bursts.xml'; //ITmedia ニュース速報
$data['feedurl'][] = 'http://japan.cnet.com/rss/index.rdf'; //CNET Japan
$data['feedurl'][] = 'http://feeds.reuters.com/reuters/JPTopNews'; //ロイター RSS
// RSS追加用(いくつでも追加可能,Atom,RSS1.0,RSS2.0に対応)
// $data['feedurl'][] = '';
$rssList = $data['feedurl'];
//同時呼び出し
$rssdataRaw = multiRequest($rssList);
for($n=0; $n < count($rssdataRaw); $n++){
  $rssdata = simplexml_load_string($rssdataRaw[$n]); //URL設定
  // Atom取得
  if($rssdata->entry){
    $site = $rssdata->title; // サイト名
    foreach($rssdata->entry as $myEntry){
      $myTitle = $myEntry->title;
      // 日時取得
      if (isset($myEntry->issued)) {
                $rssDate = $myEntry->issued;
            } else {
                $rssDate = $myEntry->published;
            }
      date_default_timezone_set('Asia/Tokyo');
      $myDateGNU = strtotime($rssDate);
      $myDate = date('Y/m/d - G:i',$myDateGNU);
      //リンクURL取得
      $myLink = $myEntry->link['href'];
      //サムネイル画像取得
      $myContent = $myEntry->content;
      $imgurl = "";
      $pattern = '/(ttps?)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\.(jpg|gif|png)/';
      if (preg_match_all($pattern, $myContent, $matches)) {
          foreach($matches[0] as $key=>$value) {
              $imgurl = "h{$value}";
          }
      } else {
          $imgurl = "img/no-image.jpg"; // 画像が見つからなければno-image画像を挿入
      }
      //連想配列($array)
      $array = array(
        "site" => $site,
          "title" => $myTitle,
          "url" => $myLink,
          "date" => $myDate,
          "image" => $imgurl,
          "visit" => 'none',
      );
      $outdata[$myDateGNU] = $array;
    }
  }
  // rss1.0取得
  elseif($rssdata->item){
    $site = $rssdata->channel->title; //サイト名
    foreach($rssdata->item as $myEntry){
      $myTitle = $myEntry->title;
      // 日時取得
      $rssDate = $myEntry->pubDate;
      if(!$rssDate) $rssDate = $myEntry->children("http://purl.org/dc/elements/1.1/")->date;
      date_default_timezone_set('Asia/Tokyo');
      $myDateGNU = strtotime($rssDate);
      $myDate = date('Y/m/d - G:i',$myDateGNU);
      //リンクURL取得
      $myLink = $myEntry->link;
      //サムネイル画像取得
      $myContent = $myEntry->children("http://purl.org/rss/1.0/modules/content/")->encoded;
      $imgurl = "";
      $pattern = '/(ttps?)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\.(jpg|gif|png)/';
      if (preg_match_all($pattern, $myContent, $matches)) {
          foreach($matches[0] as $key=>$value) {
              $imgurl = "h{$value}";
          }
      } else {
          $imgurl = "img/no-image.jpg"; // 画像が見つからなければno-image画像を挿入
      }
      //連想配列($array)
      $array = array(
          "site" => $site,
          "title" => $myTitle,
          "url" => $myLink,
          "date" => $myDate,
          "image" => $imgurl,
          "visit" => 'none',
      );
      $outdata[$myDateGNU] = $array;
    }
  }
  // RSS2.0取得
  elseif($rssdata->channel->item){
    $site = $rssdata->channel->title; //サイト名
    $rssdata = $rssdata->channel;
    foreach($rssdata->item as $myEntry){
      $myTitle = $myEntry->title;
      // 日時取得
      $rssDate = $myEntry->pubDate;
      if(!$rssDate) $rssDate = $myEntry->children("http://purl.org/dc/elements/1.1/")->date;
      date_default_timezone_set('Asia/Tokyo');
      $myDateGNU = strtotime($rssDate);
      $myDate = date('Y/m/d - G:i',$myDateGNU);
      //リンクURL取得
      $myLink = $myEntry->link;
      //サムネイル画像取得
      $myContent = $myEntry->description;
      $imgurl = "";
      $pattern = '/(ttps?)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\.(jpg|gif|png)/';
      if (preg_match_all($pattern, $myContent, $matches)) {
          foreach($matches[0] as $key=>$value) {
              $imgurl = "h{$value}";
          }
      } else {
          $imgurl = "img/no-image.jpg"; // 画像が見つからなければno-image画像を挿入
      }
      //連想配列($array)
      $array = array(
        "site" => $site,
          "title" => $myTitle,
          "url" => $myLink,
          "date" => $myDate,
          "image" => $imgurl,
          "visit" => 'none',
      );
      $outdata[$myDateGNU] = $array;
    }
  }
}
//同時取得したRSSを更新日時順にソート
krsort($outdata);
//データをJSON形式に変換
$nn = 0;
$output = '';
$length = count($outdata);
foreach($outdata as $outdata) {
  $nn++;
  $output.= json_encode($outdata);
  if($nn !== $length) {
    $output.= ',';
  } else {
    break;
  }
}
// データをJSONに格納
$html = '['.$output.']';
$json = fopen('feeddata.json', 'w+b');
flock($json, LOCK_SH);
fwrite($json, $html);
fclose($json);
//同時呼び出し関数
function multiRequest($data, $options = array()) {
  // array of curl handles
  $curly = array();
  // data to be returned
  $result = array();
  // multi handle
  $mh = curl_multi_init();
  // loop through $data and create curl handles
  // then add them to the multi-handle
  foreach ($data as $id => $d) {
    $curly[$id] = curl_init();
    $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
    curl_setopt($curly[$id], CURLOPT_URL,            $url);
    curl_setopt($curly[$id], CURLOPT_HEADER,         0);
    curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);
    // post?
    if (is_array($d)) {
      if (!empty($d['post'])) {
        curl_setopt($curly[$id], CURLOPT_POST,       1);
        curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
      }
    }
    // extra options?
    if (!empty($options)) {
      curl_setopt_array($curly[$id], $options);
    }
    curl_multi_add_handle($mh, $curly[$id]);
  }
  // execute the handles
  $running = null;
  do {
    curl_multi_exec($mh, $running);
  } while($running > 0);
  // get content and remove handles
  foreach($curly as $id => $c) {
    $result[$id] = curl_multi_getcontent($c);
    curl_multi_remove_handle($mh, $c);
  }
  // all done
  curl_multi_close($mh);
  return $result;
}
$output = [];
$data = @file_get_contents('feeddata.json');
if ($data !== false) {
$obj = json_decode($data);
$output[] = '<ul>';
$zero = '0';
foreach (json_decode($data) as $obj) {
$output[] = sprintf('<li>%s:<a href="%s">%s</a> (%s)</li>', $obj->site->$zero, $obj->url->$zero, $obj->title->$zero, $obj->date);
}
$output[] = '</ul>';
}
?>

<!DOCTYPEhtml>
<!-- RSSを表示 -->
<?= count($output) > 0 ? implode(PHP_EOL, $output) : '' ?>

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

multiRequest関数で「ロイター RSS」以外の内容が取得できていないようです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

2番目のURLがブラウザから直でアクセスできませんが、エラーはそれが原因では?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/05/11 06:54

    盲点でした・・・
    しかしその箇所を修正しても同じエラーが出てきました
    何故なのでしょう

    キャンセル

  • 2020/05/11 06:58

    何をどう修正したのでしょう。
    Warningはエラーとは違うので、コードは中断されず実行されていっているはずです。
    ということは、どの時点でWarningとなっているか調べることができます。
    どのXMLのときに起きてるかデバッグしてみてください。

    キャンセル

  • 2020/05/11 07:24

    2番目の$data['feedurl'][] = 'http://rss.rssad.jp/rss/itmnews/2.0/news_bursts.xml&#039;; //ITmedia ニュース速報部分を丸ごと削除しました
    その状態で
    Warning: simplexml_load_string(): Entity: line 2: parser error : Start tag expected, '<' not found in xx.php on line 12と表示される状態です

    また類似の物を試していたのですが、そちらでもmultiRequest関数の部分で引っかかっているようでした
    現在無料のレンタルサーバーを使用しているためもしかするとサーバー側の制限によるものなのでしょうか

    キャンセル

  • 2020/05/11 07:48

    質問は編集できるので、対応状況追記してください。
    無料のレンタルサーバーだと何かしら制限がある可能性はなくもないですが、問題切り分けするために、自身のローカルPCでもやってみてください。

    キャンセル

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

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

関連した質問

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