<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OTCHY.NET &#187; php</title>
	<atom:link href="http://www.otchy.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.otchy.net</link>
	<description>Otchy の技術ネタ。JavaScript 率と Twitter 率がやや高く、他にも PHP/Java/Perl などなど。共通点は Web。</description>
	<lastBuildDate>Wed, 25 Aug 2010 04:50:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>自前で短縮 URL。Simple Shorten URL 公開。</title>
		<link>http://www.otchy.net/20100129/simple-shorten-url/</link>
		<comments>http://www.otchy.net/20100129/simple-shorten-url/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 00:55:07 +0000</pubDate>
		<dc:creator>Otchy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.otchy.net/?p=941</guid>
		<description><![CDATA[自前のサーバに短縮 URL を設置したい場合の超シンプルな実装、Simple Shorten URL を作りました。DB を使わずに実装したので、レンタルサーバとかでも気軽に動かせるかと思います。
限定された URL 以 [...]]]></description>
			<content:encoded><![CDATA[<p>自前のサーバに短縮 URL を設置したい場合の超シンプルな実装、<a href="/php/simple-shorten-url/">Simple Shorten URL</a> を作りました。DB を使わずに実装したので、レンタルサーバとかでも気軽に動かせるかと思います。<br />
限定された URL 以下の URL のみ短縮可能で、特定用途にしぼった使い方を想定しています。もちろん短縮対象の URL と生成される短縮 URL のドメインは異なっていても構いません。</p>
<p>詳細については、<a href="/php/simple-shorten-url/">Simple Shorten URL</a> を見て下さい。<br />
OTCHY.NET 専用短縮 URL は <a href="http://otchy.net">http://otchy.net</a> で動作しています。</p>
<p>簡易実装と侮る事なかれ。<br />
ひたすらシンプルな実装にしたのでかなり高速に動作する上、自分専用という事で、ハッシュの長さを 3 にしているので、otchy.net で使うと、http://otchy.net/XXX となり、実は bit.ly の http://bit.ly/XXXXXX と同じ長さだったりします。</p>
<p>興味があればお試しを！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.otchy.net/20100129/simple-shorten-url/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Chart API を使って自サイトの合計はてブ数をグラフ化する</title>
		<link>http://www.otchy.net/20090804/total-hatebu-count-with-google-chart-api/</link>
		<comments>http://www.otchy.net/20090804/total-hatebu-count-with-google-chart-api/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 13:23:13 +0000</pubDate>
		<dc:creator>Otchy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[はてブ]]></category>

		<guid isPermaLink="false">http://www.otchy.net/?p=775</guid>
		<description><![CDATA[日頃、自サイトにはてブが付いて増えていく様子を、TopHatenar でグラフを見てほくそ笑んでいたりしたのですが、TopHatenar は更新が遅れることが多く、残念な気持ちになることも度々ありました。
そこで以前、せ [...]]]></description>
			<content:encoded><![CDATA[<p>日頃、自サイトにはてブが付いて増えていく様子を、<a href="http://tophatenar.com/" target="_blank">TopHatenar</a> でグラフを見てほくそ笑んでいたりしたのですが、TopHatenar は更新が遅れることが多く、残念な気持ちになることも度々ありました。</p>
<p>そこで以前、せめて記録だけは残そうと、<a href="/20090716/record-total-hatebu-count-to-csv-file/">自分のサイトの合計はてブ数を淡々と csv に記録し続ける</a>というエントリを書いて、それ以来ずっと記録しています。<br />
それでまあ、そろそろデータも貯まってきたので予告通り(？)、グラフ化してみる事にしました。<br />
ブログパーツのようにして、このサイトの右メニューにも貼り付けてあります。</p>
<p>大きく出すとこんな感じです。<br />
<iframe src="/hatebulog/hatebulog_big.php" style="width:400px;height:300px;border:0;margin:10px;" ></iframe></p>
<p>当初、PHP で何らかのライブラリを使用して楽をしようと思ったのですが、自分の希望を全て満たすものが見あたらなかったので、自力で Google Chart API を使用しています。</p>
<p>グラフの元になるデータは、<a href="/20090716/record-total-hatebu-count-to-csv-file/">自分のサイトの合計はてブ数を淡々と csv に記録し続ける</a>で取得したものです。<br />
下記のようなファイルになっています。</p>
<pre>
2009-07-16,204
2009-07-17,205
    ：
    ：
2009-08-03,245
2009-08-04,250
</pre>
<p>これを元に、Google Chart API のパラメータを生成して、グラフを表示しています。<br />
以下にソースを載せておきます。</p>
<pre class="height_middle">
&lt;?php

/* グラフ設定 */
$api = 'http://chart.apis.google.com/chart?'; // Google Chart API の URL
$width = 400; // 画像の横
$height = 300; // 画像の縦
$type = 'lc'; // グラフの種類 (折れ線グラフ)
$yUnit = 10; // Y軸の単位 (データの内容によって調整)
$csv = '/your_file_dir/hatebulog.csv'; // 読み取る CSV ファイル

/* データ取得 */
$fp = fopen($csv, 'r');
$data = array();
$isFirst = true;
while (($values = fgetcsv($fp)) !== FALSE) {
	if ($isFirst) {
		$firstDate = substr($values[0], 5);
		$isFirst = false;
	}
	$lastDate = substr($values[0], 5);
	array_push($data, (int) $values[1]);
}
fclose($fp);

/* yUnit に基づいてデータを正規化(0.0～100.0 の範囲に調整する) */
$min = (int) min($data); // グラフ上の最小値
while (($min % $yUnit) != 0) {
	$min--;
}
$max = (int) (max($data) + 1.0); // グラフ上の最大値
while (($max % $yUnit) != 0) {
	$max++;
}
$range = (float)($max - $min); // グラフ描画範囲
$normalizeData = array(); // 正規化データ
foreach ($data as $d) {
	$d = (float) $d;
	$d = ($d - $min)/$range * 100.0;
	array_push($normalizeData, number_format($d, 1));
}

/* min, max, yUnit に基づいて、Y軸を生成 */
$yAxis = array();
for ($y = $min; $y &lt;= $max; $y+=$yUnit) {
	array_push($yAxis, $y);
}
$yDiv = number_format((100.0 / (count($yAxis)-1)-0.1), 1); // Y 軸の分割

/* タグ を生成 */
$url = $api . 'chs=' . $width . 'x' . $height .
	'&amp;amp;cht=' . $type .
	'&amp;amp;chd=t:' . implode(',', $normalizeData) .
	'&amp;amp;chxt=x,y&amp;amp;chxl=0:|' . $firstDate . '|' . $lastDate . '|1:|' . implode('|', $yAxis) .
	'&amp;amp;chg=0,' . $yDiv
;
$tag = '&lt;img src=&quot;' . $url . '&quot; width=&quot;' . $width . '&quot; height=&quot;' . $height . '&quot; alt=&quot;&quot; /&gt;'
?&gt;
&lt;html&gt;
&lt;head&gt;
&lt;style&gt;
* {
	margin: 0;
	padding: 0;
	border: 0;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php echo $tag ?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>ソース中にざっくりとコメントを書いておきましたが、ポイントになるのは、Google Chaart API の線グラフでは、Y 軸の値が、0.0～100.0 と固定されていて、グラフを描画する値をその範囲の値に正規化しないといけない点です。<br />
値を正規化したら、Y 軸のラベルには、その正規化された世界で本来の値がどこになるのか、という情報を渡してやる必要がありますね。<br />
そんな処理が上に書かれています。</p>
<p>X 軸についてはシンプルに、最初と最後の日付を載せているだけです。</p>
<p><del datetime="2009-08-04T14:01:17+00:00">また、今回は元データが整数値なのですが、汎用性を考えて、仮に小数の値が元データになっても問題なく動作するように書いたつもりなので、小数のデータであってもきっと上手く動作するでしょう。</del><br />
整数値前提となっている部分がありました…。</p>
<h4>追記</h4>
<p>元データの行数が増えてくると、グラフとして描画するのが苦しくなってくることが予想されます。<br />
その場合、csv を保存した後に、tail -n 60 hatebulog.csv > hatebulog_tail.csv のようにしておいて、最新の何件かを取り出すようにするといいでしょう。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.otchy.net/20090804/total-hatebu-count-with-google-chart-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP で日本語のひらがなとカタカナと漢字を判別する方法 [UTF-8編]</title>
		<link>http://www.otchy.net/20090128/php-chartype-judgment-in-utf8/</link>
		<comments>http://www.otchy.net/20090128/php-chartype-judgment-in-utf8/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 16:26:01 +0000</pubDate>
		<dc:creator>Otchy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[utf-8]]></category>

		<guid isPermaLink="false">http://www.otchy.net/?p=244</guid>
		<description><![CDATA[ちょっと思うところあって調べたのでメモしておきます。
結局使わない事になったんですが。
mb_regex_encoding('UTF-8');
if (preg_match("/^[ぁ-んー]+$/u", $str))  [...]]]></description>
			<content:encoded><![CDATA[<p>ちょっと思うところあって調べたのでメモしておきます。<br />
結局使わない事になったんですが。</p>
<pre>mb_regex_encoding('UTF-8');
if (preg_match("/^[ぁ-んー]+$/u", $str)) {
    // ひらがな
} else if (preg_match("/^[ァ-ヶー]+$/u", $str)) {
    // カタカナ
} else if (preg_match("/^[一-龠]+$/u", $str)) {
    // 漢字
}</pre>
<p>mb_regex_encoding(&#8216;UTF-8&#8242;); は正規表現の基準となる文字コードの指定です。<br />
php.ini がいじれる環境なら、[mbstring] セクションに、mbstring.internal_encoding = UTF-8 とした方が良いかと思います。</p>
<p>[あ-ん] 等の指定は、Unicode 上でひらがなやカタカナを表す文字コードの最初と最後の文字を、範囲指定しています。<br />
また、厳密に言うと漢字の最後は &#8220;龠&#8221; では無いのですが、一般的に漢字と見なされる範囲の中で、最後にある JIS 第二水準の漢字であるため、この字を採用しています。(この漢字の範囲には、中国の漢字やハングルなどが含まれます)<br />
全然異なる文脈ですが、<a href="http://www.tanimoto.to/comp/bm.html" target="_blank">このページ</a>で詳しく考察されています。</p>
<p>preg_match の u フラグは、UTF-8 を正しく扱えるようにするためのフラグです。これがないと、文字コードの範囲指定などが正しく動作しないようです。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.otchy.net/20090128/php-chartype-judgment-in-utf8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
