yacsv かいせき
2016年06月08日 16:34
アップロードするための処理
View@import.ctp
<?php echo $this->Form->create('Post', array('type' => 'file')); ?>
<fieldset>
<legend><?php echo __('Import Posts'); ?></legend>
<?php if (!empty($importValidationErrors)): ?>
<?php foreach($importValidationErrors as $i => $error): ?>
<p>ヘッダを除いて<?php echo $i; ?>行目</p>
<?php pr($error); ?>
<?php endforeach; ?>
<?php endif; ?>
<?php
echo $this->Form->input('csvfile', array('type' => 'file'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
~~~~~~~~~~~~~~~~~~~~~~~~~~
Postした値をうけとる処理
import()@PostsController.php
Call元:$this->Post->importCsv($this->request->data, $options)
中継:public function __call($method, $params) @Model.php
Call先:public function importCsv(Model $model, $data = null, $options = array()){
~~~~~~~~~~~~~~~~~~~~~~~~~~
importCsv()@ImporterBehavior.php
$model->importFields
モデルに設定した、リンクするカラムの情報
// 何列目がどのフィールドか
public $importFields = array(
'title', // 1列目はPost.title
'body', // 2列目はPost.body
);
$model->importFilterArgs;
ファイルを読み込みじにViewで設定した、Postされた値をどこに格納したかを
指定。
Viewで、
$this->Form->create('Post', array('type' => 'file'));
$this->Form->input('csvfile', array('type' => 'file'));
Postされたデータは、**['Post']['csvfile']としてはいってくる。
そのため、この変数は、
1画面中に複数のPostされた値があるが、インポートしたい値だけを対象にする
ためにこのような仕組みを設けている?
★この仕組みをつかえば、複数のテーブルに対して設定は可能か?
→importCsv()の引数に、Model $modelがあるため、1テーブルに対してしか設定
できないと思われる。
Postされたデータは、
$this->params['form'][パラメーター名]
でとりだすことができる。
どのような値がとれるかは、以下の通り
[name] => ファイル名 "sample.csv"
[type] => ファイルの種類 "application/vnd.ms-excel"
[tmp_name] => アップロードファイルを一時保存したパス "C:\xampp\tmp\phpBFDD.tmp"
[error] => エラーの数 0
[size] => ファイルのサイズ 229
アップロードされたファイルは [tmp_name] のパスに一時ファイルとして保存され、アクションメソッド終了と同時に一時ファイルは削除される。
アクションメソッドの中で一時ファイルを任意の場所にコピーしてやればファイルのアップロード完了
↓一時ファイル格納場所から特定の場所にコピーする処理は↓
$filePath = TMP . uniqid('importer_', true) .'_'. $data[$model->alias][$csvField]['name'];
$filePathには、
"~\app\tmp\importer_5757aff3eb9b38.84968690_sample.csv"に格納される
uniqidとは、マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID を取得
move_uploaded_file($tmpFile, $filePath);
_importCsv($filePath) 引数には、"~\app\tmp\importer_5757aff3eb9b38.84968690_sample.csv"が入る
(1)$this->options['beforeImport']
★ここで、インポート前の処理ができそう
parseCsvFile()の後に、beforeImportで登録した関数をよびだして、
SAVEしたいファイル内容を加工できそう
(2)$this->parseCsvFile($this->model, $filePath);
設定にあわせてCSVファイルのよみこみ+解析
$csvData[]に1ぎょうずつ格納
$csvData[*行目]['data'][0]
$csvData[*行目]['data'][1]・・・
に、区切り文字でわけた情報を格納
$csvData[*行目]['line']に、1行分(1レコード分)のデータを設定
$options = array(
'csvEncoding' => 'auto', // CSVの文字コードは何か?
'hasHeader' => true, // ヘッダはあるか?
// 'skipHeaderCount' => 1, // ヘッダの行は何行か?
'delimiter' => 'auto', // 区切り文字は何か?
'enclosure' => '"', // 囲み文字は何か?
'saveMethod' => array($this->Post, 'saveWithTimestamp'),
'forceImport' => false, // 問題のない行だけはそのままsaveするか/1行でも問題があれば全てrollbackするか?
'allowExtension' => array('csv', 'txt', 'tsv', 'CSV', 'TXT', 'TSV'), // 許可するファイル拡張子は何か?
// 'parseLimit' => false, // インポート上限はどれくらいか?
)
(3)importFieldsに設定したフィールド数と、csvのフィールド数が一致していなければエラー
(4)importFieldsに設定したカラム名をKeyに、CSVのデータをデータにした連想配列を作成
$data[$this->model->alias] = array_combine($this->fields, $value['data']);
★$this->model->alias には、'Post'となっているため、SAVE先のモデル名が格納されている。
そのため、1度に複数のテーブルを設定できる仕組みにはなっていない。
(5)登録した保存メソッドを呼び出し,データベースに保存
saveWithTimestamp()
ここで、データを付け加えたりすることができる。
$this->fields
アップロードするための処理
View@import.ctp
<?php echo $this->Form->create('Post', array('type' => 'file')); ?>
<fieldset>
<legend><?php echo __('Import Posts'); ?></legend>
<?php if (!empty($importValidationErrors)): ?>
<?php foreach($importValidationErrors as $i => $error): ?>
<p>ヘッダを除いて<?php echo $i; ?>行目</p>
<?php pr($error); ?>
<?php endforeach; ?>
<?php endif; ?>
<?php
echo $this->Form->input('csvfile', array('type' => 'file'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
~~~~~~~~~~~~~~~~~~~~~~~~~~
Postした値をうけとる処理
import()@PostsController.php
Call元:$this->Post->importCsv($this->request->data, $options)
中継:public function __call($method, $params) @Model.php
Call先:public function importCsv(Model $model, $data = null, $options = array()){
~~~~~~~~~~~~~~~~~~~~~~~~~~
importCsv()@ImporterBehavior.php
$model->importFields
モデルに設定した、リンクするカラムの情報
// 何列目がどのフィールドか
public $importFields = array(
'title', // 1列目はPost.title
'body', // 2列目はPost.body
);
$model->importFilterArgs;
ファイルを読み込みじにViewで設定した、Postされた値をどこに格納したかを
指定。
Viewで、
$this->Form->create('Post', array('type' => 'file'));
$this->Form->input('csvfile', array('type' => 'file'));
Postされたデータは、**['Post']['csvfile']としてはいってくる。
そのため、この変数は、
1画面中に複数のPostされた値があるが、インポートしたい値だけを対象にする
ためにこのような仕組みを設けている?
★この仕組みをつかえば、複数のテーブルに対して設定は可能か?
→importCsv()の引数に、Model $modelがあるため、1テーブルに対してしか設定
できないと思われる。
Postされたデータは、
$this->params['form'][パラメーター名]
でとりだすことができる。
どのような値がとれるかは、以下の通り
[name] => ファイル名 "sample.csv"
[type] => ファイルの種類 "application/vnd.ms-excel"
[tmp_name] => アップロードファイルを一時保存したパス "C:\xampp\tmp\phpBFDD.tmp"
[error] => エラーの数 0
[size] => ファイルのサイズ 229
アップロードされたファイルは [tmp_name] のパスに一時ファイルとして保存され、アクションメソッド終了と同時に一時ファイルは削除される。
アクションメソッドの中で一時ファイルを任意の場所にコピーしてやればファイルのアップロード完了
↓一時ファイル格納場所から特定の場所にコピーする処理は↓
$filePath = TMP . uniqid('importer_', true) .'_'. $data[$model->alias][$csvField]['name'];
$filePathには、
"~\app\tmp\importer_5757aff3eb9b38.84968690_sample.csv"に格納される
uniqidとは、マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID を取得
move_uploaded_file($tmpFile, $filePath);
_importCsv($filePath) 引数には、"~\app\tmp\importer_5757aff3eb9b38.84968690_sample.csv"が入る
(1)$this->options['beforeImport']
★ここで、インポート前の処理ができそう
parseCsvFile()の後に、beforeImportで登録した関数をよびだして、
SAVEしたいファイル内容を加工できそう
(2)$this->parseCsvFile($this->model, $filePath);
設定にあわせてCSVファイルのよみこみ+解析
$csvData[]に1ぎょうずつ格納
$csvData[*行目]['data'][0]
$csvData[*行目]['data'][1]・・・
に、区切り文字でわけた情報を格納
$csvData[*行目]['line']に、1行分(1レコード分)のデータを設定
$options = array(
'csvEncoding' => 'auto', // CSVの文字コードは何か?
'hasHeader' => true, // ヘッダはあるか?
// 'skipHeaderCount' => 1, // ヘッダの行は何行か?
'delimiter' => 'auto', // 区切り文字は何か?
'enclosure' => '"', // 囲み文字は何か?
'saveMethod' => array($this->Post, 'saveWithTimestamp'),
'forceImport' => false, // 問題のない行だけはそのままsaveするか/1行でも問題があれば全てrollbackするか?
'allowExtension' => array('csv', 'txt', 'tsv', 'CSV', 'TXT', 'TSV'), // 許可するファイル拡張子は何か?
// 'parseLimit' => false, // インポート上限はどれくらいか?
)
(3)importFieldsに設定したフィールド数と、csvのフィールド数が一致していなければエラー
(4)importFieldsに設定したカラム名をKeyに、CSVのデータをデータにした連想配列を作成
$data[$this->model->alias] = array_combine($this->fields, $value['data']);
★$this->model->alias には、'Post'となっているため、SAVE先のモデル名が格納されている。
そのため、1度に複数のテーブルを設定できる仕組みにはなっていない。
(5)登録した保存メソッドを呼び出し,データベースに保存
saveWithTimestamp()
ここで、データを付け加えたりすることができる。
$this->fields