質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

Q&A

0回答

1530閲覧

DBに格納したWordファイルをダウンロードするとファイル内データが文字化けして正しく展開できない

Masaki_Kagawa

総合スコア2

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

0グッド

0クリップ

投稿2020/06/26 03:11

編集2020/06/26 03:49

前提・実現したいこと

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のテーブル定義)

イメージ説明

何卒宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/06/26 03:42

>XHANPP 「XAMPP」です。
Masaki_Kagawa

2020/06/26 12:32 編集

m.ts10806さん すみません、見落としていました。 ご指摘ありがとうございます。
dodox86

2020/06/26 04:17

PHPに詳しい訳ではないのですが、何か > if($stt->fetch(PDO::FETCH_BOUND)){ 以降のコードの、ファイルをHTTPレスポンスに乗せる部分がメチャメチャな気がするのですが、合っているのでしょうか? 1. "Content-Disposition:" ヘッダーを2回入れてますが、なぜでしょうか? "File Transfer"って合っていますか? 2. file_put_contents($rp_name, mb_convert_encoding($rp_data, 'SJIS-win', 'utf-8')); で、なんでここでエンコードを変えているのでしょうか? アップロード INSERTの部分で、受信したファイルをBLOB形式でそのまま保存しているので、ここで変換すると壊れちゃうのではないですか? 3. HTTPレスポンスのヘッダーは送っていますが、ファイルの本体データは送っていない様子です。これでは受信(ブラウザ)側でファイルが正しく展開できるように見えません。 上記、指摘に間違いがあればコメントください。
kyoya0819

2020/06/26 04:25

多分文字コード変換しちゃいけませんし、Wordの文章をメモ帳やエディタで開くとフォーマットの関係で少なくとも文字化けは発生するはずです。
Masaki_Kagawa

2020/06/26 12:53

dodox86さん 勉強不足で大変お恥ずかしい限りです。 ①header('Content-Disposition: attachment; filename="'.$rp_name.'"');  このコードのみで正しく動作しました。 ②file_put_contents($rp_name, mb_convert_encoding($rp_data, 'SJIS-win', 'utf-8'));  このコードを削除したおかげで正しくダウンロードできました。 ③すみません、read()関数もしくはget_file_contents()関数の実装が抜けていました。 詳細の問題まで丁寧にご指摘頂き、有難う御座います。 現在は一旦、DBにファイル保存先のパスを、ファイルデータ本体は同サーバー上のdocディレクトリに保存する仕組みを構築し、ダウンロードする際はDBから指定したファイルデータの保存先パスを抽出し、そのファイルパスを使ってdocディレクトリから読み込む流れで対応しています。この方法では、dodox86さんにご指摘頂いた方法で正常にダウンロードする事ができました。 DBに格納したwordのバイナリデータから直接ダウンロードする仕組みでも一度試してみようと思います。もし、それでも失敗した時はまたお力添え頂けると幸いです。 ご指摘、ありがとうございました。
Masaki_Kagawa

2020/06/26 12:56

asuchi0819さん ご指摘頂きありがとうございます。 文字コード変換コードを削除したところ、正しく動作しました。 今回ご指摘頂いた項目を考慮した上でもう一度バイナリデータ抽出経由でのダウンロードが成功するか試してみます。また問題が発生しましたら、お力添えをいただけますと幸いです。 ありがとうございました。
dodox86

2020/06/26 13:36

>Masaki_Kagawaさん > DBに格納したwordのバイナリデータから直接ダウンロードする仕組みでも一度試してみようと思います。 もし試して解決したら、原因と解決、対応策をまとめ、自己回答/解決で質問を閉じてもらえればと思います。
kyoya0819

2020/06/26 15:28

もしも完全に読める文字で入れたいなら、base64あたりでエンコードすればいけそうな気も。 (ただ、莫大な文字列長が予想されるのでカラムも其れ相応のものにする必要があると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問