(147) 画像ファイルをアップロードの2パターン

投稿者: | 2023年12月21日

102 views

1. やりたいこと

Webブラウザからサーバー側にファイルをアップロードしたい。

以下の2パターンで実現したい。

パターン1: 一度のボタン押下で、選択画像をサーバーにアップロード完了させる。
「画像選択画面」→「画像投稿画面」

パターン2:[送信]、[投稿確認]の二度のボタン押下で、選択画像をサーバーにアップロード完了させる。
「画像選択画面」→「画像確認画面」→「画像投稿画面」

2. やってみる:パターン1「画像選択画面」→「画像投稿画面」

1) プログラムソースコード

(1) 画像選択画面:index.html

<!DOCTYPE html>
<html>
<head>
  <title>Blog No.147-1 画像選択画面</title>
</head>
<body>
  <form action="upload.php" method="post" enctype="multipart/form-data">
    画像を選択してください。
    <input type="file" name="myimg"><br />
    <input type="submit" value="アップロード">
  </form>
</body>
</html>

(2) 画像投稿画面:upload.php

<?php
require_once('common.php');
$html_contents = '';
if($_SERVER['REQUEST_METHOD'] == 'POST') {
  // 画像ファイル指定ありの場合
  if(isset($_FILES['myimg']) === true){
    // アップロードファイルは画像ファイル?
    if(true === isValidImageFile($_FILES['myimg'])){
      // 画像保存先のディレクトリパス文字列を作成 {top-url}/upimg
      $target_dir = './upimg/';
      // 画像保存先のファイルパス文字列を作成
      $target_file = $target_dir.basename($_FILES['myimg']['name']);
      // アップロードされたファイルを、作成したファイルパスに移動
      move_uploaded_file($_FILES['myimg']['tmp_name'], $target_file);
      // アップロード画像の表示用のHTMLタグを作成
      $html_contents = '<img src="'.$target_file.'" />';
    }
  }
}
?>
<!DOCTYPE html>
<html>
<head>
  <title>Blog No.147-1 画像投稿画面</title>
</head>
<body>
<?php echo $html_contents; ?>
</body>
</html>

(4) 共通関数群:common.php

////////////////////////////////////////////////////////////////////////////////
// アップロードされたファイルが、画像ファイルであることを確認する。
// $sgv_file : $_FILES{'xxxxx'] を入力する。
function isValidImageFile( $sgv_file ){
  $ret = false;
  //------------------------------------------------------------------------
  // check 1 : 拡張子を検査
  $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'tiff', 'tif'];
  $ext = pathinfo($sgv_file['name'], PATHINFO_EXTENSION);   // ファイル名文字列から拡張子を取得
  if(false === in_array(strtolower($ext), $allowedExts)){   // 受け入れ可能な拡張子?
    goto tagEND;
  }
  //------------------------------------------------------------------------
  // check 2 : MIMEタイプを検査
  $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/tiff'];
  $fileMimeType = mime_content_type($sgv_file['tmp_name']); // UploadされたファイルのMIMEタイプを取得
  if(false === in_array($fileMimeType, $allowedMimeTypes)){ // 受け入れ可能なMIMEタイプ?
    goto tagEND;
  }
  //------------------------------------------------------------------------
  // check 3 : 画像ファイルヘッダを検査
  if (false === getimagesize($sgv_file['tmp_name'])) {
    goto tagEND;
  }
  //------------------------------------------------------------------------
  // 画像ファイルであると確認した。
  $ret = true;

tagEND:
  return $ret;
}

3. やってみる:パターン2「画像選択画面」→「画像確認画面」→「画像投稿画面」

1) 処理の流れ

2) プログラムソースコード

(1) 画像選択画面:index.html

<!DOCTYPE html>
<html>
<head>
  <title>Blog No.147-2 画像選択画面</title>
</head>
<body>
  <form action="confirm.php" method="post" enctype="multipart/form-data">
    画像を選択してください。
    <input type="file" name="myimg"><br />
    <input type="submit" value="アップロード">
  </form>
</body>
</html>

(2) 画像確認画面:confirm.php

<?php
session_start();
require_once('common.php');
$html_confirm = '';
if($_SERVER['REQUEST_METHOD'] == 'POST') {
  // 画像ファイル指定ありの場合
  if(isset($_FILES['myimg']) === true){
    // アップロードファイルは画像ファイル?
    if(true === isValidImageFile($_FILES['myimg'])){
      // 一時画像保存先のディレクトリパス文字列を作成 ./tmpimg
      $target_dir = './tmpimg/';
      // 画像保存先のファイルパス文字列を作成
      $fnameNew = makeUniqueFileName($_FILES['myimg']['name']);
      $target_file = $target_dir.$fnameNew;
      // アップロードされたファイルを、作成したファイルパスに移動
      move_uploaded_file($_FILES['myimg']['tmp_name'], $target_file);
      // 一時ファイルのパス文字列をセッションに保存
      $_SESSION['temp_uploaded_img'] = $target_file;
      // アップロード画像の表示用のHTMLタグを作成
$html_contents = <<< EOM
<form action="upload.php" method="post">
  <img src="{$target_file}" />
  <input type="submit" value="この画像を投稿します。">
</form>
EOM;
    }
  }
}
?>
<!DOCTYPE html>
<html>
<head>
  <title>Blog No.147-2 画像確認画面</title>
