[PHP] Smartyプラグインの作り方

以前のバージョンのSmartyでは{php}ステートメントを使ってテンプレート内でPHPコードを実行できたけど、新しいバージョンでは出来なくなっている模様。本家サイトのマニュアルには以下のように明記されている。

IMPORTANT NOTICE
{php} tags are deprecated from Smarty, and should not be used. Put your PHP logic in PHP scripts or plugin functions instead.

対策はSmartyプラグインを作るしかない。以下にプラグイン作成の手順をまとめておく。

Smartyプラグインの作成手順

1. プラグインの名前を決める。

例えばログインしているユーザ名を取得するプラグインを作るとして名前をmynameとする。

2. するとプラグイン関数の名前が決まるのでPHPのコードを書く。

$paramsはテンプレートから渡ってくる引数で、例えばテンプレート中で{myname var1=’test’ var2=’123′}と呼び出されると、params[‘var1’]=’test1′, params[‘var2’]=’123′ というように配列が渡ってくる。パラメータが指定されずに呼び出される場合も想定してisset(params[‘var1’]) といったチェックを行うこと。

プラグイン関数からの戻り値が必要ない場合にはreturnステートメントを書かなくてもいいけど、処理が正常終了したか真偽を返すといいかも。引数の$smarty変数の参照を利用すれば、例えば$smarty->assign(‘result’, $answer)というようにプラグイン関数内でテンプレート変数をセットすることも可能。

3. 作成したプラグインファイルを <Smartyパス>/libs/pluginsディレクトリに配置する。

Smartyの設定で異なるプラグインディレクトリを設定している場合にはそれに従う。

4. テンプレートからプラグインを呼び出す。

参考サイト

Chapter 18. Extending Smarty With Plugins | Smarty
http://www.smarty.net/docs/en/plugins.tpl

[PHP] どのコーディング規約で開発すべきか

フレームワークを使わないでスクラッチからコードを書くときは、自分でコーディング規約を決める必要がある。どうしたものかとネットを検索したらぴったりの記事を発見したのでリンクしておく。この記事では以下の結論で結んでいる。

利用しているフレームワークの規約がないなら、 PSR-2(日本語) に従っておけば、間違いない!

どのコーディング規約で開発すべき? PHPコーディング規約まとめ – Qiita
http://qiita.com/hshimo/items/04be1f432240c58300f4

PSR-2 というのは、プロジェクトの開発者で組織するPHP-FIGというグループが話し合って決めたコーディングスタイルガイドらしい。

PSR-2 コーディングガイド(日本語)|北海道札幌市のシステム開発会社インフィニットループ
http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html

PHP-FIGのウェブサイトは以下。オープンソースの著名なプロジェクトの開発者がメンバーとして名前を連ねている。

PHP-FIG — PHP Framework Interop Group
http://www.php-fig.org/

最初の記事中にもいろいろリンクされているけど、著名なプロジェクトはそれぞれ独自のコーディング規約を定めている。以下参考まで。

変数の命名規則 – PHPリファレンス
http://alphasis.info/2012/05/php-variable-name/

命名規約 – Zend Framework PHP 標準コーディング規約 – Zend Framework
http://framework.zend.com/manual/1.12/ja/coding-standard.naming-conventions.html

コーディング規約 — CakePHP Cookbook 2.x ドキュメント
http://book.cakephp.org/2.0/ja/contributing/cakephp-coding-conventions.html

[PHP] セッションの基本的な使い方

基本的な操作を簡単にまとめておく。

セッションの開始

session_start関数をコールする。

セッションがまだ開始されていない場合は、セッションIDが割り当てられて新しいセッションが開始される。具体的には、サーバーで生成されたセッションIDがブラウザに送られ、”PHPSESSID”という名前でクッキーに保存される。サーバー側では、セッション変数を保存するための作業ファイルが作成される。

既にセッションが開始されている場合は、クッキーに保存されているセッションIDのセッションが利用できるようになる。

“PHPSESSID” という名前はPHPにおけるデフォルト設定である。サーバーによっては、異なる名前に変更されているかもしれない (php.ini を編集することで変更できる)。プログラム中で “PHPSESSID” の文字列を直接指定する代わりに、session_name関数を使うことで、環境に依存しないプログラムが書けるだろう。 サーバー上に作成される作業ファイルにはセッションIDの名前が付いている。僕のXAMPP環境では、セッションID “ddsuj7031ir4eqk7h6oivs9215″ に関して、C:xampptmpsess_ddsuj7031ir4eqk7h6oivs9215 というファイルが作成されていた。新しいセッションが始まったばかりの状態では中身は空である (ファイルサイズはゼロ)。

セッション変数の読み書き

セッション変数はグローバル配列 $_SESSION 経由でアクセスする。

サーバー上の作業ファイルを覗いてみると、セッション変数が以下のように格納されていた。

セッション変数やセッションの削除

特定のセッション変数を削除したければ、$_SESSION 配列からその要素を削除すればよい。

全てのセッション変数を削除したければ、$_SESSION配列そのものを空にしてやればよい。

