BLOG ENTRY

CakePHP1.2上で外部サイトのRSSを取得&表示[CakePHP]

cakephp

CakePHP1.2上で外部サイトのRSSを取得&表示します。
CakePHP1.2でRSSを出力する場合はこちらです。

いろんな方法がありますが、今回はこの3つを書いておきます。

1:CakePHPで標準で用意されている機能を使う
2:ZendFrameworkなど外部ライブラリを使う
3:Cronを使ってRSS情報をDBに保存

の3本です。(サザエさん)

ではさっそく。

1:CakePHPで標準で用意されてる機能を使う

コントローラーのアクション内で

[php]
uses(‘Xml’);
$xml = new Xml(‘★RSSのURL★’);
$xmlArr = Set::reverse($xml);
[/php]

これで$xmlArr内に配列として入ります。これで終わりです。

2:ZendFrameworkなど外部ライブラリを使う

次に外部ライブラリを使う方法です。

まずZendframworkを使うには

[php]
/app/vendors/zend_init.php
<?php
ini_set(‘include_path’, ini_get(‘include_path’) . PATH_SEPARATOR . dirname(__FILE__));
[/php]
これを書いて
/app/vendors/
ここにZendフォルダをごっそりアップロード。

で、使うコントローラー内で

[php]
App::import(‘Vendor’, ‘zend_init’);
App::import(‘Vendor’, ‘Zend_Feed_Rss’, array(‘file’ => ‘Feed’ . DS . ‘Reader.php’));
[/php]

こんな感じで書いてやれば、CakePHP上でZendFrameworkクラスを使えます。他のPHPライブラリでも基本同じです。
この部分の書式は公式マニュアルを見ればわかりやすいです。

で、今回はZend内のZend_Feed_Readerクラスを使ってみました。
コントローラーで
[php]
function get_url()
{
App::import(‘Vendor’, ‘zend_init’);
App::import(‘Vendor’, ‘Zend_Feed_Rss’, array(‘file’ => ‘Feed’ . DS . ‘Reader.php’));

$rss_url = $this->feed_url();
foreach ($rss_url as $k => $v) {
$feed = Zend_Feed_Reader::import($v);
$data = array(
‘title’ => $feed->getTitle(),
‘link’ => $feed->getLink(),
‘dateModified’ => $feed->getDateModified(),
‘description’ => $feed->getDescription(),
‘language’ => $feed->getLanguage(),
‘entries’ => array(),
);

foreach ($feed as $entry) {
$edata = array(
‘title’ => $entry->getTitle(),
‘description’ => $entry->getDescription(),
‘dateModified’ => $entry->getDateModified(),
‘author’ => $entry->getAuthor(),
‘link’ => $entry->getLink(),
‘content’ => $entry->getContent()
);
$data[‘entries’][] = $edata;
}
}
$this->set(‘data’, $data);
}

function feed_url()
{
return array(
‘★RSSのURL1★’,
‘★RSSのURL2★’
);
}
[/php]

こんな感じでいけました。

3:Cronを使ってRSS情報をDBに保存

Cronを使って定期的にRSSを取得&DB保存するサンプルコードです。
こちらのページで素晴らしいmodelのコードが紹介されていたので参考にさせて頂きました。
ありがとうございます。

$ vi /etc/crontab
[plain]
*/15 * * * * root /bin/bash ★ディレクトリ★/app/vendors/shells/tasks/cron.sh
[/plain]

$ vi /app/vendors/shells/tasks/cron.sh
[plain]
#!/bin/bash
/usr/bin/curl http://example.com/feeds/save_rss
[/plain]

$ vi /app/models/feed.php
[php]
<?php
uses(‘Xml’);

