Подтвердить что ты не робот

CSV для ассоциативного массива

Я видел многочисленные примеры того, как взять файл CSV, а затем создать ассоциативный массив с заголовками в качестве ключей.

Например:

Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664

Где он создаст массив, такой как Array[$num][$key], где $key будет Brand, Model, Part, Test.

Итак, если бы я захотел получить доступ к тестовому значению "434", мне пришлось бы зацикливать каждый индекс в массиве, а затем игнорировать любые бренды, которые не были honda, и любые модели, которые не были Civic


Что мне нужно сделать, так это получить доступ к самому большему числу напрямую, вместо того, чтобы пропустить цикл for, проходящий через каждый индекс $num. Я хочу иметь доступ к тесту значений "434" с помощью:

Array['Honda']['Civic']['135']

или управлять инструкцией for с циклом через каждую модель Honda,... что-то вроде

foreach $model in Array['Honda']

По крайней мере, мне нужно иметь возможность пройти через каждую модель с известным брендом и получить доступ ко всей относительной информации для каждого.

Edit:

Просто чтобы подтвердить, что я приводил пример. Мои фактические данные имеют такие заголовки, как:

brand model part price shipping description footnote

Из чего мне нужно получить доступ ко всей информации, связанной с частью (цена, отправка, по убыванию, сноска)

4b9b3361

Ответ 1

запустите файл csv за строкой и вставьте в массив как:

$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);
}

Ответ 2

Слишком много длинных решений. Я всегда считал это самым простым:

<?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);
    }
?>

Ответ 3

Чтобы создать ассоциативный массив массивов, используйте что-то вроде:

$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), чтобы отфильтровать найденные модели. Другая структура позиционного массива кажется не очень работоспособной, если только вы не хотите получить доступ к атрибуту "Тест".

Ответ 4

Попробуйте этот простой алгоритм:

        $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);

Ответ 5

Вот решения, которые будут работать, указав локальный файл или 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);