セッションを終了してデータを残骸無しに削除したければ、以下の全てを削除するべきである。

  • クッキー (セッションID)
  • グローバル変数 ($_SESSION配列)
  • セッションデータ (サーバーの作業ファイル)

セッションIDの再生成

サーバーに格納されているセッションデータは、セッションIDが漏れることで第三者にセッションを乗っ取られる危険性を秘めている (セッションハイジャックと呼ばれる)。そこで、同じセッションIDを長時間使うことを避け、頻繁にセッションIDを変更することが推奨される。 これを行うためにsession_regenerate_id関数が用意されている。この関数をコールすることで、現在のセッションのデータを保持したまま、セッションIDを新しくすることができる。

セッションハイジャックのリスクに関しては、また別の機会に考察してみたい。

参考サイト

PHP: Sessions – Manual
http://php.net/manual/ja/book.session.php

[PHP] クッキーの基本的な使い方

基本的な操作を簡単にまとめておく。

クッキーの送信

setcookie関数を使う。失敗するとFALSEが戻る。

クッキーの読み取り

クッキーの値はグローバルな連想配列 $_COOKIE にセットされる。

クッキーの更新

setcookie関数を使う。クッキーが既に存在すれば上書きされる。

クッキーの有効期限設定

setcookie関数の3番目の引数にUnixのタイムスタンプを秒単位で指定する。

クッキーの削除

過去の時刻を指定すると削除される。

配列

クッキーには配列を保存することもできる。

クッキー数の制限

クッキーの数には制限がある。ブラウザ依存。以下リンクを参照。

Browser Cookie Limits
http://browsercookielimits.x64.me/

参考サイト

PHP: クッキー(Cookies) – Manual
http://php.net/manual/ja/features.cookies.php

PHP: setcookie – Manual
http://php.net/manual/ja/function.setcookie.php

PHP: $_COOKIE – Manual
http://php.net/manual/ja/reserved.variables.cookies.php

[PHP] HTTPヘッダからクッキーの仕組みを理解する

クッキーはウェブサーバーとウェブブラウザ間で状態を管理する仕組みである。

Wikipediaではその動作を以下のように説明している。

クッキーでは次のようにサーバとクライアント間の状態を管理する。

1. ウェブサーバがウェブブラウザにその状態を区別する識別子をHTTPヘッダに含める形で渡す。
2. ブラウザは次にそのサーバと通信する際に、与えられた識別子をHTTPヘッダに含めて送信する。
3. サーバはその識別子を元にコンテンツの内容をユーザに合わせてカスタマイズし、ブラウザに渡す。必要があれば新たな識別子もHTTPヘッダに含める。
以降2、3の繰り返し。

この仕組みによって、ステートレスなプロトコルであるHTTP上でステートフルなサービスを実現する。ここで注意すべき点は、一度設定されたクッキーは、条件を満たす限り何度でも要求に組み込まれるという点である。HTMLページの要求だけでなく、画像を含むすべての要求が対象となる。

HTTP cookie – Wikipedia
http://ja.wikipedia.org/wiki/HTTP_cookie

サーバー・ブラウザ間でやり取りされるHTTPヘッダを実際にダンプして動作を検証してみる。

ブラウザがクッキーを食べていない状態

HTTPヘッダにはクッキーの情報が含まれていない。

サーバーからブラウザへクッキーを送信するとき

サーバーが送るHTTPヘッダにクッキーの情報が含まれている。

以後、クライアントがサーバーとやり取りするとき

クライアントが送るリクエストにクッキーの情報が含まれている。

クッキーの有効期限が切れた後

もはやクライアントはサーバーにクッキーの情報を送らない。

HTTPヘッダで見ると動作が理解しやすい。

[PHP] 特定のタイムゾーンの日時を取得する

PHPの日時関数(date)は、ローカルの日時を取得する。ローカルとは、サーバーに設定されているタイムゾーンのこと。たとえば、もしアメリカに設置されているサーバーで実行するコード中で日本時間を取得したければどうするか。

PHPにはスクリプト中で使われるデフォルトタイムゾーンを設定する関数(date_default_timezone_set)がある。この関数を使って希望するタイムゾーンを設定した後に日付を取得すればよい。

もしスクリプト内で別のタイムゾーンの日時を必要とする箇所があるならば、必要なときだけタイムゾーンを変更し、必要無くなったら元のタイムゾーンに戻しておくなどの配慮をしておくべきだろう。

参考サイト

PHP: date_default_timezone_get – Manual
http://php.net/manual/ja/function.date-default-timezone-get.php

PHP: date_default_timezone_set – Manual
http://php.net/manual/ja/function.date-default-timezone-set.php

PHP: サポートされるタイムゾーンのリスト – Manual
http://php.net/manual/ja/timezones.php

[PHP] ローカルの日付/時刻を文字列として取得する

date関数を使うことで文字列が得られる。

良く使いそうな書式は以下の通り。

