woshidan's blog

そんなことよりコードにダイブ。

PHPでクライアントからサーバへファイルをアップロードする

ユーザー用の自己紹介画像とかをアップロードできるようにしたいよね、ということでPHPでファイルをアップロードする方法について暗中模索してました。

 

参考にしたのは、

http://www.php-labo.net/tutorial/php/upload.html#form

http://www.php.net/manual/ja/function.is-uploaded-file.php

http://www.php.net/manual/ja/function.move-uploaded-file.php

です。

 

まず、html側。

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>アップロードしたい</title>

</head>

<body>

<form action="upload.php" method="post" enctype="multipart/form-data">

ファイル:

<input type="file" name="upfile[]" size="30" id="file"><br>

<input type="submit" value="アップロード" />

</form>

</body>

</html>

 

ポイントは太字部分。

  • post方式で、enctype="multipart/form-data"を設定。
  • input typeにfileを指定。

すると、ファイルを参照ボタンがフォームに出てきます。

ついで、受け取ったファイルをチェックして適切な場所へ送るupload.php

表示がうまく行かないので混ざっていてしまってすみません。

 

    //var_dump($_FILES);
	//'file'がHTTP POSTによりアップロードされているか?
	//いなければスクリプト通りに動作していない
	if (is_uploaded_file( ( $_FILES['upfile']['tmp_name'][0]) ) ){
		//HTTP POSTによるファイルのアップロードに成功

		//phpと同じディレクトリにアップロードされているので、所定のフォルダに移す

		//アップロードしたファイルの保存先のディレクトリ
		//相対ディレクトリでも絶対ディレクトリでも。相対の方が楽ですが。
		$uploaddir = 'picture/user/';
		//アップロードしたファイルの保存名。デイレクトリ部分を含む
		$uploadfile = $uploaddir . basename($_FILES['upfile']['name'][0]);

		if(move_uploaded_file($_FILES['upfile']['tmp_name'][0], $uploadfile)){
			//move_uploaded_file($uploadfile, $uploaddir)
			echo "アップロード成功です";
		}else{
			//何らかの理由でディレクトリに移動できない場合
			echo "ディレクトリ名:" . $uploaddir . "をいまいちど確認してください
"; echo "現在のディレクトリは" . getcwd(); } } else{ echo "おそらく何らかの攻撃を受けました"; echo "ファイル名" . $_FILES['upfile']['tmp_name'][0] . "."; } 

今度のポイントはコメントにも書いているのですが、

  • is_upload_file()でファイルがHTTP POSTから送られたものかチェックする
  • そのままだと、ファイルはphpと同じフォルダにアップロードされているので、move_upload_file()で保存したいフォルダへ移動させる

です。セキュリティ対策も混じってます。

 

いくつか、引数とかでひっかかったので、下記メモです。

 

ファイル名がArray

参考にしたhttp://www.php.net/manual/ja/function.is-uploaded-file.phpだと引数として、

$_FILES['userfile']['tmp_name']

のように書いてありますが、var_dumpで$_FILESを出力させると、

["tmp_name"]=> array(1) { [0]=> string(24) "C:\xampp\tmp\php5D68.tmp"

のようになっており、arrayオブジェクトの何番目のインデックスかを後ろに[0]でつけて指定しないと名前が出てきません

['name']と入れたらnameが出てくると単純に思っていたので少し詰まりました。

他の場面でもやりそう。。

 

move_uploaded_file()の引数

move_uploaded_file(サーバーに一時的にアップされたファイル名, アップロードした後のディレクトリを含んだファイル名)ですが、

勘違いして、

move_uploaded_file(アップロードした後のディレクトリを含んだファイル名, アップロードしたいディレクトリ名)

と入力していて、しばらくつみました。

destination = 目的地

としおってこの阿呆めがぁぁ……。