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

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

新規登録して質問してみよう
ただいま回答率
85.48%
RSS

RSS(Really Simple Syndication)はブログのエントリやニュースの見出し、標準のフォーマットの音声やビデオなどを発行するために使われるウェブフィードのフォーマットの集合体です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

3474閲覧

PHPでのRSSフィードを取得する

kumagaya31

総合スコア0

RSS

RSS(Really Simple Syndication)はブログのエントリやニュースの見出し、標準のフォーマットの音声やビデオなどを発行するために使われるウェブフィードのフォーマットの集合体です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/07/23 09:45

編集2021/07/23 10:53

前提・実現したいこと

PHP初学者です。
rss-phpを使用して、RSSフィードを取得する練習をしているのですが、色々なサイトで試していると、下記のようなエラーが表示されてしまいます。

かなり初歩的な質問かと思うのですが、何かご教示いただけたら幸いです。

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

Fatal error: Uncaught FeedException: Cannot load feed. in /Applications/MAMP/htdocs/question3/Feed.php:193 Stack trace: #0 /Applications/MAMP/htdocs/question3/Feed.php(54): Feed::loadXml('https://techaca...', NULL, NULL) #1 /Applications/MAMP/htdocs/question3/sample.php(16): Feed::loadRss('https://techaca...') #2 {main} thrown in /Applications/MAMP/htdocs/question3/Feed.php on line 193

Sample.php

PHP

1<?php 2 3ini_set( 'display_errors', 1 ); 4ini_set( 'error_reporting', E_ALL ); 5 6 require_once "./Feed.php" ; 7 8 $url = "https://techacademy.jp/magazine/feed" ; 9 10 $feed = new Feed ; 11 12 $rss = $feed->loadRss( $url ) ; 13 14 $html = '' ; 15 16 foreach( $rss->item as $item ) 17 { 18 $title = $item->title ; 19 $link = $item->link ; 20 $description = $item->description ; 21 22 foreach( array( "pubDate" , "date_timestamp" , "dc:date" , "published" , "issued" ) as $time ) 23 { 24 if( isset( $item->{ $time } ) && !empty( $item->{ $time } ) ) 25 { 26 $timestamp = ( is_int( $item->{ $time } ) ) ? $item->{ $time } : strtotime( $item->{ $time } ) ; 27 break ; 28 } 29 } 30 31 if( !isset( $timestamp ) ) 32 { 33 $timestamp = time() ; 34 } 35 36 $html .= '<a href="' . $link . '">' . $title . '</a> (' . date( "Y/m/d H:i" , $timestamp ) . ')<br>' ; 37 } 38?> 39<!DOCTYPE html> 40<html> 41 <head> 42 <meta charset="UTF-8"> 43 </head> 44<body> 45 46<?php echo $html ?> 47 48</body> 49</html> 50

Feed.php

PHP

1<?php 2 3/** 4 * RSS for PHP - small and easy-to-use library for consuming an RSS Feed 5 * 6 * @copyright Copyright (c) 2008 David Grudl 7 * @license New BSD License 8 * @version 1.5 9 */ 10class Feed 11{ 12 /** @var int */ 13 public static $cacheExpire = '1 day'; 14 15 /** @var string */ 16 public static $cacheDir; 17 18 /** @var string */ 19 public static $userAgent = 'FeedFetcher-Google'; 20 21 /** @var SimpleXMLElement */ 22 protected $xml; 23 24 25 /** 26 * Loads RSS or Atom feed. 27 * @param string 28 * @param string 29 * @param string 30 * @return Feed 31 * @throws FeedException 32 */ 33 public static function load($url, $user = null, $pass = null) 34 { 35 $xml = self::loadXml($url, $user, $pass); 36 if ($xml->channel) { 37 return self::fromRss($xml); 38 } else { 39 return self::fromAtom($xml); 40 } 41 } 42 43 44 /** 45 * Loads RSS feed. 46 * @param string RSS feed URL 47 * @param string optional user name 48 * @param string optional password 49 * @return Feed 50 * @throws FeedException 51 */ 52 public static function loadRss($url, $user = null, $pass = null) 53 { 54 return self::fromRss(self::loadXml($url, $user, $pass)); 55 } 56 57 58 /** 59 * Loads Atom feed. 60 * @param string Atom feed URL 61 * @param string optional user name 62 * @param string optional password 63 * @return Feed 64 * @throws FeedException 65 */ 66 public static function loadAtom($url, $user = null, $pass = null) 67 { 68 return self::fromAtom(self::loadXml($url, $user, $pass)); 69 } 70 71 72 private static function fromRss(SimpleXMLElement $xml) 73 { 74 if (!$xml->channel) { 75 throw new FeedException('Invalid feed.'); 76 } 77 78 self::adjustNamespaces($xml); 79 80 foreach ($xml->channel->item as $item) { 81 // converts namespaces to dotted tags 82 self::adjustNamespaces($item); 83 84 // generate 'url' & 'timestamp' tags 85 $item->url = (string) $item->link; 86 if (isset($item->{'dc:date'})) { 87 $item->timestamp = strtotime($item->{'dc:date'}); 88 } elseif (isset($item->pubDate)) { 89 $item->timestamp = strtotime($item->pubDate); 90 } 91 } 92 $feed = new self; 93 $feed->xml = $xml->channel; 94 return $feed; 95 } 96 97 98 private static function fromAtom(SimpleXMLElement $xml) 99 { 100 if (!in_array('http://www.w3.org/2005/Atom', $xml->getDocNamespaces(), true) 101 && !in_array('http://purl.org/atom/ns#', $xml->getDocNamespaces(), true) 102 ) { 103 throw new FeedException('Invalid feed.'); 104 } 105 106 // generate 'url' & 'timestamp' tags 107 foreach ($xml->entry as $entry) { 108 $entry->url = (string) $entry->link['href']; 109 $entry->timestamp = strtotime($entry->updated); 110 } 111 $feed = new self; 112 $feed->xml = $xml; 113 return $feed; 114 } 115 116 117 /** 118 * Returns property value. Do not call directly. 119 * @param string tag name 120 * @return SimpleXMLElement 121 */ 122 public function __get($name) 123 { 124 return $this->xml->{$name}; 125 } 126 127 128 /** 129 * Sets value of a property. Do not call directly. 130 * @param string property name 131 * @param mixed property value 132 * @return void 133 */ 134 public function __set($name, $value) 135 { 136 throw new Exception("Cannot assign to a read-only property '$name'."); 137 } 138 139 140 /** 141 * Converts a SimpleXMLElement into an array. 142 * @param SimpleXMLElement 143 * @return array 144 */ 145 public function toArray(SimpleXMLElement $xml = null) 146 { 147 if ($xml === null) { 148 $xml = $this->xml; 149 } 150 151 if (!$xml->children()) { 152 return (string) $xml; 153 } 154 155 $arr = []; 156 foreach ($xml->children() as $tag => $child) { 157 if (count($xml->$tag) === 1) { 158 $arr[$tag] = $this->toArray($child); 159 } else { 160 $arr[$tag][] = $this->toArray($child); 161 } 162 } 163 164 return $arr; 165 } 166 167 168 /** 169 * Load XML from cache or HTTP. 170 * @param string 171 * @param string 172 * @param string 173 * @return SimpleXMLElement 174 * @throws FeedException 175 */ 176 private static function loadXml($url, $user, $pass) 177 { 178 $e = self::$cacheExpire; 179 $cacheFile = self::$cacheDir . '/feed.' . md5(serialize(func_get_args())) . '.xml'; 180 181 if (self::$cacheDir 182 && (time() - @filemtime($cacheFile) <= (is_string($e) ? strtotime($e) - time() : $e)) 183 && $data = @file_get_contents($cacheFile) 184 ) { 185 // ok 186 } elseif ($data = trim(self::httpRequest($url, $user, $pass))) { 187 if (self::$cacheDir) { 188 file_put_contents($cacheFile, $data); 189 } 190 } elseif (self::$cacheDir && $data = @file_get_contents($cacheFile)) { 191 // ok 192 } else { 193 throw new FeedException('Cannot load feed.'); 194 } 195 196 return new SimpleXMLElement($data, LIBXML_NOWARNING | LIBXML_NOERROR | LIBXML_NOCDATA); 197 } 198 199 200 /** 201 * Process HTTP request. 202 * @param string 203 * @param string 204 * @param string 205 * @return string|false 206 * @throws FeedException 207 */ 208 private static function httpRequest($url, $user, $pass) 209 { 210 if (extension_loaded('curl')) { 211 $curl = curl_init(); 212 curl_setopt($curl, CURLOPT_URL, $url); 213 if ($user !== null || $pass !== null) { 214 curl_setopt($curl, CURLOPT_USERPWD, "$user:$pass"); 215 } 216 curl_setopt($curl, CURLOPT_USERAGENT, self::$userAgent); // some feeds require a user agent 217 curl_setopt($curl, CURLOPT_HEADER, false); 218 curl_setopt($curl, CURLOPT_TIMEOUT, 20); 219 curl_setopt($curl, CURLOPT_ENCODING, ''); 220 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // no echo, just return result 221 if (!ini_get('open_basedir')) { 222 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // sometime is useful :) 223 } 224 $result = curl_exec($curl); 225 return curl_errno($curl) === 0 && curl_getinfo($curl, CURLINFO_HTTP_CODE) === 200 226 ? $result 227 : false; 228 229 } else { 230 $context = null; 231 if ($user !== null && $pass !== null) { 232 $options = [ 233 'http' => [ 234 'method' => 'GET', 235 'header' => 'Authorization: Basic ' . base64_encode($user . ':' . $pass) . "\r\n", 236 ], 237 ]; 238 $context = stream_context_create($options); 239 } 240 241 return file_get_contents($url, false, $context); 242 } 243 } 244 245 246 /** 247 * Generates better accessible namespaced tags. 248 * @param SimpleXMLElement 249 * @return void 250 */ 251 private static function adjustNamespaces($el) 252 { 253 foreach ($el->getNamespaces(true) as $prefix => $ns) { 254 $children = $el->children($ns); 255 foreach ($children as $tag => $content) { 256 $el->{$prefix . ':' . $tag} = $content; 257 } 258 } 259 } 260} 261 262 263 264/** 265 * An exception generated by Feed. 266 */ 267class FeedException extends Exception 268{ 269} 270

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

attakei

2021/07/23 10:36

出力されたエラーは、末尾に > ... thrown in /Applications/MAMP/htdocs/question3/Feed.php on line 193 とあるようにFeed.phpの側で起きていることを示しています。 少なくとも現在掲載されているコードはFeed.phpではないため、仮にFeed.phpに直接的な問題があるにしても、回答自体が誰もできないと思います。 まずは、Feed.phpの掲載をしたほうが良いでしょう。
kumagaya31

2021/07/23 10:53

ありがとうございます。追加いたしました。
kumagaya31

2021/07/23 11:45 編集

ありがとうございます。 そうです。最新版をダウンロードしました。
m.ts10806

2021/07/23 11:46

github最新ソース読み込みで試しましたが当該エラー出ずに、想定の出力をしているように見受けられます(ローカル環境のCLI実行です) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <a href="https://techacademy.jp/magazine/66916">小学生の習い事におすすめしたい「プログラミング教室」</a> (2021/06/10 18:26)<br>(中略) </body> </html>
kumagaya31

2021/07/23 14:34

ありがとうございます。 改めて試してみましたが、同様のエラーが出てしまいます。 実行環境の問題でしょうか。。。
m.ts10806

2021/07/23 19:52

では、OS含めてバージョンなど、環境構築の手順も分かる限り追記してもらって良いですか?
guest

回答1

0

直感ですが文字コードが異なっているのでは?

投稿2021/07/24 05:18

okada0930

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問