徒然なるままに プログラミングメモや日々の生活などつれづれとつづっていくblog

2015年9月30日

PHPフレームワーク公開

Filed under: PHP,オープンソース,ソース配布 — ranpei @ 3:40 AM

仕事でPHPフレームワークを使ったときに以下の不満点がふつふつと湧き上がってきた。

・クラス名やメソッド名がURIパスになってしまう。

・各ファイルの配置先があらかじめ決められており自由度がない。

・内蔵ライブラリは便利だが外部ライブラリにもっと良いものがあるのに導入に手間がかかる。

 

上記の一部の不満点はメンバーから上がってきたもので

そのときはクラス名とメソッド名の変更で対応したもののもっとうまいやり方があったのでは?と思っていた。

 

もともとPHPは趣味でやっておりオレオレフレームワークで実装することが主だったため

既存フレームワークの良いところを取り入れつつ上記の不満点を解消できないかと試行錯誤していたものが形になったため

せっかくだから公開してみようとということになった。

 

ダウンロードから設置までの流れはこちらにまとめている。(内容が薄いため今後拡充していく予定)

 

現状ではフレームワークの骨組みはどのように作られているかという勉強用のソースという意味合いが強い。

最終的には小規模なシステム開発に向いたフレームワークとしていきたい。

(さすがに中大規模は無理なのでメジャーなPHPフレームワークを使用していただきたい。)

 

あと、ソース類はgithubなどのサービスを利用して配布していければ良いなーとか考えていたり・・・

2014年5月26日

あんてなサイトのサンプルソース公開

Filed under: PHP,アンテナサイト,ソース配布 — ranpei @ 3:53 AM

話題にしたの結構前ですが、公開するのすっかり忘れていました;;
というわけでソースを公開いたします。