class Feed extends AppModel {
var $name = ‘Feed’;
var $cacheDuration = ‘+3 hours’;

function getAndSaveRss($options = array())
{
$default = array(
‘url’ => null,
‘limit’ => null,
‘categiry’ => null,
‘save’ => null,
‘offset’ => 0,
);
$options = am($default, $options);
$this->_parse($options);
}

function _parse($options)
{
$xml = new Xml($options[‘url’]);
$xml = Set::reverse($xml);

$i = 0;
// RSS1.0
if (isset($xml[‘RDF’])) {
$title = $xml[‘RDF’][‘Channel’][‘title’];
$link = $xml[‘RDF’][‘Channel’][‘link’];

$items = array();
foreach ($xml[‘RDF’][‘Item’] as $key => $item) {
if ($i >= $options[‘limit’]) {
break;
}
$items[$key][‘site_title’] = $title;
$items[$key][‘category’] = $options[‘category’];
$items[$key][‘site_url’] = $link;
$items[$key][‘pubDate’] = date(‘Y-m-d H:i:s’, strtotime($item[‘date’]));
$items[$key][‘title’] = $item[‘title’];
$items[$key][‘link’] = $item[‘link’];
if (isset($item[‘encoded’])) {
$items[$key][‘description’] = $item[‘encoded’];
} else if (isset($item[‘description’])) {
$items[$key][‘description’] = $item[‘description’];
}

if ($options[‘save’] == 1) {
$this->save_rss($items[$key]);
}
$i++;
}
}
// RSS2.0
elseif (isset($xml[‘Rss’])) {
$title = $xml[‘Rss’][‘Channel’][‘title’];
if (isset($xml[‘Rss’][‘Channel’][‘link’])) {
$link = $xml[‘Rss’][‘Channel’][‘link’];
} elseif (isset($xml[‘Rss’][‘Channel’][‘Link’][‘0’])){
$link = $xml[‘Rss’][‘Channel’][‘Link’][‘0’];
}
$items = array();
foreach ($xml[‘Rss’][‘Channel’][‘Item’] as $key => $item) {
if ($i >= $options[‘limit’]) {
break;
}
$items[$key][‘site_title’] = $title;
$items[$key][‘category’] = $options[‘category’];
$items[$key][‘site_url’] = $link;
if (isset($item[‘pubDate’])) {
$items[$key][‘pubDate’] = date(‘Y-m-d H:i:s’, strtotime($item[‘pubDate’]));
} else if (isset($item[‘date’])) {
$items[$key][‘pubDate’] = date(‘Y-m-d H:i:s’, strtotime($item[‘date’]));
}
$items[$key][‘title’] = $item[‘title’];
if (isset($item[‘link’])) {
$items[$key][‘link’] = $item[‘link’];
} else if (isset($item[‘guid’][‘value’])) {
$items[$key][‘link’] = $item[‘guid’][‘value’];
}
$items[$key][‘description’] = $item[‘description’];

if ($options[‘save’] == 1) {
$this->save_rss($items[$key]);
}
$i++;
}
}
// Atom
elseif (isset($xml[‘Feed’])) {
$title = $xml[‘Feed’][‘title’];
if (isset($xml[‘Feed’][‘Link’][‘href’])) {
$link = $xml[‘Feed’][‘Link’][‘href’];
} else if (isset($xml[‘Feed’][0][‘Link’][‘href’])) {
$link = $xml[‘Feed’][0][‘Link’][‘href’];
}
$items = array();
foreach ($xml[‘Feed’][‘Entry’] as $key => $item) {
if ($i >= $options[‘limit’]) {
break;
}
$items[$key][‘site_title’] = $title;
$items[$key][‘category’] = $options[‘category’];
if (isset($link)) {
$items[$key][‘site_url’] = $link;
} else {
$items[$key][‘site_url’] = $item[‘content’][‘xml:base’];
}
$items[$key][‘pubDate’] = date(‘Y-m-d H:i:s’, strtotime($item[‘issued’]));
$items[$key][‘title’] = $item[‘title’];
$items[$key][‘link’] = $item[‘Link’][‘href’];
$items[$key][‘description’] = $item[‘content’][‘value’];

if ($options[‘save’] == 1) {
$this->save_rss($items[$key]);
}
$i++;
}
}
else {
return false;
}
return compact(‘title’, ‘link’, ‘items’);
}

function save_rss($data)
{
$limit_title = $this->limit_title();
foreach ($limit_title as $v) {
if (strpos($data[‘title’], $v) !== FALSE) {
return FALSE; //広告などは外す
}
}

$this->data[‘Feed’] = array();

$sql = array(
‘conditions’ => array(
‘site_title’ => $data[‘site_title’],
‘title’ => $data[‘title’],
‘link’ => $data[‘link’]
)
);

$feed = $this->find(‘first’, $sql);
$this->data[‘Feed’] = $data;
if ($feed !== FALSE) {
$this->data[‘Feed’][‘id’] = $feed[‘Feed’][‘id’]; //update文にする
} else {
$this->data[‘Feed’][‘id’] = NULL; //insert文にする
}

$return = $this->save($this->data[‘Feed’]);
}

function limit_title() {
return array(
‘AD’,
‘PR’
);
}
}
[/php]

$ vi /app/controllers/components/feed_rss.php
[php]
<?php

class FeedRssComponent extends Object
{
var $controller;

function initialize(&$controller) {
$this->controller =& $controller;
}

function get_rss($limit = 5)
{
$feedArr = $this->feed_site();

foreach ($feedArr as $v) {
$url = $v[‘url’];
$category = $v[‘category’];
$save = 1;
$this->controller->Feed->getAndSaveRss(compact(‘url’, ‘category’, ‘limit’, ‘save’));
}
}

function set_rss($limit = 10)
{
$sql = array(
‘conditions’ => array(‘OR’ => array("Feed.category = ‘webdesign ‘", "Feed.category = ‘design’")),
‘order’ => ‘Feed.pubDate DESC’,
‘group’ => ‘Feed.title’,
‘limit’ => $limit,
);
$rssArr = $this->controller->Feed->find(‘all’, $sql);
$this->controller->set(‘rssArr’, $rssArr);
}

function remakeFeed($rssArr)
{
for ($i = 0; $i < count($rssArr); $i++) {
$rssArr[$i][‘Feed’][‘pubDate’] = substr($rssArr[$i][‘Feed’][‘pubDate’], 0, 4) . ‘-‘ . substr($rssArr[$i][‘Feed’][‘pubDate’], 5, 2) . ‘-‘ . substr($rssArr[$i][‘Feed’][‘pubDate’], 8, 2);
}
return $rssArr;
}
function feed_site()
{
return array(
‘★RSSのURL1★’,
‘★RSSのURL2★’,
‘★RSSのURL3★’,
‘★RSSのURL4★’,
‘★RSSのURL5★’,
‘★RSSのURL6★’,
‘★RSSのURL7★’
);
}
}
[/php]

で、表示したいコントローラーのアクション内で
[php]
$this->FeedRss->set_rss(15);
[/php]
とかでビューにデータを渡します。

終わり。

WRITE COMMENT


(required)


(required)


(required)

MENU

veltica creative of twitter