Skip to content

Instantly share code, notes, and snippets.

@okumin
Created August 12, 2012 19:17
Show Gist options
  • Save okumin/3333858 to your computer and use it in GitHub Desktop.
Save okumin/3333858 to your computer and use it in GitHub Desktop.
フィードをパースするクラス
<?php
/**
* Copyright (c) 2012 okumin, http://okumin.com/
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
class FeedParser
{
const RSS1 = 0; // RSS1.0
const RSS2 = 1; // RSS2.0
const ATOM = 2; // Atom
// フィードをパースして記事を配列で返す
// 引数$feedにはフィードの文字列をそのまま指定
// 引数$errorReportingがFALSEの場合、simplexml_load_stringによるWarningエラーは出力されない
public static function parseFeed($feed, $errorReporting = FALSE){
if(!$errorReporting){
libxml_use_internal_errors(TRUE); // Warningエラーを抑制
}
$xml = simplexml_load_string($feed, 'SimpleXMLElement', LIBXML_NOCDATA);
if(!$errorReporting){
$warnings = libxml_get_errors();
libxml_use_internal_errors(FALSE);
}
if($xml === FALSE || $errorReporting && count($warnings)){
throw new FeedParserException('parseFeed: 入力されたフィードのデータからオブジェクトを作成できませんでした。フィードのフォーマットが不正な可能性があります。');
}
$format = self::checkFeedFormat($xml);
if($format === self::RSS1){
return self::parseRss1($xml);
}elseif($format === self::RSS2){
return self::parseRss2($xml);
}elseif($format === self::ATOM){
return self::parseAtom($xml);
}
}
private static function checkFeedFormat($xml){
if($xml->getName() === 'RDF'){
return self::RSS1;
}elseif($xml->getName() === 'rss'){
return self::RSS2;
}elseif($xml->getName() === 'feed'){
return self::ATOM;
}else{
throw new FeedParserException('checkFeedFormat: 対応していないフォーマットのフィードが入力されました。扱えるフォーマットはRSS1.0、RSS2.0、Atomです。');
}
}
private static function parseRss1($xml){
$result = array();
foreach($xml->item as $value){
if(!isset($value->title, $value->link, $value->children('dc', TRUE)->date)){
continue;
}
$result[] = array(
'title' => (string) $value->title,
'link' => (string) $value->link,
'datetime' => (string) $value->children('dc', TRUE)->date,
);
}
return $result;
}
private static function parseRss2($xml){
$result = array();
foreach($xml->channel->item as $value){
if(isset($value->pubDate)){
$datetime = $value->pubDate;
}elseif(isset($value->children('dc', TRUE)->date)){
$datetime = $value->children('dc', TRUE)->date;
}else{
$datetime = NULL;
}
if(!isset($value->title, $value->link, $datetime)){
continue;
}
$result[] = array(
'title' => (string) $value->title,
'link' => (string) $value->link,
'datetime' => (string) $datetime,
);
}
return $result;
}
private static function parseAtom($xml){
$result = array();
foreach($xml as $value){
if($value->getName() !== 'entry'){
continue;
}
if(isset($value->issued)){
$datetime = $value->issued;
}elseif($value->published){
$datetime = $value->published;
}else{
$datetime = NULL;
}
if(!isset($value->title, $value->link->attributes()->href, $datetime)){
continue;
}
$result[] = array(
'title' => (string) $value->title,
'link' => (string) $value->link->attributes()->href,
'datetime' => (string) $datetime,
);
}
return $result;
}
}
class FeedParserException extends Exception{}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment