###前提・実現したいこと
PHPであるユーザーがアップロードしたファイルを他人がダウンロードできるWebアプリを作っています。
拡張子はpdf,xlsm,docxあたりを対象として、日本語もOKにしたいです。
###発生している問題・エラーメッセージ
問題になっているのは、日本語名のファイルをアップロードするとファイルが壊れ、文字化けしてしまうことです。詳細として
・日本語名のファイルをアップロードすると0バイトとなり開くことができない
・ダウンロードログとしてMysqlにダウンロードされたファイル名を挿入していますが、ファイル名が文字化けしてしまう。
この2点になります。
###該当のソースコード
こちらがアップロードのソースコード。
プログラムの都合上、一度自前の一時フォルダに移動→本来の保管場所という方法をとっています。
まずはユーザーから自前の一時フォルダへのアップロード
php
1<?php 2session_start(); 3$uploaddir = $_SESSION['uploaddir'];//前ページで決めたディレクトリを引き継ぎ(root/UID/samba/nsr) 4$ds = DIRECTORY_SEPARATOR; //スラッシュの変数 5require('dbc.php'); 6$cookie = $_COOKIE['cookie']; 7$stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); 8$stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); 9$stmt -> execute(); 10$udata = $stmt -> fetch(); 11$pdo = NULL; 12 13if (!empty($_FILES)) {//アップロードファイルがある時の処理 14 15 $tempFile = $_FILES['file']['tmp_name']; //3 16 //一時保管ディレクトリ 17 $tmpdir = '/home/tmp/' . $udata['uid']; 18 //ディレクトリの存在確認 19 if(!file_exists($tmpdir)){ 20 mkdir($tmpdir, 0700); 21 } 22 $_SESSION['tmpdir'] = $tmpdir; 23 $tmpxml = $tmpdir . '/' . $_FILES['file']['name']; //5 24 $_SESSION['tmpxml'] = $tmpxml; 25 move_uploaded_file($tempFile,$tmpxml); 26 27} 28?>
次に一時フォルダから本フォルダへ
php
1<?php 2require('../library/functions.php');//共通宣言、関数呼び出し 3require('../dbc.php');//データベース接続 4$cookie = $_COOKIE['cookie']; 5$stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); 6$stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); 7$stmt -> execute(); 8$udata = $stmt -> fetch(); 9$pdo = NULL; 10$tmppass = '/home/tmp/' . $udata['uid'] . '/'; 11//ディレクトリの中身を検索 12$dir_content = scandir($tmppass, 1);//ディレクトリ内検索 13$loop = count($dir_content); 14$loop = $loop - 2; 15//アップロードボタンが押されたら 16if(isset($_POST['upload'])){ 17 $uploaddir = $_SESSION['uploaddir'];//アップロードフォルダを定義 18 $handle = opendir( $tmppass ) ;//tmpフォルダの中身をすべて解析 19 while (false !== ($entry = readdir($handle))) { 20 if ($entry != "." && $entry != "..") { 21 //tmpディレクトリにファイルがある限りユーザーディレクトリへ移動する 22 rename($tmppass . '/' . $entry, $uploaddir . '/' . $entry); 23 } 24 } 25 unlink_dir($tmppass); 26 header("Location: /parts/regist_fin.php"); 27 exit(); 28} 29include($_SERVER['DOCUMENT_ROOT'] . '/parts/head.php'); 30?> 31 </head> 32 <body class="index"> 33 <h1>DOC-FINDER-V1</h1> 34 <div class="container"> 35 <h2>アップロードファイルの確認</h2> 36 <p>アップロードするファイルに間違いがなければアップロードボタンを押してください。</p> 37 <?php 38 $i = 0; 39 while ($i < $loop) { 40 echo '<p>' . $dir_content["$i"] . '</p>'; 41 $i++; 42 }//ファイルの数だけループ 43 ?> 44 <div class='row'> 45 <div class="col-md-offset-4 col-md-4"> 46 <form action="" method="post" enctype='multipart/form-data' multiple><input class="btn btn-warning" type="submit" name="upload" value="アップロード"></form> 47 </div> 48 <div class="col-md-2"> 49 <input type="button" class="btn btn-danger" value="キャンセル" onClick="location.href='/parts/up_cancel.php'"> 50 </div> 51 </div> 52 </div><!-- class container --> 53 </body>
ダウンロードロジック
php
1<?php 2session_start(); 3require('dbc.php'); 4$cookie = $_COOKIE['cookie']; 5$stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); 6$stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); 7$stmt -> execute(); 8$udata = $stmt -> fetch(); 9$pdo = NULL; 10 11$uid = $udata['uid']; 12$recordnumber = $_SESSION['id']; 13 14$dir = $_SESSION['dir']; 15$url = $_SERVER["REQUEST_URI"]; 16$keys = parse_url($url); //パース処理 17$path = explode("/", $keys['path']); //分割処理 18$file = end($path); //最後の要素を取得 19$file = mb_convert_encoding($file, "UTF-8", "auto"); 20$fpath = $dir . '/' . $file; 21header('Content-Length: '.filesize($fpath)); 22header("Content-type: application/octet-stream"); 23header('Content-disposition: attachment; filename="'.$file.'"'); 24readfile($fpath); 25//ダウンロードテーブルに挿入 26require('dbc.php'); 27$stmt = $pdo -> prepare("INSERT INTO download(uid,file,recordnumber) VALUES(:uid,:file,:recordnumber)"); 28$stmt -> bindValue(':uid', $uid, PDO::PARAM_STR); 29$stmt -> bindValue(':file', $file, PDO::PARAM_STR); 30$stmt -> bindValue(':recordnumber', $recordnumber, PDO::PARAM_INT); 31$stmt -> execute(); 32$pdo = NULL; 33?> 34
###試したこと
・utf-8への変換
・日本語、アルファベットの切り分け→日本語ファイルのみ破損、英語ファイルは文字化け、破損しない
###補足情報(言語/FW/ツール等のバージョンなど)
・php 7.0.19
・CentOS6.8
開発環境はローカル上のVMに構築しています。
以上になります。原因がわからなくて困っています。
何卒よろしくお願いいたします。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。