Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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];
}

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.

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.

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top