PHPプロ!TIPS+

1. 関数の知られざる引数(print_r関数、session_regenerate_id関数)

PHPの関数の中には、最初は引数として用意されていなかったものの、後々追加されたものが多く存在します。今回はその中から、よく使われる2つの関数、print_r関数とsession_regenerate_id関数の知られざる引数を紹介しようと思います。

print_r関数は、変数やオブジェクトの中身を美しく表示してくれるため、開発時に重宝している方も多いでしょう。たとえば下のように使用します。

print_r($a);

これで、変数$aの内容が美しくフォーマットされて、ブラウザに出力されます。実は、PHP 4.3.0からは2番目の引数が追加されました。これは、trueを指定すると、ブラウザに出力するのではなく、その文字列を返却してくれるものです。たとえば

$dump = print_r($a, true);

と記述すると、ブラウザに出力されていたデータを$dump変数で受け取ることができます。

後は、これをメールで送信するなりerror_log関数ではき出すなり、好きに加工できるので便利です。

同じように、PHP 5.1からはsession_regenerate_id関数にも第1引数が指定されました。第1引数をtrueに指定すると、古くなったセッションは削除されるようになります。

もともとセッション固定攻撃を防ぐために用意された関数ではなく、PHP 5.1までの同関数には古いセッションファイルを削除する機能が無かったため、セッション固定攻撃への対策としては不十分でした。

今後は、session_regenerate_id関数の引数に必ずtrueを指定することを忘れないようにしましょう。また、それまでのPHPで使う場合は、以下のコードを使うことで、セッション固定攻撃を防ぐことができます。

$old_session_id = session_id();
session_regenerate_id();
unlink(session_save_path() . '/sess_' . $old_session_id);

それぞれの関数についての詳細は、マニュアルをご覧ください。

2. ストリーム関数を使ってみよう

ストリーム関数をご存じですか?PHP 4.3.0から導入された機能で、汎用のファイル関数を利用して、ファイル以外の各リソースやストリームを扱えるようにするための関数群です。今回は、ストリーム関数を使って外部URLの読み込みや、gzip形式で圧縮されたファイルを読み書きする例を紹介していきましょう。

ひょっとしたら、既にストリーム関数を使ったことがあるかもしれません。たとえば、 外部のWebサイトの情報を取り出したいときには、httpラッパーを使って以下のように記述できます。

$html = file_get_contents("http://www.asial.co.jp/");

これで、URLがhttp://www.asial.co.jp/のHTMLを、$html変数に格納できます。もちろんfile_get_contents関数以外にも、fopen関数なども使用できます。では次に、zlib形式の圧縮ファイルを操作する例を見てみましょう。zlibラッパーを使うと、gzip形式(拡張子gz)のファイルを操作できます。

ファイルを読み込むには、以下のように記述します。

$contents = file_get_contents("compress.zlib:///home/masahiro/test.gz");

これで、$contentsに/home/masahiro/test.gzの内容が読み込まれます。同じように、文字列を圧縮してファイルに保存したい場合は、

$fp = fopen("compress.zlib:///home/masahiro/test.gz", "w");
fputs($fp, $contents);
fclose($fp);

と記述することで、$contentsの内容をファイルに保存できます。

PHPの構築時にオプション指定が必要なものもありますが、expectやSSH、FTP、HTTPSプロトコルなどもサポートされています。また、独自にストリームを定義することも可能です。

他にも、いろいろなラッパーが用意されています。ラッパーの一覧は、
http://www.phppro.jp/phpmanual/php/wrappers.htmlをご覧いただくと良いでしょう。

また、ストリーム関数の詳細は、
http://www.phppro.jp/phpmanual/php/ref.stream.htmlを参照してください。

3. session_destroy関数はファイルを消すだけで、スクリプト内ではセッション変数が使えてしまう

アプリケーション作成に不可欠なセッション変数ですが、セッションを正しく消さなければ不具合の原因のみならず、脆弱なアプリケーションとなってしまいます。

正しくセッションを消す方法を知っておきましょう。

PHPアプリケーションを作成する時に、セッション変数の利用は不可欠と言っても過言ではないでしょう。

しかしセッションには攻撃所が多く、脆弱なアプリケーションを多数見かけます。

session_regenerate_id( true ) としてセッションIDを変えるのは非常に有効な手段ですが、逆に不要なセッションは必ず破棄しなければ後々、脆弱性や不具合の原因となります。

例えばログアウトメカニズムのような実装をする場合、session_destroy()を利用していませんでしょうか?

session_destroy()は実際にセッションファイルを削除しているのですが、メモリ内の$_SESSION変数は残り続けてしまいます。以下のような検証コードを実行し、出力結果をご覧ください。

<?php
  session_start
();

  
$_SESSION['login'] = 'login';

  
session_destroy();

  
print_r($_SESSION);
?>

これでセッション変数が残っている事が確認できます。

(※session_regenerate_id()をした場合、PHP5.1.2では否応無しにセッション破棄に失敗してWarningが出る)

正しくログアウト(セッション変数を全て破棄)するにはメモリ内のセッション変数をarray()関数で初期化しましょう。

$_SESSION = array();
session_destroy();

バックナンバーについて

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

Tipsꗗy[W 

Pick Up Q&A

Q
array_mergeの再帰処理の動作について
 このエントリーをはてなブックマークに追加 
A
>1個になったとき$leftを返しますが、 >このとき、最終的な$leftはnullになるかと思います。 いいえ、最後は「渡された配列をそのまま」返します。要素が2以上あるときとの違いは(並べ替えずに戻るので...

>>続きを読む

再帰関数は最初の内は混乱しますが、非常に上手く使える場面もいずれ出てきます。これを機会に学んでいけるといいですね。

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