前提・実現したいこと
XHAMPPでPHP(Ver.7.4.7)、MariaDB(Ver.10.4.13)を使用してローカルサーバー上にWordファイルをアップロード、及びダウンロードできるツールを開発しています。
発生している問題
DBから抽出したWordファイルデータをダウンロードして展開しようとすると、データ内容がすべて文字化けしてしまい、正しく展開できません。(尚、ファイル名、ファイルサイズ、ファイルの種類の情報については正しく格納及び抽出ができています。)
本来、wordファイルや画像ファイルはDBに格納すべきではないということは承知の上で、個人的にDBにそれらの情報を格納して出力する方法を確立させておきたいのです。一般的な方法ではないことは理解しています。なんとか、お力添えいただけないでしょうか??
該当のソースコード
以下に、実装中のプログラムソースを記します。
PHP
1 2// 入力フォーム 3 4<!DOCTYPE html> 5<html> 6<head> 7<meta charset="UTF-8" /> 8<title>XXXXX</title> 9</head> 10<body> 11<p align="justify"> 12<h1>XXXXX</h1> 13<form method="POST" enctype="multipart/form-data" action="XXXXX.php" > 14<div> 15 <label for="username"> ユーザー名:</label> 16 <input id="username" type="text" name="username" size="20" maxlength="20" /><br /> 17 <label for="modelname"> 製品名:</label> 18 <input id="modelname" type="radio" name="modelname" value="MP-60N" checked="checked">MP-60N 19 <input type="radio" name="modelname" value="MP-012">MP-012<br /> 20 <label for="ser"> シリアルNo.:</label> 21 <input id="s_symbol" type="text" name="s_symbol" size="5" maxlength="5" /> - 22 <input id="s_number" type="text" name="s_number" size="5" maxlength="5" /> 23 <label for="ordered"> 修理受注日:</label> 24 <input id="ordered" type="text" name="ordered" size="15" maxlength="15" /> 25 <label for="issued"> 報告書発行日:</label> 26 <input id="issued" type="text" name="issued" size="15" maxlength="15" /> 27 <input type="hidden" name="max_file_size" value="1000000" /> 28 <label for="report"> 修理報告書:</label> 29 <input type="file" name="report" size="50" /><br /> ← Wordファイルをアップロード 30 <input type="submit" value="登録" /> 31 <input type="reset" value="入力内容をリセットする" /> 32</div></p> 33<?php 34session_start(); 35$token = sha1(uniqid(mt_rand(), true)); 36$_SESSION['token'] = $token; 37 38?> 39<input type="hidden" name="token" value="<?php print $token; ?>" /> 40</form> 41</body> 42</html>
PHP
1 2// DBへ格納 3 4<?php 5require_once '../DbManager.php'; 6 7try { 8 $db = getDb(); 9 $stt = $db->prepare('INSERT INTO repairing(username, modelname, s_symbol, s_number, ordered, issued, rp_name, rp_type, rp_size, rp_data) VALUES(:username, :modelname, :s_symbol, :s_number, :ordered, :issued, :rp_name, :rp_type, :rp_size, :rp_data)'); 10 $stt->bindValue(':username', $_POST['username']); 11 $stt->bindValue(':modelname', $_POST['modelname']); 12 $stt->bindValue(':s_symbol', $_POST['s_symbol']); 13 $stt->bindValue(':s_number', $_POST['s_number']); 14 $stt->bindValue(':ordered', $_POST['ordered']); 15 $stt->bindValue(':issued', $_POST['issued']); 16 $file1 = file_get_contents($_FILES['report']['tmp_name']); // 17 $stt->bindValue(':rp_name', $_FILES['report']['name'], PDO::PARAM_STR); // 18 $stt->bindValue(':rp_type', $_FILES['report']['type'], PDO::PARAM_STR); // ファイルの格納処理 19 $stt->bindValue(':rp_size', $_FILES['report']['size'], PDO::PARAM_INT); // 20 $stt->bindValue(':rp_data', $file1, PDO::PARAM_LOB); // 21 $stt->execute(); 22 header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/XXXXX.php'); 23} catch(PDOException $e) { 24 print "エラーメッセージ:{$e->getMessage()}"; 25}*/ 26
PHP
1 2// DBから抽出しダウンロード 3 4<?php 5 6require_once '../DbManager.php'; 7require_once '../Encode.php'; 8 9try { 10 $db = getDb(); 11 $stt = $db->prepare('SELECT * FROM repairing WHERE id = ?'); 12 $stt->bindValue(1, $_GET['id'] ?: 1); 13 $stt->execute(); 14 15 $stt->bindColumn('rp_name', $rp_name, PDO::PARAM_STR); // 16 $stt->bindColumn('rp_type', $rp_type, PDO::PARAM_STR); // 各種ファイルデータをパラメータに格納 17 $stt->bindColumn('rp_size', $rp_size, PDO::PARAM_INT); // 18 $stt->bindColumn('rp_data', $rp_data, PDO::PARAM_LOB); // 19 20 if($stt->fetch(PDO::FETCH_BOUND)){ 21 file_put_contents($rp_name, mb_convert_encoding($rp_data, 'SJIS-win', 'utf-8')); // 22 header("Content-Disposition: File Transfer"); // 23 header("Content-type: {$rp_type}"); // 24 header('Content-Disposition: attachment; filename="'.$rp_name.'"'); // 25 header('Expires: 0'); // ダウンロード処理 26 header('Cache-Control: must-revalidate'); // 27 header('Content-Transfer-Encoding: binary'); // 28 header("Content-Length: {$rp_size}"); // 29 } 30 else{ 31 print '該当するデータがありません。'; 32 } 33 34 }catch(PDOException $e) { 35 print "エラーメッセージ:{$e->getMessage()}"; 36} 37
試したこと
①画像ファイルなどで試験 ⇒ 同様の現象が発生(拡張子は正しく動作する)
②入力フォームの送信先で$_FILESの中身やfile_get_contents($_FILES['report']['tmp_name'])の出力を確認 ⇒ 文字化け発生
③phpmyadminにて直接DBに画像ファイルやWordファイルを格納しプログラムで抽出及びダウンロードして展開 ⇒ 文字化け発生(②と同様)
補足情報(DBのテーブル定義)
何卒宜しくお願い致します。
あなたの回答
tips
プレビュー