LoginSignup
11
25

More than 5 years have passed since last update.

PHPでCSVをインポートする

Last updated at Posted at 2017-02-14

はじめに

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>
11
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
25