第2回 HTTP クラス - RFCに従ったプロトコル通信 - PEAR講座
くまっち先生のPEAR講座
Lecutures on PHP
第2回 HTTP クラス - RFCに従ったプロトコル通信 (その1)
RFCを守っていますか?

RFC (Request for Comments) とは、インターネットに関する様々な技術仕様、およびルールを取りまとめているテキスト群です。「インターネットの標準化」というべき代物で、皆さんが普段利用しているインターネットにおけるブラウジングやメールといったアプリケーションもすべてこのRFCによって定められた仕様に基づき作られています。メールのやり取りを行うために相手とメールソフトを統一する必要がないのも、おおよそ全てのメールソフトがRFCの仕様をクリアし、仕組みに従ったつくりをしているからなのです。
さて、私たちがPHPを利用してWebページおよびアプリケーションを動作させている背景では、やはりRFCに則った仕組みとやり取りが用いられています。いわゆる「プロトコル (protocol)」と呼ばれるものがまさにこれです。普段こういった処理を全く意識せずに済んでいる訳は、Webサーバ (Apache, IISなど) やPHPそのものが自動的にハンドリングしてくれているからです。しかし時には、このプロトコル処理を自分自身で行わなければならないケースが、実はあります。
数多くあるRFCの中には複雑で面倒な仕様なものも含まれていますが、それらはある程度のパターンルールに限られていたり内容が固定であったりします。こういったものこそ、ユーティリティとしてライブラリを使用することで簡単にその恩恵に与りたいところです。また正しいプロトコル処理を実現する上でも、正しく実装された内容を利用するということも重要なアプローチといえます。
今回はこのプロトコル処理の1つであるHTTP (Hyper-Text-Transfer-Protocol) の簡単な機能を提供してくれるライブラリ、HTTPパッケージとして提供されているHTTPクラスを取り上げ、その中身を読んでみることにしましょう。
正しい日時フォーマットを得るために
HTTP通信では、たとえば「決められた形式(フォーマット)に従った送信日時を相手に伝えましょう」というルールがRFCによって定められています。日時フォーマットは、この仕様を初めて示した「RFC822」という規定に由来して「RFC822形式」と呼ばれており、メールデータやWWWデータといった様々なHTTP通信で用いられています。
以下がその日時フォーマットの仕様です。
Date: date-time CRLF date-time = [ day "," ] date time day = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" date = day month year month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" time = hour zone hour = 00:00:00 - 23:59:59 zone = 世界時(Universal Time)
なにやら複雑なようにも見受けられますが、以下のような実際にフォーマットされた形式をみれば、おおよそ理解できるのではないでしょうか。
Date: Mon, 14 May 2007 13:05:13 GMT
さて、この日時フォーマットの内容を得ることができる機能がHTTPクラスに準備されています。それがリスト1に示すDateメソッドです。
リスト1 Dateメソッド
function Date($time = null)
{
if (!isset($time)) {
$time = time();
} elseif (!is_numeric($time) && (-1 === $time = strtotime($time))) {
return false;
}
// RFC822 or RFC850
$format = ini_get('y2k_compliance') ? 'D, d M Y' : 'l, d-M-y';
return gmdate($format .' H:i:s \G\M\T', $time);
}

まずはじめの条件分岐文を見てみると、メソッドの引数値がセットされていなければ、time関数によって現在の日時を取得し以後取り扱うデータであるとしています。このようにメソッドの引数値を正しい値へと調整する処理を「正規化処理 (normalize)」といいます。
また引数値が「日時を表す値」か否かをチェックし、問題があればfalseを返すことで処理を終了するようにしています。本当に正しいかどうかをまず確認し、場合によっては処理を中断・終了する手法は、前回でも紹介した「ガード節」です。
続いて、コメントアウトされた説明文と共に実行している三項演算子があります。ここでは、PHPの設定内容の1つである「y2k_compliance」(*1)の内容を元に、最終的に出力する日時のフォーマット内容を決定しているようです。
y2k_complianceは2000年問題に対応できていないWebサーバなどで動作させる場合に調整する値ですが、現在ではtrueが初期値になっていますので、通常は前者のフォーマットが使用されることになるはずです。この値の調整も実は前述の正規化処理の1つにあたります。
最後に、gmdate関数を利用して書式化された日時のテキストデータを作成しその値を返しています。書式化するフォーマットがRFCに則ったものになっています。
この最後の関数実行こそが本機能の本体でありメインだといえますが、それ以前の正規化もまたとても重要な処理です。正規化処理に漏れがあった場合、メインである関数実行を行ったにも関わらず正しい日時データを作成することが出来ないかもしれません。メソッドを正しく作成するその基本は、引数として飛んでくる値の可能性を考えることと、その値を正しく調整することです。
ちなみに、PEARパッケージを作成する上においても、RFCとは違いますが「標準コーディング規約」という規約があります。
この標準コーディング規約における命名規約(*2)では、関数およびメソッドは先頭単語の頭のみを小文字にした「studly caps形式」(キャメルケース・lowerCamelCaseともいいます)で名称を決定すべきと書かれています。したがって正しく規約に従うのなら、このメソッドの名前は先頭文字を大文字"D"にするのではなく小文字"d"とした「date」がよいでしょう。
- くまっち先生のワンポイント講座 -
コーディング規約

プログラムコードを記述していく上で、クラスやメソッド、変数の名称について、マニュアルや各言語のコミュニティ (PEARなど) などから形式的な規定を推奨していることが多くあります。これは主に「可読性がある」「どのような役割を持つものなのか理解しやすい」といった目的のための手法が考えられ、それらを規定として設けてられています。
代表的な手法として以下のようなものがあります。
- キャメルケース
1まとめの複合語を記述する際、単語の最初を大文字で書き表す手法です。 (例:UserId, SupportEmail) 先頭単語の最初も大文字で書くUpperCamelCase、先頭単語のみ小文字で書くlowerCamelCaseといったキャメルケースをより詳細にした手法もあり、PEARでは関数やクラスメソッドに対して後者のlowerCamelCaseを用いて命名することを推奨しています。 - アンダースコア
1まとめの複合語を連続して記述する際、単語同士をアンダースコア (_) で連結して書き表す手法です。 (例:User_ID, support_email) アンダースコアで繋げること以外、大文字/小文字は自由に (可読性を損なわないレベルで) 使用することができます。
なお、これら手法をより効果的なものとするため、
- 意味のない名称を利用しない (駄目な例:a, b2, ccc など)
- 単語を不必要に略さない (駄目な例:メッセージ => msg, ユーザデータ => udata など)
といった点に注意し、自分自身はもちろん第三者が見ても理解しやすい単語や連語(場合によっては文章)を名称として使用することが重要です。
*1)
http://jp.php.net/manual/ja/ini.core.php#ini.y2k-compliance
- 1
- 2





ページのトップへ


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