ユーザーが画像やドキュメントなどのファイルをサーバーにアップロードできるようにすることで、より豊かなユーザー体験を提供できます。
古くは、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とサーバーサイドの処理を連携させることで、高速で洗練されたファイルアップロードを実装できます。
この記事で紹介したテクニックを活用し、さらに発展させることで、ユーザーにとって直感的で快適なファイルアップロード機能を提供しましょう。

