PHPでCSVファイルを読み込む(その2)

(1/1)
PHP で CSV ファイルを読み込む」では、関数  fgetcsv  を利用し、CSV 形式ファイルを HTML の TABLE タグに変換するプログラムを紹介した。
しかし、関数 fgetcsv は、CSV ファイル中の空白文字を無視する。空白文字を含む場合は、フィールド囲い文字を利用し、"_空白文字がある" のようにするのが CSV の定石なので、このような動作になっているものと思われる。
そこで今回は、フィールド区切り文字が無くとも空白文字を扱うことができ、さらにデリミタやフィールド囲い文字を正規表現で指定できるオリジナルの fgetcsv をつくってみることにする。

サンプル・プログラム

サンプル・プログラムの解説:可変長引数

PHP の関数定義では、可変長引数を利用することができる。第一引数のみ必須で、第二引数以降はオプション(省略可能)であるようなユーザー関数を定義する場合、可変長引数を利用する。

関数  func_get_arg  は、その func_get_arg が含まれるユーザー関数のn番目の引数の値を返す。n=0 の時が第一引数、n=1 の時が第二引数‥‥という対応である。その引数がなければ FALSE を返す。
一般的には、 func_num_args  や  func_get_args  と組み合わせて利用される。

ここでは、関数  fgetcsv  と同じ引数が指定できることができるように $hancle のみ必須で、$length, $delimiter, $enclosure はオプションとした。
また、これらの引数が省略されている場合は、各々のデフォルト値が代入されるようにしてある。

0021:     $length    = @func_get_arg(1) != FALSE ? func_get_arg(1) : 0;
0022:     $delimiter = @func_get_arg(2) != FALSE ? func_get_arg(2) : ',';
0023:     $enclosure = @func_get_arg(3) != FALSE ? func_get_arg(3) : '"';
0024: 

サンプル・プログラムの解説:空白の処理

CSV ファイルの読み込みは、関数  fgets  を利用している。
読み取りに失敗したり、文字列長がゼロの場合(fgets は改行文字まで読み込むので、空行でも文字列長がゼロになることはない)、ファイルの終端に達したものと考える。

次に、空白文字を残し、行末の改行文字のみを削除するために関数  rtrim  を利用する。

0026:     if ($s == FALSE || $s == '')   return FALSE;
0027: 
0028:     $s = rtrim($s);
0029:     $arr = split($delimiter$s);

サンプル・プログラムの解説:CSVの分解

CSV を個々のフィールドに分解するのに、関数  split  を利用した。
split は正規表現を用いてフィールドを分解することができる

次に、フィールド囲い文字を削除するために関数  preg_replace  を利用した。

0030:     foreach ($arr as $key=>$val) {
0031:         $arr[$key] = preg_replace("/^\"(.*)\"$/", "$1", $val);
0032:     }
0033: 

サンプル・プログラムの解説:セキュリティ対策

 htmlentities  を用い、HTML タグや PHP スクリプトとして解釈される可能性がある特殊文字をHTML エンティティ(< >など)に変換してから表示する。
そのまま表示してしまうと、スクリプトとして実行され、システムの弱点を突かれる恐れがあるからである。

0078:             $val = preg_replace("/ /u", ' ', $val); //空白を に

参考書籍

(この項おわり)
header