PHPプロ!TIPS+

1. strtotimeの落とし穴

strtotime関数はGNU Date Input Formats形式に準拠した文字列をタイムスタンプ形式に変えるためのものです。使用方法として、ある時点から何年前、何ヶ月 後、何日前などの日付を計算するためなどに使用できます。月末に実行されるスクリプト内に、strtotime関数を使用していると思わぬ落とし穴にはまることがあるので注意しましょう。

月末に以下のように先月の日付文字列を取得するコードを記述したとします。

$next_month = date('Y-m', strtotime('-1 month'));

このコードは3,5,7,10,12月の月末に実行すると、そのまま3,5,7,10,12月が返ってきてしまいます。これはなぜかというと、3月31日という日付から一ヶ月前を計算しようとしたときに、2月31日が存在せず、3月3日という日付が返ってきてしまうのが原因のようです。

なので、翌月、先月、何ヶ月前などの計算を行う場合は、mktime関数を使用して一つ一つ指定することになるでしょう。とはいっても、3月31日の一ヶ月前は明 確に「これだ!」といえる定義があるわけではないと思いますが。。

それと、これはTipsとはいえませんが、PHP 5から追加された日付関数date_sunrisedate_sunsetという日の出、日の入時刻を計算する関数を発見してしまいました。この関数は使われるのでしょうか。。

 
strtotime
 
http://jp2.php.net/strtotime
 
date_sunrise
 
http://jp2.php.net/date_sunrise
 
date_sunset
 
http://jp2.php.net/date_sunset

2. MagpieRSSで簡単にRSSを操作しよう

ブログを始めニュースサイト等などで更新情報を配信する手段としてRSSが使われています。皆さんはそれらRSSをどのように活用していますか?RSSリーダを利用してそのRSSを読むというのが一般的だと思います。既製のRSSリーダを利用して楽しむのも良いですが、PHPを使うとこれらRSSを取得し自分好みにアレンジして表示するということが簡単にできます。

今回紹介するのは、それをPHPで簡単に実現することができるライブラリ「MagpieRSS」です。

MagpieRSSは、GPLで開発されているRSSを解析するライブラリ、いわゆるRSSパーサです。PHPでリモートからRSSを取得して解析、キャッシュを行います。対応しているRSSはRSS 0.9からRSS 1.0とRSS 1.0のモジュールと、RSS 2.0とAtomの一部になります。

では早速使ってみましょう。MagpieRSSのサイトからMagpieRSSをダウンロードして解凍します。出てきたファイルの中で使用するのは基本的に、rss_cache.inc、rss_fetch.inc、rss_parse.inc、rss_utils.inc の4つのファイルとextlibディレクトリです。

これらを同じディレクトリ階層におき下記スクリプトを書き保存して実行してください。

<?php

require_once('rss_fetch.inc');
define('MAGPIE_OUTPUT_ENCODING''UTF-8');

$url 'http://www.phppro.jp/news/rss.php';
$rss fetch_rss($url);
$title $rss->channel['title'];
echo 
"<h1>$title</h1>\n";
echo 
"<dl>\n";
foreach (
$rss->items as $item ) {
    
$title $item['title'];
    
$link $item['link'];
    
$desc $item['description'];
    echo 
"<dt><a href=\"$link\">$title</a></dt>\n";
    echo 
"<dd>$desc</dd>\n";
}
echo 
"</dl>\n";

?>

PHPプロ!ニュースのRSSが読み込まれ整形されて表示されます。流れを簡単に説明すると、fetch_rss()で指定されたURLからRSSを取得、あとは配列にデータが入っているので欲しいものだけ取り出す。それだけです。

ちなみに、そのままでは日本語が文字化けを起こします。そのため、上記スクリプトでも行っていますが、

define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');

として、エンコーディングをUTF-8に変更するのを忘れないでください。

簡単にRSSを取得し自分の好みに操作できるMagpieRSS、ブログに埋め込んだり自作のRSSリーダを作成したり、可能性が広がるのではないでしょうか。

ちなみに、始めにも述べましたがMagpieRSSはGPLです。場合によってはプロジェクト内で使うには制約がきついかもしれません。その辺を十分考慮して使用 してください。

MagpieRSSのサイト: http://magpierss.sourceforge.net/

3. 2038年問題

32ビットPCでは数値を扱う限界があります。

PHPで日付を扱う事が多いと思いますが、UNIXタイムスタンプを利用すると数値の限界に引っかかる事を知っておく必要があります。

32ビットPCで扱う数値限界は 2の31乗-1 で、 2147483647 です。これをUNIXタイムとして日付に直すと、

<?php
$unixtime_max 
pow(231) - 1;
echo 
date('Y-m-d H:i:s'$unixtime_max) . "\n";

$unixtime_overflow $unixtime_max 1;
echo 
date('Y-m-d H:i:s'$unixtime_overflow) . "\n";
?>

2038-01-19 12:14:07
1901-12-14 05:45:52

となり、2038-01-19 12:14:07 以降の日付は扱えません。これを一般的に「2038年問題」と呼びます。

既に2038年を超えるデータを扱うシステムでは上記の問題に直面しているはずです。

末永く利用する(できる)システムでは、UNIXタイムスタンプを用いたコーディングは出来ません。

この問題を回避するには、PEARのCalcクラスを利用しましょう。

<?php
require_once "Date/Calc.php";

$nextday Date_Calc::nextDay('31''12''2999''%Y-%m-%d');
echo 
$nextday;
?>

3000-01-01

Calcクラスを使うと速度が遅くなってしまいますがUNIXタイムを扱いませんので、子孫にやさしいコーディングを行う事が出来ます。

PEAR::Date
http://pear.php.net/package/Date
date関数
http://jp2.php.net/date

バックナンバーについて

TIPS-MLは、毎週金曜日に更新され、新しい記事が掲載されます。

Tipsꗗy[W 

Pick Up Q&A

Q
PHPのHTML埋め込み記述について
 このエントリーをはてなブックマークに追加 
A
$_POST["data"] == "男" ? $val = "checked" : $val = "" ; の意味は以下と同じです。 if($_POST["data"] == "男"){ $val = "checked; } e...

>>続きを読む

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)