TOP > カテゴリ > PHP >

ファイルをアップロードする(複数ファイル+ドラッグ&ドロップ対応版)

ブラウザを使用してファイルをアップロードするサンプルです。複数ファイルやAjaxを使用したドラッグ&ドロップにも対応しています。サンプルではGIF/PNG/JPEGの画像ファイルの認識や各種エラーにも対応しています。言語はPHPとなります。

まずは結果から

[初期画面]

[アップロード後の画面]

ファイルを複数選択して「アップロードを実行するボタンを押す」 or 「ドラッグ&ドロップ」するとサーバーへ画像ファイルがアップロードされます。アップロードされた画像ファイルはブラウザに表示されるようにしています。

ソースコード[uploads.php]

下記がサンプルのソースコードとなります。

<?php

  $errmsg = ""; // エラーメッセージ
  define("FOLDER_UPLOAD" ,"./hoge/") ; // 保存先のフォルダ名(任意のフォルダ名にする)  
  
  if (isset($_FILES["upfile"])){
       
      // エラーの確認
      foreach ($_FILES["upfile"]["error"] as $key => $error) {
        
          // アップロード系のエラー
          switch ($error) {
              case UPLOAD_ERR_OK: // OK
                  break;
              case UPLOAD_ERR_NO_FILE:   
                  $errmsg = '<span style="font-weight:bold;color:red;">ファイルが選択されていません。</span><br />';
                  break;
              case UPLOAD_ERR_INI_SIZE:  
              case UPLOAD_ERR_FORM_SIZE: 
                  $errmsg .= '<span style="font-weight:bold;color:red;">「'.$_FILES["upfile"]["name"][$key] . 
                             '」のファイルサイズが最大値を超えています。</span><br />';
                  break;
              default:
                  $errmsg .= '<span style="font-weight:bold;color:red;">「'.$_FILES["upfile"]["name"][$key] . 
                             '」:エラーが発生しました。</span><br />';
                  break;
          }                
         
          
          if ($error === UPLOAD_ERR_OK){
            
              // 同名ファイルの確認   
              if (file_exists(FOLDER_UPLOAD .$_FILES["upfile"]["name"][$key])){            
                  $errmsg .= '<span style="font-weight:bold;color:red;">「' .$_FILES["upfile"]["name"][$key] . 
                             '」は既に存在します。</span><br />';  
              }           
              
              // ファイルのタイプの確認
              if (!( ($_FILES["upfile"]["type"][$key] === 'image/gif')  || 
                     ($_FILES["upfile"]["type"][$key] === 'image/jpeg') ||
                     ($_FILES["upfile"]["type"][$key] === 'image/png'))){
                  $errmsg .= '<span style="font-weight:bold;color:red;">「' .$_FILES["upfile"]["name"][$key] . 
                             '」は対応していない形式です。</span><br />'; 
              }
          }                              
      }  
          
      // ファイルのアップロード 
      if ($errmsg  == ""){
          foreach ($_FILES["upfile"]["error"] as $key => $value) {   
                   
              $filename  = FOLDER_UPLOAD . $_FILES["upfile"]["name"][$key];
              
              if (move_uploaded_file($_FILES['upfile']['tmp_name'][$key],$filename)){
                  chmod($filename,0644);  
              }else{
                 $errmsg .= '<span style="font-weight:bold;color:red;">ファイルのアップロードに失敗しました。</span><br />';        
              }  
              
          }       
      } 
      
      if ($errmsg  == ""){
          foreach ($_FILES["upfile"]["error"] as $key => $value) {
              $errmsg .= '<span style="font-weight:bold;">・「' . $_FILES["upfile"]["name"][$key] . '」をアップロードしました。</span><br />';  
              $errmsg .= '<img src="' . htmlspecialchars(FOLDER_UPLOAD . $_FILES["upfile"]["name"][$key]) .'" /><br />';                
          }  
      }
      
      // ドラッグ&ドロップの場合は終了
      if ($_GET["drop"] == 1){
        // 下記2行の処理はAjaxで必須
        echo $errmsg;
        exit();
      }      
  }      
?>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript"> 
<!--
 
  // XMLHttpRequestオブジェクトの生成
  function createXmlHttpRequest(){

    if(window.XMLHttpRequest){      
    
      return new XMLHttpRequest();     
      
    }else if(window.ActiveXObject){
      
      try {
          return new ActiveXObject("MSXML2.XMLHTTP.6.0"); 
      } catch (e) {
        try {
           return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        } catch (e2) {
          try {
              return new ActiveXObject("MSXML2.XMLHTTP");
          } catch (e3) {
             return null
          }
        }
      }
      
    }else {
        return null
    }
  }
  
  // サーバーへHttpリクエストの送信
  function sendHttpRequest(files){ 
        
      // XMLHttpRequestオブジェクトの生成
      var xmlhttp = createXmlHttpRequest();
      
      // イベントの設定
      xmlhttp.onreadystatechange = function() { 
        // レスポンスの処理が完了後、コールバック関数へ渡す
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
            // コールバック
            XmlHttpCallback(xmlhttp);
        }
      }       
     
      // フォームデータの生成(HTML5)
      var fd = new FormData();
      for (var i=0; i< files.length; i++) {
          fd.append("upfile[]",files[i]); 
      }      
     
      xmlhttp.open('POST', 'upload.php?drop=1', true);
       
      // サーバにHTTPリクエストを送信
      xmlhttp.send(fd);     
  }
  
  // コールバック関数(クライアント側への表示)
  function XmlHttpCallback(xmlhttp){
      var result = document.getElementById("result");
      result.innerHTML = xmlhttp.responseText;
  } 
  
  // *** アップロード用ドラッグ&ドロップ
  function onUpload_DragOver(event){ 
      // イベントのキャンセル
      event.preventDefault(); 
  } 

  function onUpload_Drop(event){  
      if (event.dataTransfer.files.length !=0){
          // まとめて送信する
          sendHttpRequest(event.dataTransfer.files);    
      }
      // イベントのキャンセル
      event.preventDefault(); 
  }     
// -->
</script>
</head>
<body>
<div id="result"><?php echo $errmsg; ?></div>
<br />
<form action="upload.php" method="post" enctype="multipart/form-data">
  <div ondragover="onUpload_DragOver(event)" ondrop="onUpload_Drop(event)" style="border:2px solid #ccc; width:300px;height:150px;">
  <input name="upfile[]" type="file" multiple="multiple" /><br />
  <br />
  <br />
  ここに画像ファイルをドラッグ&ドロップ。
  </div> 
  <br />
  <input type="submit" value="アップロードを実行する" />
</form>
</body>
</html>

サンプルの解説

HTMLではformタグにenctype="multipart/form-data"を追加する事でファイルがアップロードできるようになります。複数ファイルに対応させるにはinputタグにmultiple="multiple"を追加してname属性を複数([])にします。

ドラッグ&ドロップはdivタグにondragover、ondropイベントを設定しています。tableタグなど他のタグにイベントを設定する事が可能です。また、ドラッグ&ドロップはHTML5の新機能となります。

PHPでは$_FILESでアップロードされたデータを扱うことができます。各種エラー処理を実施してから、move_uploaded_fileでサーバーのテンポラリから任意のフォルダへファイルをコピーします。

非常にざっくりな説明ですが後はソース内のコメントから読み取ってくださいね :-)

その他のサンプル

1つのファイルだけをアップロードしたい場合は

をご覧下さい。





関連記事



公開日:2015年01月28日
記事NO:00163