PHPにおいてPOSTメソッドでアップロードされたファイルは、アップロードの成否にかかわらず、一時ディレクトリに保存される、という話のメモ。
PHPのドキュメントによると、POSTメソッドでアップロードされたファイルは、まず一時ディレクトリに保存される。
一時保存先にはデフォルトでシステムの一時ディレクトリが使用されるが、php.ini
のupload_tmp_dir
に任意のディレクトリを指定すれば、そちらに保存される。
$ grep upload_tmp_dir /etc/php5/apache2/php.ini
;upload_tmp_dir =
その後、ファイルを移動させたり、ファイル名を変更しなかったりした場合、一時ディレクトリに保存されたファイルはリクエストの終了時に削除される。
簡単なテストプログラムを用いて、アップロード処理を検証してみた。
※以下に示すソースコードはあくまで検証を目的としたもので、セキュリティ対策等は施していないため、本番環境では使用しないこと。
以下はファイルをアップロードするためのフォーム画面のソースコードである。
<html>
<head>
<title>File upload form</title>
</head>
<body>
<form method ="post" action="upload-test.php" enctype="multipart/form-data">
<input type="file" name="userfile" />
<br />
<br />
<input type="submit" value="upload" />
</form>
</body>
</html>
以下はアップロードされたファイルを処理するためのPHPコードである。
<?php
$uploaddir = '/tmp/myuploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
$user_file_contents = file_get_contents($uploadfile);
print($uploadfile);
print(" : ");
print($user_file_contents); //print the contents of the uploaded file
print("<br />");
print("File successfully uploaded.");
print("<br />");
} else {
$tmp_file_contents = file_get_contents($_FILES['userfile']['tmp_name']);
print($_FILES['userfile']['tmp_name']);
print(" : ");
print($tmp_file_contents); //print the contents of temporary saved file
print("<br />");
print("Upload failed.");
print("<br />");
}
print("Debug info: ");
print_r($_FILES);
?>
以下は上記のコードの簡単な解説。
- アップロードされたファイルを
/tmp/myuploads/
ディレクトリに保存する。 - ファイルが
/tmp/myuploads/
ディレクトリにアップロードされた場合は、File successfully uploaded.
というメッセージを表示し、さらにアップロードされたファイルの中身を出力する。 - ファイルのアップロードに失敗した場合は、
Upload failed.
というメッセージを表示し、さらに一時ディレクトリに保存されたファイルの中身を出力する。(一時ファイル名は$_FILES['userfile']['tmp_name']
で取得できる) - また、最後に
print_r
でデバッグ情報を出力する。
以下は/tmp/myuploads/
のディレクトリ情報である。現在、ディレクトリにはファイルが存在しない。
$ ls -ld /tmp/myuploads/
drwxrwxr-x 2 www-data www-data 4096 Nov 17 14:57 /tmp/myuploads/
$ ls -l /tmp/myuploads/
total 0
test.txt
というファイルをアップロードしてみた。
$ cat test.txt
This is a test file.
ファイルが/tmp/myuploads/
にアップロードされた。またデバッグ情報より、ファイルが一時的に/tmp/phplpiRKS
として保存されていたことが分かる。
$ ls -l /tmp/myuploads/
total 4
-rw-r--r-- 1 www-data www-data 21 Nov 17 15:01 test.txt
続いてアップロードに失敗した場合の例を見てみる。
先述したPHPコードをいじって、ファイルの保存先に/tmp/dir_not_exists/
という存在しないディレクトリを指定した。
//$uploaddir = '/tmp/myuploads/';
$uploaddir = '/tmp/dir_not_exists/';
$ ls -ld /tmp/dir_not_exists/
ls: cannot access /tmp/dir_not_exists/: No such file or directory
先ほどと同様にtest.txt
をアップロードしてみたが、保存先のディレクトリが存在しないため、アップロードに失敗した。
しかし、上記の画像より、ファイルが一時的に/tmp/phpSyEZlT
として保存されていたことが分かる。
以上より、PHPにおいてPOSTメソッドでアップロードされたファイルは、アップロードの成否にかかわらず、一時ディレクトリに保存されるということが分かった。
ただし、一時ディレクトリに保存されたファイルは原則としてリクエストの終了時に削除される。