基本的な部分は気ままアンテナ☆ミヾ(*´∇`)σと同じですが、
HTML部分は必要最低限のみを記載してシンプルにしています。

配布・解説等は試験的にConcrete5で構築したサイトで行っていますのでこちらをご覧ください。

ご質問等ありましたらコメント等でお願いします。

あんてなサイトサンプルダウンロード先:徒然なるままに

2013年7月7日

RSSリーダーを作ってみる その2

Filed under: PHP,アンテナサイト,ソース配布 — ranpei @ 1:38 AM

前回の公開したrssLoader
実はRSS2.0だとitemタグを解析できないというバグがある

どこが悪くて読み込めないかというと以下の部分

        // 各記事を取得する
        foreach($rssDom->item as $item) {
 
            $itemBean = new itemBean();

RSSのフォーマット・仕様・構造 – RSS1.0、RSS2.0、Content-Type」を見ていただくと分かるが
RSS1.0ではitemタグはchannelタグと同列のDom階層に存在するが
RSS2.0ではitemタグはchannelタグ配下のDom階層にある

RSS2.0を読み込むには「$rssDom->channel->item」としなければならないのだ

修正したソースは以下のようになる

<?php
require_once __DIR__."/channelBean.php";
require_once __DIR__."/itemBean.php";
require_once __DIR__."/rssException.php";
require_once __DIR__."/lib/httpConnecter.php";
require_once __DIR__."/lib/xmlLoader.php";

class rssLoader {

	const VERSION_1 = 1;
	const VERSION_2 = 2;

	const VERSION_ALL = 0;

	public function __construct() {
	}

	public function __destruct() {
	}

	/**
	 * RSSを読み込みchannelBeanで取得
	 *
	 * @param int $version 対象RSSバージョン指定
     *                    全バージョンのRSS  : rssLoader::VERSION_ALL
     *                    バージョン1.0のRSS : rssLoader::VERSION_1
     *                    バージョン2.0のRSS : rssLoader::VERSION_2
	 *
	 */
	public function loadRss($path, $version = self::VERSION_ALL) {

		/**
		 * RSSを取得
		 */
		$http = new httpConnecter();
		$http->connect($path);
		$rssStr = $http->loadText();
		if($rssStr === "") {

			// 取得できなければエラー
			throw rssException::notRss("RSSファイルの取得ができませんでした。");
		}


		/**
		 * RSSを解析
		 */
		$xml = new xmlLoader();
		$rssDom = $xml->parsor($rssStr);

		// すべてのバージョン
		if($version == self::VERSION_ALL) {

			try {

				return $this->loadRss2($rssDom);

			} catch (Exception $e) {

				return $this->loadRss1($rssDom);
			}
		}

		// rss1.0
		else if(isset($rssDom->attributes()->version) == false && $version == self::VERSION_1) {

			return $this->loadRss1($rssDom);
		}
		// rss2.0
		else if($rssDom->attributes()->version == 2 && $version == self::VERSION_2) {

			return $this->loadRss2($rssDom);
		}
		else {

			throw rssException::notMatchVersion("このRSSは正しい型式ではありません。");
		}

		return $channelBean;
	}

	/**
	 * RSS1.0を解析
	 * @param unknown $rssDom
	 */
	private function loadRss1($rssDom) {

		//if($rssDom->attributes()->version != self::VERSION_1) {

		//	throw rssException::notMatchVersion("このRSSはVertion1.0ではありません。");
		//}


		$channelBean = new channelBean();

		$channelBean->encoding = "UTF-8";
		$channelBean->rssVersion = self::VERSION_1;
		$channelBean->rssUrl = $rssDom->channel->link;


		// RSSの本体情報を取得
		if(isset($rssDom->channel->title)) {
			$channelBean->title = $rssDom->channel->title;
		}
		if(isset($rssDom->channel->link)) {
			$channelBean->link = $rssDom->channel->link;
		}
		if(isset($rssDom->channel->description)) {
			$channelBean->description = $rssDom->channel->description;
		}
		// dcの要素を取得
		$dc = $rssDom->channel->children('http://purl.org/dc/elements/1.1/');
		if(isset($dc->date)) {
			$channelBean->date = $dc->date;
		}
		if(isset($dc->language)) {
			$channelBean->language = $dc->language;
		}
		if(isset($dc->creator)) {
			$channelBean->creator = $dc->creator;
		}


		// ver1.0各記事を取得する
		foreach($rssDom->item as $item) {

			$itemBean = new itemBean();

			if(isset($item->title)) {
				$itemBean->title = $item->title;
			}
			if(isset($item->link)) {
				$itemBean->link = $item->link;
			}
			if(isset($item->description)) {
				$itemBean->description = $item->description;
			}
			if(isset($item->category)) {
				$itemBean->category = $item->category;
			}
			if(isset($item->pubDate)) {
				$itemBean->date = $item->date;
			}
			// dcの要素を取得
			$dc = $item->children('http://purl.org/dc/elements/1.1/');
			if(isset($dc->date)) {
				$itemBean->date = $dc->date;
			}
			if(isset($dc->subject)) {
				$itemBean->category = $dc->subject;
			}
			if(isset($dc->creator)) {
				$itemBean->creator = $dc->creator;
			}

			array_push($channelBean->itemList, $itemBean);
		}

		return $channelBean;
	}

	/**
	 * RSS2.0を解析
	 * @param unknown $rssDom
	 */
	private function loadRss2($rssDom) {

		if($rssDom->attributes()->version != self::VERSION_2) {

			throw rssException::notMatchVersion("このRSSはVertion2.0ではありません。");
		}

		$channelBean = new channelBean();

		$channelBean->encoding = "UTF-8";
		$channelBean->rssVersion = self::VERSION_2;
		$channelBean->rssUrl = $rssDom->channel->link;


		// RSSの本体情報を取得
		if(isset($rssDom->channel->title)) {
			$channelBean->title = $rssDom->channel->title;
		}
		if(isset($rssDom->channel->link)) {
			$channelBean->link = $rssDom->channel->link;
		}
		if(isset($rssDom->channel->description)) {
			$channelBean->description = $rssDom->channel->description;
		}
		// dcの要素を取得
		$dc = $rssDom->channel->children('http://purl.org/dc/elements/1.1/');
		if(isset($dc->date)) {
			$channelBean->date = $dc->date;
		}
		if(isset($dc->language)) {
			$channelBean->language = $dc->language;
		}
		if(isset($dc->creator)) {
			$channelBean->creator = $dc->creator;
		}


		// ver2.0各記事を取得する
		foreach($rssDom->channel->item as $item) {

			$itemBean = new itemBean();

			if(isset($item->title)) {
				$itemBean->title = $item->title;
			}
			if(isset($item->link)) {
				$itemBean->link = $item->link;
			}
			if(isset($item->description)) {
				$itemBean->description = $item->description;
			}
			if(isset($item->category)) {
				$itemBean->category = $item->category;
			}
			if(isset($item->pubDate)) {
				$itemBean->date = $item->date;
			}
			// dcの要素を取得
			$dc = $item->children('http://purl.org/dc/elements/1.1/');
			if(isset($dc->date)) {
				$itemBean->date = $dc->date;
			}
			if(isset($dc->subject)) {
				$itemBean->category = $dc->subject;
			}
			if(isset($dc->creator)) {
				$itemBean->creator = $dc->creator;
			}

			array_push($channelBean->itemList, $itemBean);
		}

		return $channelBean;
	}
}

上記ソースはほかにもネームスペース「dc」の要素が読み込めていない問題などを修正している

ダウンロードはこちらから→[download id=”1″]

2013年6月23日

RSSリーダーを作ってみる

Filed under: PHP,アンテナサイト,ソース配布 — ranpei @ 7:19 AM

ブログやニュースなどの更新情報を配信するために用いられるRSS
これを利用して複数のサイトの情報を取得表示しているのがアンテナサイトです。
今回ふと思い立ってこのアンテナサイトを作ることにしたので数回に分けて作成までの道のりをつらつらとつづって行こうと思います。
まずはRSSを解析する仕組みが必要なのですがググって見つかるソースは拡張モジュールのcurlを利用しているものばかり
基本的に拡張モジュールは使いたくないので自力で作ってみることにした。

・rssLoader.php

<?php

require_once __DIR__."/channelBean.php";
require_once __DIR__."/itemBean.php";
require_once __DIR__."/rssException.php";
require_once __DIR__."/lib/httpConnecter.php";
require_once __DIR__."/lib/xmlLoader.php";

class rssLoader {

	const VERSION_1 = 1;
	const VERSION_2 = 2;

	const VERSION_ALL = 0;

	public function __construct() {
	}

	public function __destruct() {
	}

	/**
	 * RSSを読み込みchannelBeanで取得
	 *
	 * @param int $version 対象RSSバージョン指定
     *                    全バージョンのRSS  : rssLoader::VERSION_ALL
     *                    バージョン1.0のRSS : rssLoader::VERSION_1
     *                    バージョン2.0のRSS : rssLoader::VERSION_2
	 *
	 */
	public function loadRss($path, $version = self::VERSION_ALL) {

		/**
		 * RSSを取得
		 */
		$http = new httpConnecter();
		$http->connect($path);
		$rssStr = $http->loadText();
		if($rssStr === "") {

			// 取得できなければエラー
			throw rssException::notRss("RSSファイルの取得ができませんでした。");
		}

		/**
		 * RSSを解析
		 */
		$xml = new xmlLoader();
		$rssDom = $xml->parsor($rssStr);

		$channelBean = new channelBean();

		$channelBean->encoding = "UTF-8";

		// rss1.0
		if(isset($rssDom->attributes()->version) == false) {
			$channelBean->rssVersion = self::VERSION_1;
			$channelBean->rssUrl = $rssDom->channel->link;

			if($version != self::VERSION_1 && $version != self::VERSION_ALL) {

				throw rssException::notMatchVersion("このRSSはVertion1.0ではありません。");
			}
		}
		// rss2.0
		else if($rssDom->attributes()->version == 2) {

			$channelBean->rssVersion = self::VERSION_2;
			$channelBean->rssUrl = $rssDom->channel->link;

			if($version != self::VERSION_2 && $version != self::VERSION_ALL) {

				throw rssException::notMatchVersion("このRSSはVertion2.0ではありません。");
			}
		}

		// RSSの本体情報を取得
		if(isset($rssDom->channel->title)) {
			$channelBean->title = $rssDom->channel->title;
		}
		if(isset($rssDom->channel->link)) {
			$channelBean->link = $rssDom->channel->link;
		}
		if(isset($rssDom->channel->description)) {
			$channelBean->description = $rssDom->channel->description;
		}
		// dcの要素を取得
		$dc = $rssDom->channel->children('http://purl.org/dc/elements/1.1/');
		if(isset($dc->date)) {
			$channelBean->date = $dc->date;
		}
		if(isset($dc->language)) {
			$channelBean->language = $dc->language;
		}
		if(isset($dc->creator)) {
			$channelBean->creator = $dc->creator;
		}

		// 各記事を取得する
		foreach($rssDom->item as $item) {

			$itemBean = new itemBean();

			if(isset($item->title)) {
				$itemBean->title = $item->title;
			}
			if(isset($item->link)) {
				$itemBean->link = $item->link;
			}
			if(isset($item->description)) {
				$itemBean->description = $item->description;
			}
			if(isset($item->category)) {
				$itemBean->category = $item->category;
			}
			if(isset($item->pubDate)) {
				$itemBean->date = $item->date;
			}
			// dcの要素を取得
			$dc = $item->children('http://purl.org/dc/elements/1.1/');
			if(isset($dc->date)) {
				$itemBean->date = $dc->date;
			}
			if(isset($dc->subject)) {
				$itemBean->category = $dc->subject;
			}
			if(isset($dc->creator)) {
				$itemBean->creator = $dc->creator;
			}

			array_push($channelBean->itemList, $itemBean);
		}

		return $channelBean;
	}
}

rssLoaderで解析するとchannelBeanクラスが返却される。
このchannelBeanクラス内部にitemBeanのリストがありそこに個々の記事のデータがあるといった感じ
itemBeanがchannelBeanの内部にあるのはRSS2.0ではchannelタグの内部にitemタグがあるからといった理由から

使い方は以下
・rssTest.php

<?php

require_once "rssLoader.php";

$rssLoader = new rssLoader();
try {
	$channel = $rssLoader->loadRss("http://watch2ch.2chblog.jp/index.rdf");// ネットワーク上のファイルの場合
	//$channel = $rssLoader->loadRss("/var/www/html/rss.rdf");// ローカルファイルの場合
} catch (Exception $e) {

	echo $e->getMessage();
}

?>
<html lang="ja">
	<head>
		<meta charset="utf-8" />
		<title>RSS</title>
	</head>

	<body>
		<h2><?=$channel->title ?></h2>
		<table border="1">
			<tr>
				<th>タイトル一覧</th>
				<th>記事</th>
				<th>作成日</th>
			</tr>
			<?php foreach($channel->itemList as $item): ?>
			<tr>
				<td><?=$item->title ?></td>
				<td><?=$item->date ?></td>
			</tr>
			<?php endforeach; ?>
		</table>
	</body>
</html>

ソースコードのダウンロードはこちら:[download id=”1″]

これでRSSを読み込んで記事情報を取り出すことはできました。

次回に続きます。

追記
このrssLoaderにはRSS2.0が読み込めないバグがあります。
修正版は後日別の記事にて掲載いたします。

Powered by WordPress