php - fputs - CSV a matriz asociativa
php fputcsv delimiter (5)
He visto numerosos ejemplos sobre cómo tomar un archivo CSV y luego crear una matriz asociativa con los encabezados como claves.
Por ejemplo:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
Donde se crearía una matriz como Array[$num][$key]
donde $key
sería Brand, Model, Part, Test.
Por lo tanto, si quisiera acceder al valor de prueba "434", debería realizar un ciclo de todos los índices en la matriz e ignorar las Marcas que no fueron Honda, y cualquier modelo que no sea Civic.
Lo que tengo que hacer es acceder al valor más directamente, en lugar de ejecutar un bucle for pasando por cada índice de $ num. Quiero poder acceder a la prueba de valor "434" con:
Array[''Honda''][''Civic''][''135'']
o controlar un enunciado for con looping a través de cada modelo que Honda tiene ... algo así como
foreach $model in Array[''Honda'']
Por lo menos, necesito poder revisar cada modelo de una marca conocida y acceder a toda la información relativa de cada uno.
Editar:
Solo para confirmar que estaba configurando esto como un ejemplo. Mi información en realidad tiene encabezados como:
brand model part price shipping description footnote
De lo cual necesito acceder a toda la información vinculada a la parte (precio, envío, desc, nota al pie)
Aquí hay una solución que funcionará especificando un archivo local o URL. También puede activar y desactivar la asociación. Espero que esto ayude.
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++;
}
}
}
Prueba este uso:
$o=new CSVData();
$o->getData(''/home/site/datafile.csv'');
$data=$o->data;
print_r($data);
Demasiadas soluciones largas. Siempre he encontrado que esto es lo más simple:
<?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);
}
?>
Ejecuta el archivo csv línea por línea e inserta en una matriz como:
$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);
}
Para crear una matriz de lista asociativa, use algo como:
$keys = fgetcsv($f);
while (!feof($f)) {
$array[] = array_combine($keys, fgetcsv($f));
}
Y para recorrer y filtrar por atributos específicos, escriba una función como:
function find($find) {
foreach ($array as $row) {
if (array_intersect_assoc($row, $find) == $find) {
$result[] = $row;
}
}
}
Donde lo invocaría con $find = array(Brand=>Honda, Model=>Civic, Part=>135)
para filtrar los modelos buscados. La otra estructura de matriz posicional parece poco viable, a menos que solo desee acceder al atributo "Prueba".
Pruebe este algoritmo simple:
$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);