種別 書式 説明 戻り値の例
Y 4桁の数字 例: 1999または2003
y 2桁の数字 例: 99または03
F フルスペル JanuaryからDecember
M 三文字形式 JanからDec
m 数字。先頭にゼロ付き 01から12
n 数字。先頭にゼロ無し 1から12
t 指定した月の日数 28から31
d 二桁の数字 01から31
j 数字。先頭にゼロ無し 1から31
z 年間の通産日。ゼロから始まる数字 0から365
S 英語の序数を表す2文字のサフィックス (1st,2nd,3rd,4th…) st,nd,rdまたはth
曜日 l フルスペル SundayからSaturday
D 3文字 SunからSat
N 曜日の数値表現 1(月曜日)から7(日曜日)
W 月曜日に始まる年単位の週番号 例: 42 (年の第42週目)
時刻 a 午前または午後 (小文字) amまたはpm
A 午前または午後 (大文字) AMまたはPM
g 時。12時間単位。先頭にゼロ無し 1から12
G 時。24時間単位。先頭にゼロ無し 0から23
h 時。12時間単位 01から12
H 時。24時間単位 00から23
i 00から59
s 00から59

参考サイト

PHP: date – Manual
http://php.net/manual/ja/function.date.php

[PHP] サーバー情報および実行時の環境情報 ($_SERVER)

サーバー情報および実行時の環境情報はグローバル配列 $_SERVER[] にセットされる。サーバーでphpinfo関数を実行することで実際の値を確認することも可能。

以下に、良く使いそうなインデックスをマニュアルから抜粋しておく。

‘PHP_SELF’
現在実行しているスクリプトのファイル名です。 ドキュメントルートから取得されます。 例えば、http://example.com/foo/bar.php というアドレス上にあるスクリプトでは $_SERVER[‘PHP_SELF’] は /foo/bar.php となります。

‘SERVER_ADDR’
現在のスクリプトが実行されているサーバーの IP アドレスです。

‘SERVER_NAME’
現在のスクリプトが実行されているサーバーのホスト名です。 スクリプトがバーチャルホスト上で実行されている場合は そのバーチャルホスト名となります。

‘REQUEST_METHOD’
ページにアクセスする際に使用されたリクエストのメソッド名です。 ‘GET’, ‘HEAD’, ‘POST’, ‘PUT’ など。

‘DOCUMENT_ROOT’
現在実行されているスクリプトが存在するドキュメントルート ディレクトリです。サーバーのコンフィグレーションファイルで 定義されています。

‘HTTP_REFERER’
現在のページに遷移する前にユーザーエージェントが参照していた ページのアドレス(もしあれば)。これはユーザーエージェントに よってセットされます。全てのユーザーエージェントが これをセットしているわけではなく、また、HTTP_REFERER を変更する機能を持つものもあります。 要するに、信頼するべきものではありません。

‘HTTP_USER_AGENT’
現在のリクエストに User-Agent: ヘッダが もしあればその内容。ページにアクセスしてきているユーザーエージェント のしるしの文字列です。典型的な例は、 Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586)。たとえば、 get_browser() でこの値を使って ページの出力をそのブラウザにあわせたものにすることも できるでしょう。

‘REMOTE_ADDR’
現在ページをみているユーザーの IP アドレス。

‘REMOTE_HOST’
現在のページにアクセスしているホスト名。DNS の逆引き検索は ユーザーの REMOTE_ADDR に基づいています。

‘SCRIPT_NAME’
現在のスクリプトのパス。 スクリプト自身のページを指定するのに有用です

‘REQUEST_URI’
ページにアクセスするために指定された URI。例えば、 ‘/index.html’

‘PHP_AUTH_USER’
HTTP 認証しているときにそのユーザー名がセットされます。

‘PHP_AUTH_PW’
HTTP 認証しているときにそのユーザーの パスワードがセットされます。

‘AUTH_TYPE’
HTTP 認証しているときにその認証形式がセットされます。

参考サイト

PHP: $_SERVER – Manual
http://php.net/manual/ja/reserved.variables.server.php

[PHP] アクセス元のホスト名を取得する

ホスト名からIPアドレスを取得することを「正引き」、IPアドレスからホスト名を取得することを「逆引き」と言う。すなわち、アクセス元のIPアドレスからホスト名を「逆引き」する方法。

アクセス元のIPアドレスは、サーバー変数 $_SERVER[‘REMOTE_ADDR’] にセットされる。gethostbyaddr関数を使うことで、IPアドレスからホスト名を取得することができる。

gethostbyaddr関数は、ホスト名が取得できなかった場合は、引数のIPアドレスをそのまま返す。引数のIPアドレスが不適切な場合にはFALSEを返す。

参考サイト

PHP: gethostbyname – Manual
http://php.net/manual/ja/function.gethostbyname.php

[PHP] 経過時間を計測する

処理の実行時間を計測したい場合がある。

処理の前後でシステム時刻を取得して差をとることで経過時間が得られる。

単位はマイクロ秒(100万分の1秒、10のマイナス6乗秒)。

参考サイト

PHP: microtime – Manual
http://php.net/manual/ja/function.microtime.php