CSVファイルを取得し、ヘッダーをキーとして連想配列を作成する方法に関する多くの例を見てきました。
例えば:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
Array[$num][$key]
などの配列を作成する場所。$key
は、ブランド、モデル、パーツ、テストです。
したがって、テスト値「434」にアクセスする場合、配列内のすべてのインデックスをループし、ホンダではないブランド、およびシビックではないモデルを無視する必要があります。
私がする必要があるのは、各$ numインデックスを通過するforループを実行する代わりに、最も直接値にアクセスすることです。値テスト「434」にアクセスできるようにしたい:
Array['Honda']['Civic']['135']
またはホンダが持っているすべてのモデルをループしてfor文を制御します...のようなもの
foreach $model in Array['Honda']
少なくとも、既知のブランドが指定されたすべてのモデルを調べて、それぞれのすべての関連情報にアクセスできる必要があります。
編集:
これを確認するために、これを例として設定しました。私の実際のデータには次のようなヘッダーがあります。
brand model part price shipping description footnote
そのうち、部品に関連付けられているすべての情報(価格、配送、説明、脚注)にアクセスする必要があります
csvファイルを1行ずつ実行し、次のように配列に挿入します。
$array = $fields = array(); $i = 0;
$handle = @fopen("file.csv", "r");
if ($handle) {
while (($row = fgetcsv($handle, 4096)) !== false) {
if (empty($fields)) {
$fields = $row;
continue;
}
foreach ($row as $k=>$value) {
$array[$i][$fields[$k]] = $value;
}
$i++;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
長すぎるソリューション。私はこれが最も簡単だといつも思ってきました。
<?php
/* Map Rows and Loop Through Them */
$rows = array_map('str_getcsv', file('file.csv'));
$header = array_shift($rows);
$csv = array();
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
?>
連想リスト配列を作成するには、次のようなものを使用します。
_$keys = fgetcsv($f);
while (!feof($f)) {
$array[] = array_combine($keys, fgetcsv($f));
}
_
また、特定の属性でトラバースおよびフィルタリングするには、次のような関数を記述します。
_function find($find) {
foreach ($array as $row) {
if (array_intersect_assoc($row, $find) == $find) {
$result[] = $row;
}
}
}
_
$find = array(Brand=>Honda, Model=>Civic, Part=>135)
を使用して呼び出し、検索されたモデルを除外する場所。 「Test」属性にのみアクセスする場合を除き、他の位置配列構造はあまり有効ではないようです。
この簡単なアルゴリズムを試してください:
$assocData = array();
if( ($handle = fopen( $importedCSVFile, "r")) !== FALSE) {
$rowCounter = 0;
while (($rowData = fgetcsv($handle, 0, ",")) !== FALSE) {
if( 0 === $rowCounter) {
$headerRecord = $rowData;
} else {
foreach( $rowData as $key => $value) {
$assocData[ $rowCounter - 1][ $headerRecord[ $key] ] = $value;
}
}
$rowCounter++;
}
fclose($handle);
}
var_dump( $assocData);
ローカルファイルまたはURLを指定することで機能するソリューションを次に示します。関連付けのオンとオフを切り替えることもできます。これがお役に立てば幸いです。
class CSVData{
public $file;
public $data;
public $fp;
public $caption=true;
public function CSVData($file=''){
if ($file!='') getData($file);
}
function getData($file){
if (strpos($file, 'tp://')!==false){
copy ($file, '/tmp/csvdata.csv');
if ($this->fp=fopen('/tmp/csvdata.csv', 'r')!==FALSE){
$this->readCSV();
unlink('tmp/csvdata.csv');
}
} else {
$this->fp=fopen($file, 'r');
$this->readCSV();
}
fclose($this->fp);
}
private function readCSV(){
if ($this->caption==true){
if (($captions=fgetcsv($this->fp, 1000, ","))==false) return false;
}
$row=0;
while (($data = fgetcsv($this->fp, 1000, ",")) !== FALSE) {
for ($c=0; $c < count($data); $c++) {
$this->data[$row][$c]=$data[$c];
if ($this->caption==true){
$this->data[$row][$captions[$c]]=$data[$c];
}
}
$row++;
}
}
}
この使用法を試してください:
$o=new CSVData();
$o->getData('/home/site/datafile.csv');
$data=$o->data;
print_r($data);
fgetcsv()
を使用することが、このジョブにとって最も直接的で賢明なツールのようです。
csv.csvの内容:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
コード:
$assoc_array = [];
if (($handle = fopen("csv.csv", "r")) !== false) { // open for reading
if (($data = fgetcsv($handle, 1000, ",")) !== false) { // extract header data
$keys = $data; // save as keys
}
while (($data = fgetcsv($handle, 1000, ",")) !== false) { // loop remaining rows of data
$assoc_array[] = array_combine($keys, $data); // Push associative subarrays
}
fclose($handle); // close when done
}
echo "<pre>";
var_export($assoc_array); // print to screen
echo "</pre>";
出力:
array (
0 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '123',
'Test' => '244',
),
1 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '135',
'Test' => '434',
),
2 =>
array (
'Brand' => 'Toyota',
'Model' => 'Supra',
'Part' => '511',
'Test' => '664',
),
)