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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PHP

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

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

3回答

2724閲覧

クラウド上のWebアプリ(PHP)にCSVデータをアップロードしデータベースに格納する方法

tomona

総合スコア37

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PHP

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

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2018/10/08 12:53

CakePHP3を利用してクラウドのWebアプリを作成しています。

ユーザーが「ファイルを選択」ボタンからユーザー側ローカルにあるCSVファイルを選択し、そこからデータをインポートし、最終的にデータベースに格納する処理を作ろうとしています。

フレームワークではCakePHPを利用していますがフレームワーク内に適当な関数がなかったためPHPのfgetcsv関数を利用してデータを取ろうと試みました。

URL

http://localhost/rd-trial/csv-test/add

すると、下記のエラーメッセージが出てファイルを読み込めていないようです。
※csvtest用データ 住所録.csvを開こうとしています。

fopen(csvtest用データ 住所録.csv): failed to open stream: No such file or directory

【主なソースコード】
CsvTestController.php

public function add() { $csvTest = $this->CsvTest->newEntity(); if ($this->request->is('post')) { //print_r($_FILES); $f = fopen($_FILES['csv_test']['name'], "r"); while($line = fgetcsv($f)){ // 読み込んだ結果を表示します。 var_dump($line); } // test.csvを閉じます。 fclose($f); } //$this->set(compact('csvTest')); }

add.ctp

<?php /** * @var \App\View\AppView $this * @var \App\Model\Entity\CsvTest $csvTest */ ?> <nav class="large-3 medium-4 columns" id="actions-sidebar"> <ul class="side-nav"> <li class="heading"><?= __('Actions') ?></li> <li><?= $this->Html->link(__('List Csv Test'), ['action' => 'index']) ?></li> </ul> </nav> <div class="csvTest form large-9 medium-8 columns content"> <?= $this->Form->create($csvTest,array('enctype'=>'multipart/form-data')) ?> <fieldset> <legend><?= __('Add Csv Test') ?></legend> <?php echo $this->Form->input('csv_test',array('type'=>'file')); ?> </fieldset> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> </div> <div> <input type="file" name="csv_test" size="30"> </div>

以下のURLを見ると一度サーバー側にアップロードしているようですが、アップロードは必須でしょうか。出来ればサーバー側にデータは残しておきたくないです。
またアップロードする場合、どのディレクトリが適切か等ありますでしょうか。

https://qiita.com/katsukii/items/1b7e95723d0070cfc5b9

また、その他、アドバイスあればいただけると幸いです。
宜しくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/08 23:16

参考サイトを読んでください。そして模倣してください。それで解決です。
tomona

2018/10/10 13:42

アドバイスありがとうございます。アップロードは必須の様ですので模倣するようにいたします。
guest

回答3

0

自己解決

以下のコンポーネントを作ることで対応できました。
アップロードしたファイルはサーバーのTempフォルダに格納され、処理が終わった後は自動的に消されておりました。

CsvComponent.php

PHP

1<?php 2namespace App\Controller\Component; 3 4use Cake\Controller\Component; 5class CsvComponent extends Component{ 6 7 public function import(){ 8 $file_tmp_name = $_FILES["csv_test"]["tmp_name"]; 9 $file_name = $_FILES["csv_test"]["name"]; 10 11 //拡張子の判定 12 if (pathinfo($file_name, PATHINFO_EXTENSION) != 'csv') { 13 echo __('CSVファイルのみ対応しています。'); 14 return; 15 }else{ 16 //ファイルのオープン 17 $f = fopen($file_tmp_name, "r"); 18 //配列に変換する 19 while (($csvdata = fgetcsv($f, 0, ","))!=false) { 20 foreach($csvdata as &$value){ 21 //文字コードの変換 22 $value=mb_convert_encoding($value,'UTF-8'); 23 //echo $value.'<br>'; 24 }unset($value); 25 $data[]=$csvdata; 26 //print_r($data); 27 } 28 $fc=fclose($f); 29 return $data; 30 } 31 } 32 public function export(){ 33 34 } 35 36} 37?>

CsvTestController.php

PHP

1<?php 2namespace App\Controller; 3 4use App\Controller\AppController; 5 6/** 7 * CsvTest Controller 8 * 9 * @property \App\Model\Table\CsvTestTable $CsvTest 10 * 11 * @method \App\Model\Entity\CsvTest[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = []) 12 */ 13class CsvTestController extends AppController 14{ 15 public function initialize(){ 16 $this->loadComponent('Csv'); 17 18 } 19 /** 20 * Index method 21 * 22 * @return \Cake\Http\Response|void 23 */ 24 public function index() 25 { 26 $entity=$this->CsvTest->newEntity(); 27 if($this->request->is('post')){ 28 //$this->loadModel('CsvTest'); 29 30 $data=$this->Csv->import(); 31 /*echo '<pre>'; 32 print_r($data); 33 echo '</pre>';*/ 34 $this->set(compact('entity','data')); 35 //$this->render('confirm'); 36 } 37 38 $this->set(compact('csvTest','data')); 39 40 } 41

CsvTest/index.ctp

ctp

1<?php 2/** 3 * @var \App\View\AppView $this 4 * @var \App\Model\Entity\CsvTest $csvTest 5 */ 6?> 7 8<div class="csvTest form large-9 medium-8 columns content"> 9 <?= $this->Form->create('csvTest',array('enctype'=>'multipart/form-data')) ?> 10 <fieldset> 11 <legend><?= __('Add Csv Test') ?></legend> 12 <?= $this->Form->input('csv_test',array('type'=>'file'));?> 13 </fieldset> 14 <?= $this->Form->button(__('Submit')) ?> 15 <?= $this->Form->end() ?> 16</div> 17<table cellpadding="0" cellspacing="0"> 18 <?php $i=1 ?> 19 <?php foreach ($data as $value): ?> 20 <?php if($i=1): ?> 21 <thead> 22 <tr> 23 <?php foreach ($value as $column): ?> 24 <th scope="col"><?= $this->Paginator->sort($column) ?></th> 25 <?php endforeach; ?> 26 <?php $i=2; ?> 27 </tr> 28 </thead> 29 <?php else: ?> 30 <tbody> 31 <?php foreach ($value as $data): ?> 32 <tr> 33 <td><?= h($data) ?></td> 34 </tr> 35 <?php endforeach; ?> 36 </tbody> 37 <?php endif; ?> 38 <?php endforeach; ?> 39</table>

投稿2019/03/02 01:23

tomona

総合スコア37

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ファイルをアップロードするという手法であれば、PHP の仕組み上、サーバ内にファイルが作成されます。
どうしてもそれが嫌なのであれば、ファイルアップロードという手法はあきらめて、textarea にコピペで CSV 全文を貼り付ける、Ajaxでファイルの内容を返すように実装する、、といったことで実現可能ではあります。
普通にファイルアップロードした方が良いとは思いますが。

投稿2018/10/09 02:12

ssasaki

総合スコア1167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomona

2018/10/10 13:44

ご回答ありがとうございます。アップロードは必須の様ですのでアップロード処理を組み込みたいと思います。また、CakePHPのディレクトリでアップロード場所にふさわしい場所があればご教示頂けると幸いです。
guest

0

アップロードしてサーバー内にファイルを設置しないとファイルを読み込めないのでアップロードは必須です。
アップロードした後にそのファイルを削除すれば良いです。
あと、$_FILESが持っているのはファイルの情報ですがnameはあくまでファイルがセットされたローカルPC上のパス(またはファイル名)なのでサーバー側からは参照できません。

投稿2018/10/08 23:10

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/08 23:19

参考サイトがないとなにか言われると思って検索しただけの人に何を教える必要があるの? 1ミリも理解してないし、模倣する気もない人に
m.ts10806

2018/10/08 23:23

質問的には「なぜアップロードが必要か」という内容だったのでそれに答えたつもりです。 まあ、起きた現象に対してなぜそうなのか考えて参考記事でまずやってみれば良いのかなとは思いますが、 そもそもPHPマニュアル案件ですね。CakePHPもファイルアップロード関係はPHPマニュアル参照ってされてましたし。
退会済みユーザー

退会済みユーザー

2018/10/08 23:39

しかし、参考サイトも冗長だな。 コピー先ファイル名を何度も結合しなおしてる(潜在バグ)
m.ts10806

2018/10/08 23:41

そこはその通りにやってみないとわからない部分も実際はあるのでやってみたうえでリファレンスとPHPマニュアル確認は習慣付けたいところですね。
tomona

2018/10/10 13:53

ご回答ありがとうございます。アップロードは必須の様ですのでアップロード処理を組み込みたいと思います。 今回のご質問の趣旨としては、サーバーアップロード、変数格納、削除といった処理が複雑であり、CSVファイルを読み込むというどこのサイトでも使われている処理なのでもっとシンプルにできないかと思った点と参考サイトを自分なりに応用してみて失敗したのでアドバイスいただければと思った次第です。 単に参考サイトをコピペするだけなら意味ないと思います。自分のコードに応用して模倣したつもりですが何か間違っていますか?
m.ts10806

2018/10/10 20:46

>単に参考サイトをコピペするだけなら意味ないと思います。自分のコードに応用して模倣したつもりですが何か間違っていますか? 応用は基本が出来てからです。 PHPであればフレームワークのマニュアル・・・よりも先に PHPマニュアルで基本的な考え方と機能をおさえる必要があります。 http://php.net/manual/ja/features.file-upload.post-method.php 単にコピペが意味がないという考え方は良いですが、参考サイトの処理をきちんと把握した上で組み込むことができなければただの掟破りです。 CakePHPはフレームワークなのでお作法があります。PHPにもお作法があります。 「ファイルアップロードはこうする」基本的流れがありますので、それをぶった切った状態で自分が思うように組み込んだのでは動かないのは当然です。 PHPマニュアルを参照すれば、私の回答の後半部分がどういう意味か理解できるかと思います。 > あと、$_FILESが持っているのはファイルの情報ですがnameはあくまでファイルがセットされたローカルPC上のパス(またはファイル名)なのでサーバー側からは参照できません。 応用するのは参考サイトなりリファレンスなりPHPマニュアルなりの基本的なやり方がそのまま組み込めて、実際に動作してからです。 「お作法」は総じて複雑、というか煩雑であるものです。しかしそれは「必要な手順」です。 CakePHPであればもう少し簡単にできるようにはなっていると思いますよ。もちろん裏ではおおもとのPHPのお作法にのっとった処理が書かれているわけなので、 「単に参考サイトをコピペするだけなら意味ない」と仰るのでしたら「フレームワークの根幹を理解せずに使ってるだけなら意味ない」とも言えます。 フレームワークを利用しているのであれば$_FILESを直接利用するのはフレームワークのメリットを活用できていないということにもなります。 ファイルが残ってしまうことを気にされていますが、回答の通り用事が済んだら削除すれば良いだけです。CakePHPにもstorage的なディレクトリ(ブラウザから参照不可な領域)はあるかと思いますので、そちらにアップロードして消せば良いです。 もし例外などが発生して削除処理が行われないことを懸念されるのでしたら処理の冒頭で該当フォルダ内のファイルを一斉削除する処理か、定期実行するバッチを仕込んでおいて自動削除するようにすれば良いかと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問