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

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

新規登録して質問してみよう
ただいま回答率
87.20%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

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

解決済

phpで日本語名のファイルをアップロードするとファイルが壊れる

alberorana
alberorana

総合スコア50

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

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

2回答

1評価

2クリップ

9491閲覧

投稿2017/07/10 02:24

###前提・実現したいこと
PHPであるユーザーがアップロードしたファイルを他人がダウンロードできるWebアプリを作っています。
拡張子はpdf,xlsm,docxあたりを対象として、日本語もOKにしたいです。

###発生している問題・エラーメッセージ
問題になっているのは、日本語名のファイルをアップロードするとファイルが壊れ、文字化けしてしまうことです。詳細として

・日本語名のファイルをアップロードすると0バイトとなり開くことができない
・ダウンロードログとしてMysqlにダウンロードされたファイル名を挿入していますが、ファイル名が文字化けしてしまう。
この2点になります。

ファイル破損

ダウンロードログ文字化け

###該当のソースコード
こちらがアップロードのソースコード。
プログラムの都合上、一度自前の一時フォルダに移動→本来の保管場所という方法をとっています。

まずはユーザーから自前の一時フォルダへのアップロード

php

<?php session_start(); $uploaddir = $_SESSION['uploaddir'];//前ページで決めたディレクトリを引き継ぎ(root/UID/samba/nsr) $ds = DIRECTORY_SEPARATOR; //スラッシュの変数 require('dbc.php'); $cookie = $_COOKIE['cookie']; $stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); $stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); $stmt -> execute(); $udata = $stmt -> fetch(); $pdo = NULL; if (!empty($_FILES)) {//アップロードファイルがある時の処理 $tempFile = $_FILES['file']['tmp_name']; //3 //一時保管ディレクトリ $tmpdir = '/home/tmp/' . $udata['uid']; //ディレクトリの存在確認 if(!file_exists($tmpdir)){ mkdir($tmpdir, 0700); } $_SESSION['tmpdir'] = $tmpdir; $tmpxml = $tmpdir . '/' . $_FILES['file']['name']; //5 $_SESSION['tmpxml'] = $tmpxml; move_uploaded_file($tempFile,$tmpxml); } ?>

次に一時フォルダから本フォルダへ

php

<?php require('../library/functions.php');//共通宣言、関数呼び出し require('../dbc.php');//データベース接続 $cookie = $_COOKIE['cookie']; $stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); $stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); $stmt -> execute(); $udata = $stmt -> fetch(); $pdo = NULL; $tmppass = '/home/tmp/' . $udata['uid'] . '/'; //ディレクトリの中身を検索 $dir_content = scandir($tmppass, 1);//ディレクトリ内検索 $loop = count($dir_content); $loop = $loop - 2; //アップロードボタンが押されたら if(isset($_POST['upload'])){ $uploaddir = $_SESSION['uploaddir'];//アップロードフォルダを定義 $handle = opendir( $tmppass ) ;//tmpフォルダの中身をすべて解析 while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { //tmpディレクトリにファイルがある限りユーザーディレクトリへ移動する rename($tmppass . '/' . $entry, $uploaddir . '/' . $entry); } } unlink_dir($tmppass); header("Location: /parts/regist_fin.php"); exit(); } include($_SERVER['DOCUMENT_ROOT'] . '/parts/head.php'); ?> </head> <body class="index"> <h1>DOC-FINDER-V1</h1> <div class="container"> <h2>アップロードファイルの確認</h2> <p>アップロードするファイルに間違いがなければアップロードボタンを押してください。</p> <?php $i = 0; while ($i < $loop) { echo '<p>' . $dir_content["$i"] . '</p>'; $i++; }//ファイルの数だけループ ?> <div class='row'> <div class="col-md-offset-4 col-md-4"> <form action="" method="post" enctype='multipart/form-data' multiple><input class="btn btn-warning" type="submit" name="upload" value="アップロード"></form> </div> <div class="col-md-2"> <input type="button" class="btn btn-danger" value="キャンセル" onClick="location.href='/parts/up_cancel.php'"> </div> </div> </div><!-- class container --> </body>

ダウンロードロジック

php

<?php session_start(); require('dbc.php'); $cookie = $_COOKIE['cookie']; $stmt = $pdo -> prepare("SELECT * FROM user WHERE cookie=:cookie"); $stmt -> bindValue(':cookie', $cookie, PDO::PARAM_STR); $stmt -> execute(); $udata = $stmt -> fetch(); $pdo = NULL; $uid = $udata['uid']; $recordnumber = $_SESSION['id']; $dir = $_SESSION['dir']; $url = $_SERVER["REQUEST_URI"]; $keys = parse_url($url); //パース処理 $path = explode("/", $keys['path']); //分割処理 $file = end($path); //最後の要素を取得 $file = mb_convert_encoding($file, "UTF-8", "auto"); $fpath = $dir . '/' . $file; header('Content-Length: '.filesize($fpath)); header("Content-type: application/octet-stream"); header('Content-disposition: attachment; filename="'.$file.'"'); readfile($fpath); //ダウンロードテーブルに挿入 require('dbc.php'); $stmt = $pdo -> prepare("INSERT INTO download(uid,file,recordnumber) VALUES(:uid,:file,:recordnumber)"); $stmt -> bindValue(':uid', $uid, PDO::PARAM_STR); $stmt -> bindValue(':file', $file, PDO::PARAM_STR); $stmt -> bindValue(':recordnumber', $recordnumber, PDO::PARAM_INT); $stmt -> execute(); $pdo = NULL; ?>

###試したこと
・utf-8への変換
・日本語、アルファベットの切り分け→日本語ファイルのみ破損、英語ファイルは文字化け、破損しない

###補足情報(言語/FW/ツール等のバージョンなど)
・php 7.0.19
・CentOS6.8
開発環境はローカル上のVMに構築しています。

以上になります。原因がわからなくて困っています。
何卒よろしくお願いいたします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

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