fopen()関数を使用して、マシン上にあるファイルを開くことができます。
fopen( filename, mode );
1. ローカルディスク(C:)直下に、ディレクトリを作成する。
(今回はtemplateという名前のディレクトリを作成しています)
2. 作成したディレクトリに、txtファイルを作成します。
(今回はsample.txtという名前のtxtファイルを作成しています)
3. 作成したtxtファイルに、好きな文言を入力します。
(今回はtxtファイルに「sample.txtを表示します。」という文言を入力しています)
マシン上のテキストファイルを開く
<?php
$file = fopen( "c:¥¥template¥¥sample.txt", "r" );
fpassthru( $file );
?>
上記スクリプトでは、「fopen( "c:¥¥template¥¥sample.txt", "r" );」で指定したファイルを読込み専用で開き、「fpassthru( $file );」でブラウザに出力しています。また、ファイルがオープンに成功すると、「※ファイルハンドル」が返されます。
fopen()関数の引数のmodeは、ファイルを開くタイプを指定します。
実行結果
sample.txtを表示します。※ファイルハンドルとは・・・
ファイルに関する命令の時、どのファイルに対して実行するか指示をするために、実ファイル名に対して処理用の名前(ファイルハンドル)を付け、それ以降ではそのファイルハンドル名に対して処理を指示します。これにより、実ファイルが変更になっても修正個所が少しで済みます。
fopen()関数の引数のモード
| モード | 説明 |
|---|---|
| a | 追記専用で開く(書き込みは末尾行から) |
| a+ | 追記および読み込みができる(書き込みは末尾から) |
| r | 読み込み専用で開く |
| r+ | 読み込みおよび書き込みができる(書き込みは先頭行から) |
| w | 書き込み専用で開く |
| w+ | 読み込みおよび書き込みができる(現在のファイルの内容はすべて消される) |
| x | 書き込みのみで開く。※ファイルポインタをファイルの先頭に置き、ファイルがすでに存在する場にはfopen()は失敗し、E_WARNINGレベルのエラーを発行する。なお、ファイルが存在しない場合には新規作成を試みる。 |
| x+ | 書き込みおよび読み込みで開く。※ファイルポインタをファイルの先頭に置き、ファイルがすでに存在する場にはfopen()は失敗し、E_WARNINGレベルのエラーを発行する。 |
※ファイルポインタとは・・・
ファイルの中で読み込みや書き込みを行う位置を表します。ファイルポイントが先頭で読み込みを開始すれば、ファイルの先頭から読み込みを行うことになります。先頭から書き込みを行うということは、既にファイルに何か書いてあっても、既存の内容を破棄してファイルの先頭から書き込みを行うことを意味します。また、ファイルポイントが最後とは、既存の内容の最後に追加として書き込みを行うことを意味します。
開いたファイルに対する操作を終えたら、fclose()関数を使ってファイルを閉じます。引数には、fopen()関数で取得したファイルハンドルを渡します。
fclose( filepointer );
ファイルを閉じる
<?php
$file = fopen( "c:¥¥template¥¥sample.txt", "r" );
fclose( $file );
?>
上記スクリプトに成功した場合ファイルが閉じられるので、ブラウザには何も出力されません。
fpassthru()関数は、fopen()関数で開いたファイルの中身をそのまま出力する関数です。この関数で表示されたときには、fclose()関数を実行しなくても、ファイルは自動的に閉じられます。
fpassthru( filepointer );
開かれたテキストファイルを出力する
<?php
$file = fopen( "c:¥¥template¥¥close.txt", "r" );
fpassthru( $file );
?>
実行結果
close.txtは、自動的に閉じられます。ファイルの内容を一度に全て読み込むには、file()関数、およびfile_get_contents()関数を使います。file()関数は、読み込んだファイルの各行のデータを配列に格納して返します。一方、file_get_contents()関数は、読み込んだファイルの各行のデータを文字列に格納して返します。
実際に、ローカルディスク(C:)直下のtemplateディレクトリに「test.txt」を作成し、file()関数、file_get_contents()関数を使ってファイルの内容を全て読み込んでみます。
c:¥template¥test.txt
aaaaafile()関数を使って、「test.txt」を読み込む
<?php
$filename = "c:¥¥template¥¥test.txt";
$array = file( $filename );
var_dump( $array );
?>
実行結果
array(3) { [0]=> string(7) "aaaaa " [1]=> string(7) "bbbbb " [2]=> string(5) "ccccc" }file_get_contents()関数を使って、「test.txt」を読み込む
<?php
$filename = "c:¥¥template¥¥test.txt";
$str = file_get_contents( $filename );
echo $str;
?>
実行結果
aaaaa bbbbb cccccfread()関数は、ファイル全体ではなく、指定した文字数単位で読み込みます。
fread( filepointer, string,[ length ] );
今回は、「ファイル操作」の「ファイルを開く」で、ローカルディスク(C:)直下の「template」ディレクトリに作成した「sample.txt」を使用します。
ファイルの先頭から6文字を表示する
<?php
$file = fopen( "c:¥¥template¥¥sample.txt", "r" );
$str = fread( $file, 6 );
echo "$str";
fclose( $file );
?>
実行結果
sampleなお、文字はバイト単位で数えます。上記のスクリプトでは、半角英字の文字列を読み込むために、6バイトを指定しています。
fgetc()関数は、ファイルから1文字だけ読み込みます。
ファイルの先頭から1文字を表示する
<?php
$file = fopen( "c:¥¥template¥¥sample.txt", "r" );
$str = fgetc( $file );
echo "$str";
fclose( $file );
?>
実行結果
sなお、fgetc()関数も文字数をバイト単位で数えます。
fwrite()関数を使って、ファイルへの書き込みを行います。
fwrite( filepointer, string,[ length ] );
ファイルに一行追記する(1)
<?php
$file = fopen( "c:¥¥template¥¥sample.txt", "a" );
fwrite( $file, "書き込めましたか?" );
?>
実行結果(sample.txt)
sample.txtを表示します。書き込めましたか?上記のスクリプトの「$file = fopen( "c:¥¥template¥¥sample.txt", "a" );」の「a」は追記書き込みを意味しています。すでに書き込まれている「sample.txtを表示します。」の後に「書き込めましたか?」が追記されます。
なお、PHP5からは、fopen()関数でファイルをオープンせずに、ファイル名と書き込む値を指定するだけでファイルへの書き込みをが行えるfile_put_contents()関数という関数が追加されました。
ファイルに一行追記する(2)
<?php
$file = "c:¥¥template¥¥sample.txt";
$data = "大丈夫です。"
file_put_contents( $file, $data, FILE_APPEND );
?>
実行結果(sample.txt)
sample.txtを表示します。書き込めましたか?大丈夫です。file_put_contents()関数の第1引数にファイルの名前、第2引数に書き込むデータを指定します。第3引数に「FILE_APPEND」を指定すると「追記」、「LOCK_EX」を指定すると※「排他的ロック」、省略すると「上書き」になります。
※排他的ロック
排他的ロックとは、プログラムがファイルなどを独占的に利用するように設定することです。他のプログラムはそのファイルを編集できなくなり、データの不整合を防ぐことができます。
テキストファイルのアップロードを行うため、いくつか準備を行います。まずは、ファイル送信フォームを作成します。
ファイル送信フォームのソース
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>送信ファイル</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data" action="reception.php">
<p>送信ファイル:<input type="file" name="userfile" size="40"> <input type="submit" value="送信" name="up"></p>
</form>
</body>
</html>
実行結果
上記のフォームは、HTMLで作成されたページです。今回はファイルを送信するために、各属性を以下の通りに指定しました。
enctype属性
enctype属性に「multipart/form-data」を指定することで、フォームからテキストファイルや画像ファイルなどのデータを送信することができます。
action属性
フォームから送信されたデータを処理するスクリプトを指定します。今回は、「reception.php」という名前のphpファイルを使います。
method属性
method属性には「※POST」を指定します。「※GET」では、送信できるデータに上限があるため、テスト以外の時は「POST」にしてください。
※POST、GETについては、「17.フォームへの埋め込み」の「データの渡し方を指定する」で説明します。
type属性
type属性に「file」を指定すると、ファイルを参照するための「参照」ボタンが自動的に追加されます。
前章のaction属性で指定した「reception.php」ファイルを作成します。
<?php
if( !is_uploaded_file( $_FILES[ 'userfile' ][ 'tmp_name' ] ) ) {
echo "ファイルを保存できませんでした!";
exit;
} else {
copy( $_FILES[ 'userfile' ][ 'tmp_name' ], "c:¥¥template¥¥upload.txt" );
}
?>
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>アップロードファイルの保存</title>
</head>
<body>
<table border="1" width="300">
<tr>
<td width="150" align="right">ファイル名:</td>
<td width="150"><? echo $_FILES['userfile']['name']; ?></td>
</tr>
<tr>
<td width="150" align="right">ファイルサイズ:</td>
<td width="150"><? echo $_FILES['userfile']['size']; ?></td>
</tr>
<tr>
<td width="150" align="right">MIMEタイプ:</td>
<td width="150"><? echo $_FILES['userfile']['type']; ?></td>
</tr>
</table>
</body>
</html>
今回は、受信したデータを「upload.txt」というテキストファイルに保存して、先に作成したローカルディスク(C:)直下のtemplateディレクトリに配置します。
ファイル送信フォームから送信されたファイルは、マシン(サーバを利用する場合はサーバ)の一時ディレクトリに保存されます。ただし、この一時ファイルはスクリプトの実行終了後に自動的に削除されます。
実際にテキストファイルのアップロードを行ってみます。
ファイル送信フォーム
確認メッセージ
ローカルディスク(C:)直下のtemplateに保存されたファイル
確認メッセージには、受信ファイルの「ファイル名」、「サイズ」、「※MIMEタイプ」を表示しています。これらの値は変数を指定するだけで取得できます。
| 取得値 | 変数名 |
|---|---|
| ファイル名 | $textfile_name |
| サイズ | $textfile_size |
| MIMEタイプ | $textfile_type |
※MIMEタイプとは・・・
Webの世界では拡張子という概念と、もうひとつ「MIMEタイプ」という概念があります。MIMEタイプとは「タイプ名/サブタイプ名」の形式の文字列で、WEBサーバーとWEBブラウザの間はこのMIMEタイプを用いてデータの形式を指定しています。
MIMEタイプ一覧
| ファイル形式 | 一般的な拡張子 | MIMEタイプ |
|---|---|---|
| テキスト | .txt | text/plain |
| HTML文書 | .htm .html | text/html |
| XML文書 | .xml | text/xml |
| JavaScript | .js | text/javascript |
| CSS | .css | text/css |
| GIF画像 | .gif | image/gif |
| JPEG画像 | .jpg .jpeg | image/jpeg |
| Word文書 | .doc | application/msword |
| PDF文書 | application/pdf |
CSVとは、Comma Separated Value(カンマで区切られた値)の頭文字をとったものです。つまり、CSVファイルとは、値(数値やテキスト等)をカンマで区切って書いたテキストファイルのことを指しています。
CSVファイルをダブルクリックすると、自動的に表計算ソフト(Excel等)が起動し、カンマは見えず、表計算ソフト(Excel等)のデータと見た目は変わりありません。また、CSVファイルはテキストファイルなので、PCの機種の違いやアプリケーションの違いが(ほとんど)ありません。
このことにより、異なるアプリケーション間でデータを受け渡しすることが可能になります。
アップロードされたCSVファイルを利用するためには、カンマで区切られたそれぞれのデータを切り離して取得する必要があります。
PHPの関数の中には、いとも簡単にCSVファイルをそのままデータとして活用することができる関数が用意されています。
それではまず、ファイル送信フォームを作成します。
ここで使用するファイル送信フォームは、前節の「テキストファイルのアップロード」で使用したフォームの実行対象スクリプトを、「reception.php」から「address.php」に変更したHTMLのページです。
ファイル送信フォームのソース
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>送信ファイル</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data" action="address.php">
<p>送信ファイル:<input type="file" name="userfile" size="40"> <input type="submit" value="送信" name="up"></p>
</form>
</body>
</html>
送信対象のCSVファイルを作成します。今回は、作成したCSVファイル「address.csv」を、ローカルディスク(C:)直下のtemplateディレクトリに配置します。
送信対象のCSVファイル「address.csv」
山田太郎,男,166-0003,東京都杉並区高円寺南1-111-11前章のaction属性で指定した「address.php」ファイルを作成します。
CSVファイルを処理するスクリプト「address.php」
<?php
$handle = fopen( $_FILES[ 'userfile' ][ 'tmp_name' ], "r" );
while( $data = fgetcsv( $handle, 1000, "," ) ) {
$name = $data[0];
$sex = $data[1];
$postcode = $data[2];
$address = $data[3];
echo "名前:$name<br>¥n";
echo "性別:$sex<br>¥n";
echo "郵便番号:$postcode<br>¥n";
echo "住所:$address<br>¥n";
echo "-----------------------------------------<br>¥n";
}
fclose( $handle );
?>
実行結果
名前:山田太郎上記スクリプトのfgetcsv()関数で取得したデータをカンマで切り離し、その結果を配列$dataに格納します。後は配列に格納されたデータを取り出せば、CSVファイル経由でアップロードされたデータを自由に使うことができます。
fgetcsv( resource handle [, int length [, string delimiter [, string enclosure]]] );
説明
handle
fopen()、popen()、fsockopen()で正常にオープンされたファイルへのファイルポインタである必要があります。
length
行末文字を考慮して、CSVファイルにある最も長い行よりも大きい必要があります。
delimiter
フィールドの※デリミタ(1文字のみ)を設定します。デフォルトは「カンマ」です。
※デリミタとは・・・
「カンマ」、「スペース」、「タブ」など、データをテキストファイル形式で記録する際に、(項目フィールド)を区切る記号として使用される特殊な文字のことです。区切り文字ともいいます。
enclosure
フィールド囲い子文字(1文字のみ)を設定します。デフォルトは「"」ダブルクォーテーションマークです。
PHPでは、ファイル操作を組み合わせて、サーバでCSVファイルを生成することができます。
CSVファイルを生成してダウンロードするソース
<?php
$file_name = "date.csv";
$fp = fopen( $file_name, "w" );
$theme = "¥"氏名¥", ¥"性別¥", ¥"年齢¥", ¥"血液型¥", ¥"郵便番号¥", ¥"住所¥"¥n";
fputs( $fp, $theme );
$contents = "¥"" . "山田 太郎" . "¥", ¥"" . "男" . "¥", ¥"" . "40" . "¥", ¥"" . "B" . "¥", ¥"" . "166-0003" . "¥", ¥"" . "東京都杉並区高円寺南1-111-11" . "¥"¥n";
fputs( $fp, $contents );
fclose( $fp );
?>
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>CSVファイルのダウンロード</title>
</head>
<body>
<a href="date.csv">ダウンロードできます!</a>
</body>
</html>
生成されたCSVファイルへのリンク
リンクをクリックするとダイアログが表示
上記のスクリプトでは、「$file_name = "date.csv";」で生成するファイルを指定して、「$fp = fopen( $file_name, "w" );」で書き込み専用でファイルを開きます。続いて、変数$themeに、CSVファイルを開いた時の見出しを、カンマ区切りで指定します。
そして、fputs()関数で変数$themeに指定された文字列を、作成したファイルdate.csvに書き込みます。その後のデータについても、同様にファイルへ書き込み、fclose()関数で生成したファイルを閉じます。
生成したCSVファイルへのリンクを指定すれば、ダウンロードができるようになります。
fputs( filepointer, string,[ length ] );
fputs()関数はfwrite()関数の別名で、すべての面で同一です。lengthパラメータはオプションであり、指定されない場合、文字列全体が書かれることに注意して下さい。
mkdir()関数を使って、新しくディレクトリを作成することができます。
新規にディレクトリを作成する
<?php
$dir = "c:\\template\\sample";
$dirCheck = mkdir( $dir, 0777 );
if( $dirCheck ) {
echo "ディレクトリが作成されました";
} else {
echo "ディレクトリの作成に失敗しました";
}
?>
実行結果
ディレクトリが作成されました上記のスクリプトでは、本章で作成したローカルディスク(C:)直下の「template」ディレクトリ内に、「sample」ディレクトリを新規に作成しています。実際に作成できているかどうかは「template」ディレクトリ内を確認してみてください。
mkdir()関数の第1引数にはディレクトリを作成するパス、およびディレクトリ名を指定します。パスは相対パスでも絶対パスでも指定することができます。第2引数を指定すると、作成するディレクトリにアクセス権を設定することもできます。アクセス権は、先頭に「0」をつけた8進数3桁で指定します。3桁の1桁目は「所有者」、2桁目は「所有グループ」、3桁目は「その他」のアクセス権を表します。
上記のスクリプトの「0777」は、すべてに「読み込み」「書き込み」「実行」を許可している指定です。第2引数を省略した場合は、デフォルトで「0777」になります。
アクセス権一覧
| 値 | アクセス権 |
|---|---|
| 0 | なし |
| 1 | 実行 |
| 2 | 書き込み |
| 3 | 書き込み、実行 |
| 4 | 読み込み |
| 5 | 読み込み、実行 |
| 6 | 読み込み、書き込み |
| 7 | 読み込み、書き込み、実行 |
また、mkdir()関数を使って、複数のディレクトリを作成することも可能です。
複数のディレクトリを作成する
<?php
$dir = "c:\\template\\sample2\\sample3";
$dirCheck = mkdir( $dir, 0777, true );
if( $dirCheck ) {
echo "ディレクトリが作成されました";
} else {
echo "ディレクトリの作成に失敗しました";
}
?>
実行結果
ディレクトリが作成されました上記のスクリプトでは、本章で作成したローカルディスク(C:)直下の「template」ディレクトリ内に、「sample2」ディレクトリを新規に作成し、さらにその作成したディレクトリの中に「sample3」ディレクトリも新規に作成しています。実際に作成できているかどうかは「template」ディレクトリ内を確認してみてください。
第3引数に「TRUE」を指定することで、指定パスに存在しないディレクトリが全て作成されます。「TRUE」を指定しなかった場合は、「Warning: mkdir() [function.mkdir]: No such file or directory in ・・・」のような警告メッセージが表示されます。
rmdir()関数を使って、ディレクトリを削除することができます。
ディレクトリを削除する(1)
<?php
$dir = "c:\\template\\sample";
$dirCheck = rmdir( $dir );
if( $dirCheck ) {
echo "ディレクトリが削除されました";
} else {
echo "ディレクトリの削除に失敗しました";
}
?>
実行結果
ディレクトリが削除されました上記のスクリプトでは、(C:)直下の「template」ディレクトリ内の、「sample」ディレクトリを削除しています。実際に削除できているかどうかは「template」ディレクトリ内を確認してみてください。
ディレクトリを削除する場合は、削除対象のディレクトリ内には何も無いことが前提となります。もし、ディレクトリ内にファイルやディレクトリが残っている場合は警告メッセージが表示されます。
file_exists()関数を使って、指定したファイルが存在するかどうかを調べることができます。
ファイルの存在をチェックする
<?php
$dir = "c:¥¥template¥¥sample2.txt";
if ( file_exists( $dir ) ) {
echo "指定されたファイルは存在します";
} else {
echo "指定されたファイルは存在しません";
}
?>
上記のスクリプトでは、ローカルディスク(C:)直下の「template」ディレクトリに「sample2.txt」ファイルが存在するかどうか調べています。
上記スクリプトで「sample.txt」ファイルを指定すると、指定したファイルの存在を確認することができ、実行結果は「指定されたファイルは存在します」となります。
実行結果
指定されたファイルは存在しませんfileatime()関数を使って、対象ファイルへのアクセス日時を取得することができます。
<?php
$ftime = fileatime( "c:\\template\\sample.txt" );
echo "最終アクセス日時:", date( "Y/m/d H:i:s", $ftime );
?>
上記のスクリプトでは、fileatime()関数を使って、ローカルディスク(C:)直下の「template」ディレクトリの「sample.txt」ファイルの最終アクセス日時を取得しています。
fileatime()関数を使って取得できる時間は、万国標準時 (UCT) 「1970年1月1日 0時0分0秒」からの経過時間を秒単位で表した数値になります。
filemtime()関数を使って、対象ファイルの更新日時を取得することができます。
<?php
$ftime = filemtime( "c:\\template\\sample.txt" );
echo "最終更新日時:", date( "Y/m/d H:i:s", $ftime );
?>
上記のスクリプトでは、filemtime()関数を使って、ローカルディスク(C:)直下の「template」ディレクトリの「sample.txt」ファイルの最終更新日時を取得しています。
filemtime()関数を使って取得できる時間は、万国標準時 (UCT) 「1970年1月1日 0時0分0秒」からの経過時間を秒単位で表した数値になります。
ファイル関数には、上記以外にも様々なものがあります。
その他のファイル関数一覧
| 関数名 | 機能 |
|---|---|
| is_readable | 指定したファイルが、読み込み可能か確認する |
| is_writable | 指定したファイルが、書き込み可能か確認する |
| is_executable | 指定したファイルが、実行可能か確認する |
| chgrp | ファイルのグループを変更する |
| chmod | ファイルのモードを変更する |
| chown | ファイルの所有者を変更する |
| fileatime | ファイルの最終アクセス数を取得する |
| filegroup | ファイルのグループを取得する |
| filemtime | ファイルの更新時刻を取得する |
| fileowner | ファイルの所有者を取得する |
| fileperms | ファイルの許可属性を取得する |
| filesize | ファイルのサイズを取得する |
| filetype | ファイルのタイプを取得する |
| move_uploaded_file | 新しい位置にアップロードされたファイルを移動する |
| realpath | 絶対パス名を返す |
| rename | ファイルをリネームする |
| tempnam | ユニークなファイル名を生成する |
| tmpfile | テンポラリファイルを作成する |
| touch | ファイルの最終更新日をセットする |
| unlink | ファイルを削除する |