はじめに
PHPからデータをインポートするモジュールを記載。備忘録。
フロントエンド
<!DOCTYPE html>
<html>
<head>
<title>CSV取込サンプル</title>
</head>
<body>
<form action="csv_import.php" method="post" enctype="multipart/form-data">
<input type="file" id="csvFile" name="csvFile">
<input type="submit">
</form>
</body>
</html>
enctype="multipart/form-data"について
これを指定しなければ添付ファイルの情報が送信できず、input type="text"なんかと同じ扱いになる模様。
こちら(enctype='multipart/form-data'ってなんだ?)を参考にさせていただきました。
input type="file"のデザインを編集できないの?
できるっぽいです。ただ、デフォルトだと弄れないっぽいので、標準をdisplay: noneにしてlabelでデザインしてあげるべきだとかなんとか。
<label for="csvFile">
<span id="filename">クリックしてファイルを選択してください</span>
<input type="file" id="csvFile" name="csvFile">
</label>
<style>
form label input[type="file"]{
display: none;
}
form label{
display: block;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
background: #DDD;
border-radius: 5px;
}
</style>
ファイル名を表示させたい場合はjQueryのお世話になる感じです。
$(function(){
$("#csvFile").on("change", function(){
var file = this.files[0];
if(file) $("#filename").html(file.name);
});
})
サーバーサイド
<?php
$filePath = "./files/" . $_FILES["csvFile"]["name"];
if (move_uploaded_file($_FILES["csvFile"]["tmp_name"], $filePath))
{
chmod($filePath, 0644); // ファイルアップロード成功
}else{
// ファイルアップロード失敗
}
$objFile = new SplFileObject($filePath);
$objFile->setFlags(SplFileObject::READ_CSV);
$objFile->setCsvControl("\t" /* 区切り文字 */, "\"" /* 囲い文字 */);
foreach ($objFile as $key => $line)
{
foreach ($line as $buf)
{
$buf = mb_convert_encoding($buf, "UTF-8", "sjis-win");
$records[$key][] = $buf;
}
}
echo "<pre>";
print_r($records);
echo "</pre>";
foreach (glob("./files/*.csv") as $delFile) unlink($delFile); // ファイル削除処理
?>
実際はこの後の処理の部分(ファイルの存在判定・CSVデータチェックetc...)が入ってきます。
move_uploaded_fileについて
一度クライアント側ファイルをサーバー上にアップロードする必要があります。いつもお世話になっているPHPマニュアル様によると、
bool move_uploaded_file (/* string */ $filename , /* string */ $destination);
この関数は、filename で指定されたファイルが (PHP の HTTP POST アップロード機構によりアップロードされたという意味で) 有効なアップロードファイルであるかどうかを確認します。 そのファイルが有効な場合、destination で指定したファイル名に移動されます。
この種の確認は、アップロードされたファイルに関して何でもできる場 合には、その内容をユーザー、または同じシステム上の他のユーザーにさえ 暴かれる可能性があるため、特に重要です。
とのことです。アップロード後、アクセス権を変更してるのはこれでなんですかね。
SplFileObjectについて
マニュアルの量的に紹介しきれなかったので簡単に。
この辺(【PHP】その CSV 変換、本当に「fgetcsv」でいいの?)を参考にさせていただきました。
$objFile->setFlags(SplFileObject::READ_CSV);
ここで取り込んだ行をCSVとして読み込んでいます。
$objFile->setCsvControl("\t" /* 区切り文字 */, "\"" /* 囲い文字 */);
ここで区切り位置と、CSVファイルの囲い文字を指定しています。
Tabとカンマ、どっちにも対応する方法がないか調べてみたんですが見当たらず...力技でやるしかないのかなぁ。サンプルはTabで区切るようにしています。
おまけ
HTML5から実装されたらしいファイルのダウンロード処理。簡単。
<a href="./files/download.csv" download="download.csv">ダウンロード</a>