tags:

views:

993

answers:

5

I'm trying to read data from a.csv file to ouput it on a webpage as text.

It's the first time I'm doing this and I've run into a nasty little problem.

My .csv file(which gets openened by Excel by default), has multiple rows and I read the entire thing as one long string.

like this:

$contents = file_get_contents("files/data.csv");

In this example file I made, there are 2 lines.

Paul Blueberryroad 85 us Flashlight,Bag November 20, 2008, 4:39 pm

Hellen Blueberryroad 85 us lens13mm,Flashlight,Bag,ExtraBatteries November 20, 2008, 16:41:32

But the string read by PHP is this:

Paul;Blueberryroad 85;us;Flashlight,Bag;November 20, 2008, 4:39 pmHellen;Blueberryroad 85;us;lens13mm,Flashlight,Bag,ExtraBatteries;November 20, 2008, 16:41:32

I'm splitting this with:

list($name[], $street[], $country[], $accessories[], $orderdate[]) = split(";",$contents);

What I want is for $name[] to contain "Paul" and "Hellen" as its contents. And the other arrays to receive the values of their respective columns.

Instead I get only Paul and the content of $orderdate[] is

November 20, 2008, 4:39 pmHellen

So all the rows are concatenated. Can someone show me how i can achieve what I need?

EDIT: solution found, just one werid thing remaining:

I've solved it now by using this piece of code:

$fo = fopen("files/users.csv", "rb+");
while(!feof($fo)) {
  $contents[] = fgetcsv($fo,0,';');
}
fclose($fo);

For some reason, allthough my CSV file only has 2 rows, it returns 2 arrays and 1 boolean. The first 2 are my data arrays and the boolean is 0.

+1  A: 

The file() function reads a file in an array, every line is an entry of the array.

So you can do something like:

$rows = array();
$name = array();
$street = array();
$country = array();

$rows = file("file.csv");
foreach($rows as $r) {
    $data = explode(";", $r);
    $name[] = $data[0];
    $street[] = $data[1];
    $country[] = $data[2];
}
Davide Gualano
+11  A: 

You are better off using fgetcsv() which is aware of CSV file structure and has designated options for handling CSV files. Alternatively, you can use str_getcsv() on the contents of the file instead.

Eran Galperin
A: 

The remark about fgetcsv is correct.

I will still answer your question, for educational purpose. First thing, I don't understand the difference between your data (with comas) and the "string read by PHP" (it substitutes some spaces with semi-colon, but not all?). PS.: I looked at the source code of your message, it looks like an odd mix of TSV (tabs) and CSV (coma).

Beside, if you want to go this way, you need to split first the file in lines, then the lines in fields.

PhiLho
"(it substitutes some spaces with semi-colon, but not all?)"so it would seem. I'm testing with fgetcsv now. There is always a boolean 0 as last element of the returned array.
Vordreller
+1  A: 

I've solved it now by using this piece of code:

$fo = fopen("files/users.csv", "rb+");
while(!feof($fo)) {
  $contents[] = fgetcsv($fo,0,';');
}
fclose($fo);

For some reason, allthough my CSV file only has 2 rows, it returns 2 arrays and 1 boolean. The first 2 are my data arrays and the boolean is 0.

Vordreller
A: 

The best way is of course fgetcsv() as pointed out.

$f = fopen ('test.csv', 'r');
while (false !== $data = fgetcsv($f, 0, ';'))
    $arr[] = $data;
fclose($f);

But if you have the contents in a variable and want to split it, and str_getcsv is unavailable you can use this:

function str_split_csv($text, $seperator = ';') {
    $regex = '#' . preg_quote($seperator) . '|\v#';
    preg_match('|^.*$|m', $text, $firstline);
    $chunks = substr_count($firstline[0], $seperator) + 1;
    $split = array_chunk(preg_split($regex, $text), $chunks);
    $c = count($split) - 1;
    if (isset($split[$c]) && ((count($split[$c]) < $chunks) || (($chunks == 1) && ($split[$c][0] == ''))))
        unset($split[$c]);
    return $split;
}
OIS