ファイルの読み込み(書き込み)に失敗する場合

ファイルシステム関数は、文字列を扱う関数や配列を扱う関数と異なり、プログラムの実行環境の影響を受けます。たとえば冒頭で取り上げたプログラム(fs1.php)をもう一度見てみましょう。

<?php
$str = "Hello World" . PHP_EOL;
$file = "hello.txt";
file_put_contents($file, $str);

このプログラムは正しく動作するように見えますが、以下のようなケースではエラーとなってしまいます。

  • 他のプログラムがファイルを処理(ロック)の場合
  • ファイルの書き込み権限がない場合
  • ディスク容量が足りない場合

上記のようなケースはプログラムの作り方に不具合があるのではなく、プログラムの動作する環境側の問題と言えます。

このような問題はファイルシステムのやりとり以外でも、ネットワークやデータベースにアクセスする場合にも考えないといけません。

そのためここで紹介したファイルシステムを扱う関数のほとんどは、実行時にエラーが発生した場合、関数の戻り値にfalseを返す仕組みになっています。

たとえば先ほどのプログラム(fs1.php)の場合、以下のようにfile_put_contents関数の戻り値を判定することでファイルの書き込未失敗を検出することができます。

<?php
$str = "Hello World" . PHP_EOL;
$file = "hello.txt";
$result = file_put_contents($file, $str);
if ($resutl === false) {
  echo "error" . PHP_EOL;
}

file_put_contents関数は、正常にファイルに書き込めた場合は、書き込んだデータのバイト数を戻り値で返しますが、ファイルの書き込みに失敗した場合はfalseを返却するようになっています。上記のように戻り値をif文で確認することで、ファイル書き込みに失敗した場合の後処理を実装することができます。

もう一つ例を見ておきましょう。先に取り上げたファイルを読み込むプログラム(fs5.php)を見てみましょう。

$file = "hello.txt";
$handle = fopen($file, "r");
while(($line = fgets($handle)) !== false) {
  echo $line;
}
fclose($handle);

fopen関数で読み込み対象のファイル名hello.txtを指定していますが、実行環境によってはhello.txtファイルが存在しない可能性も考えられます。fopen関数は、通常戻り値としてファイルポインタを返しますが、読み込み対象のファイルが存在しない場合やアクセス権限が不足する場合などは戻り値にfalseを返します。そのため以下のように実装することでファイル読み込みの失敗を検出することができます。

<?php
$file = "hello.txt";
$handle = fopen($file, "r");
if ($handle === false) {
  die("can't open file");
}
while(($line = fgets($handle)) !== false) {
  echo $line;
}
fclose($handle);

上記のプログラムでは$handle変数がfalseの場合にはdie関数を使って処理を異常終了させています。PHPのプログラムはdie関数を呼び出すとその場でメッセージを出力して処理を終えるようになっています。ここではファイルのオープンに失敗した場合は後続の処理を実行せずに停止するようにしています。


前へ | 次へ