</head>
<body>
<?php echo html_confirm; ?>
</body>
</html>

(3) 画像投稿画面:upload.php

<?php
session_start();
require_once('common.php');
$html_imgshow = '';

// セッションから一時ファイルのパス文字列を取得
$temp_uploaded_img = $_SESSION['temp_uploaded_img'];
// ファイルが存在しない? → 不正操作と判断する。
if(file_exists($temp_uploaded_img) === false){
  echo '不正な操作です。'; exit();
}

// ファイルの拡張子を取得
$ext = pathinfo($temp_uploaded_img, PATHINFO_EXTENSION);
// ファイルを移動後のファイル名を作成
$fnameNew = makeImgFileNameBodyWithId(time(), $ext);

// 一時ファイルを正式に画像保存フォルダに移動する。
$target_file = './upimg/'.$fnameNew;
rename($temp_uploaded_img, $target_file);

// ごみ処理(1時間以上前に作られた一時ファイルを削除)
removeOldFiles('./tmpimg/');

// 投稿画像の表示用のHTMLタグを作成
$html_imgshow = <<< EOM
<img src="{$target_file}"><br />
この画像の投稿が完了しました!
EOM;
?>
<!DOCTYPE html>
<html>
<head>
  <title>Blog No.147-2 画像投稿画面</title>
</head>
<body>
<?php echo $html_imgshow; ?>
</body>
</html>

(4) 共通関数群:common.php

<?php
////////////////////////////////////////////////////////////////////////////////
// アップロードされたファイルが、画像ファイルであることを確認する。
// $sgv_file : $_FILES{'xxxxx'] を入力する。
function isValidImageFile( $sgv_file ){
  $ret = false;

  // check 1 : 拡張子を検査
  $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'tiff', 'tif'];
  $ext = pathinfo($sgv_file['name'], PATHINFO_EXTENSION);   // ファイル名文字列から拡張子を取得
  if(false === in_array(strtolower($ext), $allowedExts)){   // 受け入れ可能な拡張子?
    goto tagEND;
  }
  // check 2 : MIMEタイプを検査
  $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/tiff'];
  $fileMimeType = mime_content_type($sgv_file['tmp_name']); // UploadされたファイルのMIMEタイプを取得
  if(false === in_array($fileMimeType, $allowedMimeTypes)){ // 受け入れ可能なMIMEタイプ?
    goto tagEND;
  }
  // check 3 : 画像ファイルヘッダを検査
  if (false === getimagesize($sgv_file['tmp_name'])) {
    goto tagEND;
  }
  // 画像ファイルであると確認した。
  $ret = true;

tagEND:
  return $ret;
}

// セッションIDと時刻からユニークなファイル名を作成する。
function makeUniqueFileName( $fname ){
  $ssid = session_id();
  $time = time();
  return $ssid.$time.basename($fname);
}

// 指定IDでファイル名文字列を作成する。
// $ext : 拡張子文字列 例) jpg png gif (※.(dot)無しで指定すること)
function makeImgFileNameBodyWithId( $id, $ext='' ){
  if($ext != ''){
    $ext = '.'.$ext;
  }
  return 'img_uploaded_'.$id.$ext;
}

// 指定IDに対応する画像ファイルを探す。
function findImgFileNakeById( $id, $withPath=false ){
  $ret = '';
  $dir = './upimg';
  $ptn = '/img_uploaded_'.$id.'*';
  // 指定ディレクトリ内で、指定パターンにマッチするファイルを探す。
  $ary_files = glob($dir.$ptn);
  if(is_array($ary_files) === true){        // ファイルが存在した?
    if($withPath === true){
      $ret = $ary_files[0];
    }else{
      $ret = basename($ary_files[0]);
    }
  }
  return $ret;
}

// 古い一時保存ファイルを削除する。
// $lifetime_sec : 生存期間[秒] (作成時刻から指定時間だけ経過したファイルを削除する。)
function removeOldFiles( $dir, $lifetime_sec=3600 ){
  // 指定されたフォルダ内の全ファイルを取得する。
  $ary_files = glob($dir.'/*');
  if(is_array($ary_files) === true){        // ファイルが存在した?
    foreach($ary_files as $file){           // 1ファイルずつ処理する。
      $timemake  = filemtime($file);        // ファイルの作成時刻を取得
      $timelimit = time() - $lifetime_sec;  // ファイルの生存期限を算出
      if($timemake < $timelimit){
        unlink($file);                      // ファイルを削除
      }
    }
  }
}
?>

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)