CakePHP、CSVファイルをインポート

FormでCSVファイルをインポートする方法についてまとめておきます。

まずは面ページ(Template)の設定。

add.ctp

<?= $this->Form->create($deposit, array('type' => 'file')) ?>
<?= $this->Form->file('csv',[ 'accept'=>'.csv']); ?>
<?= $this->Form->button('Submit'); ?>
<?= $this->Form->end() ?>

createの時にtype => ‘file’としておくことでファイルがPostされます。 またForm->fileに’accept’=>’.csv’をしておくとcsvファイルのみが選択される状況になるので予期せぬ挙動を防ぐことができます。

次にコントローラーの設定です。

ArticlesController.php

public function add(){
    $article = $this->Articles->newEntity();
    $tmp_file_name = $_FILES["csv"]["tmp_name"];
    $data = array();
    if (is_uploaded_file($tmp_file_name)){
        $csv_contents = fopen($tmp_file_name, "r");
        while(($csv_content = fgetcsv($csv_contents, 0, ",")) !==FALSE){
            $data[] = mb_convert_encoding($csv_content, 'UTF-8', "auto");  // エンコード
        }
    }
    $article = $this->Articles->patchEntity($article, $data);
    if($this->Articles->save($article)){
        $connection->commit();
        $this->Flash->success(__('CSVファイルを追加しました'));
        return $this->redirect(['action' => 'index']);
    }
    $this->log(print_r($deposits->getErrors(), true), LOG_DEBUG);
    $this->Flash->error(__('CSVファイルを追加できませんでした'));
}

このような感じでCSVファイルのインポートができると思います。今回の例ではCSVファイルを tempから移動させていないのでファイルは消去されてしまします。アップロードされたCSVファイルを取っておきたいときは別途move_uploaded_file関数を実装しましょう。