LoginSignup
27
33

More than 5 years have passed since last update.

Ajaxで画像ファイルをアップロードする方法 ※ファイル数制限、削除、サムネイル表示 (PHP)

Last updated at Posted at 2016-05-31

やりたいこと

  • Ajaxを用いた画像ファイルのアップロード
    • ファイル選択と同時にAjaxでファイルを保存
    • ファイル名は日付に変更して保存
    • サムネイルの表示
    • 画像ファイル数の制限(最大3つ)
    • 画像削除ボタンの設置

*セキュリティ対策の部分は実装出来ておりません。
*使用している画像はフリー素材です。
starwars-icon

スクリーンショット 2016-05-31 11.39.00.png

3つ目の画像が選択されるとinputが非表示になる。
(1つ画像が削除されると再度表示される)
スクリーンショット 2016-05-31 11.39.18.png

index.php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="js/jquery-1.12.4.min.js" charset="utf-8"></script>
    <style media="screen">
      li{
        list-style: none;
      }
    </style>
    <script type="text/javascript">
    $(function(){
      var $fileList = $('#file_list');
      $fileList
        //削除がクリックされた場合の処理
        .on('click.deleteFile', '.delete_btn', function(){
          var $li = $(this).closest('.each_file');
          $li.remove();
          //inputタグ数が4つ未満になった場合に再度表示させる処理
          var $fileListLI = $('#file_list li input[name=img_file]');
          var inputFileNum = $fileListLI.length;
          //最後のinputタグを表示する処理
          var lastInputFile = $fileListLI.eq(-1);
          if (inputFileNum < 4){
            $(lastInputFile).show();
          }
          return false;
        })

      $fileList
        //inputタグに画像が追加された場合の処理
        .on('change.inputFile', '.input_file', function(e){
          var $input = $(this),
              $li    = $input.closest('.each_file'),
              $newLi = $li.clone();
              $fileList.append($newLi);
          //サムネイル画像を表示する処理
          var file = e.target.files[0],
              fileName = file.name;
        //FileReaderオブジェクトの生成
              reader = new FileReader();
              reader.readAsDataURL(file);

              reader.onloadend = function(){
                var fileReader = this;
                if(fileReader.result){
                  var thumb = '<div class = "thumbnail"><img src = "' + fileReader.result + '" width = "150px" style = "max-width: 150px;">' + fileName + '<button class = "delete_btn">削除</button></div>';
                  $li.append(thumb);
                }
                return this;
              };
          $input.hide();

          //画像が3つになった場合にinputタグを非表示にする処理
          //上にも同じコードがあるのでまとめた方がいいのですが...
          var $fileListLI = $('#file_list li input[name=img_file]');
          var inputFileNum = $fileListLI.length;
          var lastInputFile = $fileListLI.eq(-1);
          if (inputFileNum == 4){
            $(lastInputFile).hide();
          }

          //Ajaxで飛ばすdata(FromDataオブジェクト)を生成する処理
          var fd = new FormData();
     //最後から2番目のinputタグを拾う処理
     //画像が選択されるinputタグは必ず最後から2番目
          var targetFile = $fileListLI.eq(-2);
     //1画像毎のUPなので[0]、複数である場合は[1][2]...
          fd.append( "file", $(targetFile).prop("files")[0]);

          $.ajax({
            url: 'file_api.php',
            type: 'post',
            dataType: 'json',
            data: fd,
            processData: false,
            contentType: false
          })
          .done(function(res){
            console.log(res);
          })
          .fail(function(jqXHR, statusText, errorThrown){
            console.log(errorThrown);
          });
          return this;
        });
    });
    </script>
    <title>Ajax Sample</title>
  </head>
  <body>
    <h1>Ajax sample</h1>
    <form action="upload.php" method="post" enctype="multipart/form-data">
      <ul id="file_list">
        <li class="each_file">
          <input type="file" class="input_file" name="img_file" value="" accept="image/*">
        </li>
      </ul>
      <input type="submit" id="submit_btn" value="画像アップロード">
    </form>
  </body>
</html>

file_api.php
<?php
  date_default_timezone_set('Asia/Tokyo');
  header("Content-type: text/json; charset=UTF-8");
  //直接のページ遷移を阻止
  $request = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
  if($request !== 'xmlhttprequest') exit;
  //画像の拡張子を取得
  $file_ext = pathinfo($_FILES['file']['name']);
  $time = date("YmdHis");
  //ファイル名を日付に変更
  $file_name = $time.".".$file_ext[extension];
  //保存先のパス
 //index.php file_api.phpと同層にupload_fileディレクトリが存在
  $file_path = "upload_file/".$file_name;

  $tmp_file = $_FILES['file']['tmp_name'];
  $result = move_uploaded_file($tmp_file, $file_path);
  //保存出来たらファイル名をjsonで返す
  if($result){
    echo json_encode($file_name);
  }
?>

大変参考にさせていただきました。
http://qiita.com/mpyw/items/939964377766a54d4682
https://app.codegrid.net/entry/file-api-filereader-api
http://libro.tuyano.com/index3?id=384001&page=3

27
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
33