htmxによるシンプルで高速なファイルアップロード

htmxによるシンプルで高速なファイルアップロード プログラミング

ユーザーが画像やドキュメントなどのファイルをサーバーにアップロードできるようにすることで、より豊かなユーザー体験を提供できます。
古くは、formタグのenctype属性を”multipart/form-data”に設定し、inputタグのtype属性を”file”にすることで、ファイルアップロードを実装していました。

しかし、この方法では、ページ全体をリロードする必要があり、ユーザーエクスペリエンスが悪化する問題がありました。
その後、JavaScriptを使ったAjaxによるファイルアップロードが主流になりました。

これにより、ページ全体をリロードすることなく、ファイルをアップロードできるようになりました。
ただし、JavaScriptによる実装は複雑で、コードの記述量も多くなりがちでした。

そこで登場したのがhtmxです。
htmxを使えば、シンプルなHTMLの属性だけでファイルアップロードを実現できます。

この記事では、htmxを使ったファイルアップロードの実装方法を詳しく解説します。

本記事の内容

  • ファイルアップロードのHTML構造
  • サーバーサイドでのファイル処理
  • アップロード成功/失敗のフィードバック
  • サンプルコード
  • まとめ

それでは、上記に沿って解説していきます。

ファイルアップロードのHTML構造

まず、ファイルアップロードのHTML構造を定義します。
ファイル選択のinputとアップロードボタンを以下のように配置します。

<form id="upload-form" hx-post="upload.php" hx-encoding="multipart/form-data" hx-target="#response">
  <input type="file" name="file">
  <button type="submit">Upload</button>
</form>
<div id="response"></div>

ormタグには、hx-post、hx-encoding、hx-targetの属性を設定します。
hx-postで指定したPHPファイルにファイルがPOSTされ、hx-targetで指定した要素にレスポンスが表示されます。

hx-encodingを”multipart/form-data”にすることで、ファイルのアップロードが可能になります。
これは、従来のformタグを用いたファイルアップロードと同様の設定と言えます。

しかし、htmxを使うことで、ページ全体をリロードすることなく、ファイルをアップロードできます。

サーバーサイドでのファイル処理

次に、PHPを使ってアップロードされたファイルを処理します。
upload.phpというPHPファイルを作成し、以下のようなコードを記述します。

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $uploadDir = './uploads/';
    $uploadFile = $uploadDir . basename($file['name']);

    if (!is_dir($uploadDir)) {
      echo 'Upload directory does not exist.';
    } elseif (!is_writable($uploadDir)) {
      echo 'Upload directory is not writable.';  
    } elseif (move_uploaded_file($file['tmp_name'], $uploadFile)) {
      echo 'File uploaded successfully.';
    } else {
      echo 'Error uploading file.';
    }
  } else {
    echo 'No file selected.';
  }
}
?>

このPHPファイルでは、POSTリクエストが送信された場合にファイルのアップロード処理を行います。
アップロードされたファイルの情報は、$_FILES[‘file’]で取得できます。

$uploadDir変数でアップロード先のディレクトリを指定し、$uploadFileでファイルの保存先を設定します。
move_uploaded_file関数を使って、一時ファイルを目的の場所に移動することで、ファイルのアップロードが完了します。

アップロードの成功や失敗に応じて、適切なメッセージをechoしてレスポンスとして返します。
htmxは、このレスポンスを#response要素に挿入して表示します。

アップロード成功/失敗のフィードバック

ファイルアップロードの成功や失敗をユーザーにフィードバックすることで、より使いやすいUIを提供できます。
以下のようなCSSを使って、レスポンスメッセージのスタイルを定義します。

#response {
  margin-top: 10px;
  padding: 10px;
  border-radius: 5px;
}

#response.success {
  background-color: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

#response.error {
  background-color: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;  
}

レスポンスメッセージに応じてクラスを付与することで、成功時は緑色、失敗時は赤色の背景色を適用します。
これにより、ユーザーはアップロードの結果を視覚的に確認できます。

サンプルコード

以上の内容を組み合わせた完全なサンプルコードは以下の通りです。

HTMLコード (index.html)

<!DOCTYPE html>
<html>
<head>
    <!-- htmxライブラリをCDNから読み込む -->
    <script src="https://unpkg.com/htmx.org"></script>
    <style>
        #response {
          margin-top: 10px;
          padding: 10px;
          border-radius: 5px;
        }
    
        #response.success {
          background-color: #d4edda;
          color: #155724;
          border: 1px solid #c3e6cb;
        }
    
        #response.error {
          background-color: #f8d7da;
          color: #721c24;
          border: 1px solid #f5c6cb;
        }
      </style>
</head>
<body>
    <h1>File Upload with HTMX</h1>
    <!-- ファイルアップロードフォーム -->
    <!-- hx-post属性で送信先を指定 -->
    <!-- hx-encoding属性でmultipart/form-dataを指定 -->
    <!-- hx-target属性でレスポンスの表示先を指定 -->
    <form id="upload-form" hx-post="upload.php" hx-encoding="multipart/form-data" hx-target="#response">
        <!-- ファイル選択input -->
        <input type="file" name="file">
        <!-- アップロードボタン -->
        <button type="submit">Upload</button>
    </form>
    <!-- レスポンス表示用のdiv -->
    <div id="response"></div>
</body>
</html>

PHPコード (upload.php)

<?php
// POSTリクエストが送信された場合にファイルのアップロード処理を行う
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // ファイルが選択されているかチェック
  if (isset($_FILES['file'])) {
    // アップロードされたファイルの情報を取得
    $file = $_FILES['file'];
    // アップロード先のディレクトリを指定
    $uploadDir = './uploads/';
    // アップロードされたファイルの保存先を設定
    $uploadFile = $uploadDir . basename($file['name']);

    // アップロード先のディレクトリが存在しない場合
    if (!is_dir($uploadDir)) {
      echo "<div id='response' class='error'>Upload directory does not exist.</div>";
    // アップロード先のディレクトリに書き込み権限がない場合
    } elseif (!is_writable($uploadDir)) {
      echo "<div id='response' class='error'>Upload directory is not writable.</div>";
    // ファイルの移動に成功した場合
    } elseif (move_uploaded_file($file['tmp_name'], $uploadFile)) {
      echo "<div id='response' class='success'>File uploaded successfully.</div>";
    // ファイルの移動に失敗した場合
    } else {
      echo "<div id='response' class='error'>Error uploading file.</div>";
    }
  // ファイルが選択されていない場合
  } else {
    echo "<div id='response' class='error'>No file selected.</div>";
  }
}
?>

このコードを実行すると、シンプルで高速なファイルアップロードが実現されます。

ファイルのアップロードに成功すると、緑色の背景色でメッセージが表示されます。
一方、アップロードに失敗した場合は、赤色の背景色でエラーメッセージが表示されます。

まとめ

この記事では、htmxとPHPを組み合わせてファイルアップロードを実装する方法を解説しました。
formタグを用いた従来の方法では、ページ全体をリロードする必要がありました。

しかし、htmxを使えば、JavaScriptを書かずにシンプルなHTMLの属性だけでファイルアップロードを実現できます。
また、サーバーサイドでのファイル処理や、アップロードの成功/失敗のフィードバックを適切に実装することで、ユーザーにとって使いやすいUIが作成できます。

htmxとサーバーサイドの処理を連携させることで、高速で洗練されたファイルアップロードを実装できます。
この記事で紹介したテクニックを活用し、さらに発展させることで、ユーザーにとって直感的で快適なファイルアップロード機能を提供しましょう。

タイトルとURLをコピーしました