質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

630閲覧

PHPMailerの添付ファイルの処理について テンポラリーファイル名とファイル名の違いを使った処理?

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/06/11 05:44

PHPMAILERの勉強をしています。
フォームからアップロードされた
添付のファイルを処理するこの2行が理解できないので、質問させて頂きました。

PHP

1 $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'])); 2 if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {

1行目
アップロードされたファイル名から
テンポラリーの場所に、HASH処理した新しいファイル名でファイルを作成
$uploadfileはそのファイルのパスを文字列で返す

2行目
アップロードされたファイルのテンポラリー名から、1行目で作った場所に動かす。

このような処理をする理由はなぜでしょうか?
move_uploaded_fileがうまくいかない時はどのような時でしょうか?
ファイル名とテンポラリーファイル名って名前が違うだけで同じだから、上書きできる、ということでしょうか?

ご教示いただけましたら幸いです。

ありがとうございます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

$_FILES['userfile']['name'] にはユーザーが任意につけたファイル名が代入されていますね。(ここについて説明は流石に不要ですよね…)例えば、「参考資料.xlsx」のようになっています。ここでこのファイル名をそのまま保存するファイル名に使うというサンプルコードもたまに見かけますが、バッドノウハウです。

というのも、クライアントOSがWINDOWSの場合、サーバーOSがLinuxの場合などでは文字コードが異なるため、Linuxでファイル指定できず、ファイルを取り出せないという事態が起こりうるのです。なので、hash('sha256',...) を利用することで、ファイル名を半角英数字に変換してしまおうというのです。

ただし!提示されたコードには問題があります。

たとえば、ほぼ同時にAさんが「参考資料.xlsx」というファイルをアップロードします。たまたま同じ時間にBさんが「参考資料.xlsx」というファイルをアップロードします。このときどうなるでしょう。

hash('sha256', $_FILES['userfile']['name']) で生成されるファイル名は、いつでも同じものになります。ファイルの保存先も同位置のディレクトリなので、一瞬でも後に処理されたファイルの内容で上書きされてしまいます。

tempnam() を使っているので、上書きはされませんでしたね。となると、hash('sha256', $_FILES['userfile']['name'])を使うことは無意味。tempnam()だけ使えば十分。

Aさん、もしくはBさんはアップロードしたファイルでない別物のファイルをアップロードしたことになります。
この辺りの仕様はもう一度見直しましょう。

投稿2018/06/11 06:02

編集2018/06/11 06:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/11 08:44

ありがとうございます。同時にアップロードするとそのような怖い事態になるんですね! もしご時間ございましたら、2行目についても教えていただけますでしょうか・・・ if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { どうしてわざわざこれをしているのかわかりません。 サイズの大きさをフォームで指定しているので、それをこの2行目でチェックしているのでしょうか? <input type="hidden" name="MAX_FILE_SIZE" value="100000">
退会済みユーザー

退会済みユーザー

2018/06/11 08:52

ごめんなさい。関数が何をするかは読んで理解できたのですが、なぜそうするのは読んでも分からなかったので質問させていただきました。テンポラリーファイル名を、処理した名前に書き換えるためという理解でいいでしょうか?
退会済みユーザー

退会済みユーザー

2018/06/11 08:59 編集

名前を書き換えることが目的なら、move_uploaded_fileという関数名は不適当ではありませんか?アップロードしたファイルを移動するのが目的だから、そういう名前になっているわけだし。 アップロードされたファイルは、どこのディレクトリに保存されるかはご存知ですか?
退会済みユーザー

退会済みユーザー

2018/06/12 06:34

返信ありがとうございます。 $_FILES['userfile']['tmp_name']はC:\xampp\tmp\でしたが、 sys_get_temp_dir()は、ローカルでした。C:\Users\name\AppData\Local\Temp ファイルを移動させるのは、なぜですか? <?php if(isset($_POST['submit'])){ var_dump($_FILES['userfile']['tmp_name']); echo sys_get_temp_dir(); }
退会済みユーザー

退会済みユーザー

2018/06/12 06:36

Linuxサーバーなどでは、/tmp 以下のファイルがアップロードされます。 /tmp はあらゆるプログラムから書き込みされるディレクトリだし、定期的に削除されます。つまりここに置いたままではファイルは削除されるので移動しなければなりません。
退会済みユーザー

退会済みユーザー

2018/06/12 10:27

ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問