Converting CSV to PHP Array - issue with end line (CR LF) - php

I am converting csv file to an array using code bellow. But, problem is that end of the row is CR LF, and it is not detected, so array has wrong offset. CR LF is ignored and "cells" around it are merged.
How could i rewrite code to detect this row ending and split array correctly ? Or, is there better approach to convert csv to array?
There are some simmilar questions here but i have not found solution to this issue yet.
Thanks.
$fileName ='test.csv';
$csvData = file_get_contents($fileName);
$csvNumColumns = 11;
$csvDelim = ";";
$data = array_chunk(str_getcsv($csvData, $csvDelim), $csvNumColumns);
print_r($data);

Have you tried using fgetcsv()? full info on php.net.
Example usage from php.net
<?php
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
?>

I would avoid str_getcsv() and work with fgetcsv() to avoid dealing with some of the end of line futz.
http://php.net/manual/en/function.fgetcsv.php
if (($handle = fopen("fileName", "r")) !== FALSE) {
while (($data = fgetcsv($handle)) !== FALSE) {
var_dump($data); //array representation of one line of csv...
}
}
fclose($handle);
If you're on a Mac...
Note: If PHP is not properly recognizing the line endings when reading files either on or created by a Macintosh computer, enabling the auto_detect_line_endings run-time configuration option may help resolve the problem.

Related

Removing an extra space from a table content

I am importing a CSV file which contains list of URLS. These URLs are displaying in tabular format to perform some operations. But a space is added to the beginning of url. Because of this the operations I am performing on it fails. So how I can remove that space.When I done print_r() in my controller it shows result as
�https://www.surveygizmo.com
if (($handle = fopen($filename, "r")) !== FALSE)
{
while (($value = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$num = count($value);
for ($c=0; $c < $num; $c++)
{
echo "<pre>";
print_r($value[$c]);
Above a few lines of code. I am getting symbol,� before the content.
How can I remove that? I tried with trim. But still its not working. I need help. Thank you
Try this. I have similar issue and after following tweak it fixed
$col_val = $value[$c];
$final_value = trim($col_val ," \t\n\r\0\x0B\"");
print_r($final_value);

How can I get the total number of rows in a CSV file with PHP?

Using PHP, how can I get the total number of rows that are in a CSV file? I'm using this method but cannot get it to work properly.
if (($fp = fopen("test.csv", "r")) !== FALSE) {
while (($record = fgetcsv($fp)) !== FALSE) {
$row++;
}
echo $row;
}
Create a new file reference using SplFileObject:
$file = new SplFileObject('test.csv', 'r');
Try to seek to the highest Int PHP can handle:
$file->seek(PHP_INT_MAX);
Then actually it will seek to the highest line it could in the file, there is your last line and the last line + 1 is equals to your total lines:
echo $file->key() + 1;
Tricky, but this will avoid you from loading the file contents into memory, which is a very cool thing to do when dealing with really large files.
Here's another option using file() to read the entire file into an array, automatically parsing new lines etc:
$fp = file('test.csv');
echo count($fp);
Also, since PHP5, you can pass in the FILE_SKIP_EMPTY_LINES... to skip empty lines, if you want to:
$fp = file('test.csv', FILE_SKIP_EMPTY_LINES);
Manual: http://php.net/manual/en/function.file.php
Try
$c =0;
$fp = fopen("test.csv","r");
if($fp){
while(!feof($fp)){
$content = fgets($fp);
if($content) $c++;
}
}
fclose($fp);
echo $c;
I know that this is pretty old, but actually I ran into the same question.
As a solution I would assume to use linux specific logic:
$rows = shell_exec('$(/bin/which cat) file.csv | $(/bin/which tr) "\r" "\n" | $(which wc) -l');
NOTE: this only works for linux only and this only should be used if you are 100% certain that your file has no multiline-cells
CSV rows are separated by line breaks. Therefore, split the rows by line breaks, and you will get an array of rows, which is countable.
if (($fp = fopen("test.csv", "r")) !== FALSE) {
$rows = explode("\n", $fp);
$length = count($rows);
echo $length;
}
Note; none of higher-upvoted solutions that count lines in the file are reliable, as they are only counting the lines, not the csv entries (which can contain newline characters)
I'm using a similar solution to op, and it works perfectly, but with op's code the while part can break on empty lines, which is potentially his problem.
So it looks like this (edited op's code)
$rowCount=0;
if (($fp = fopen("test.csv", "r")) !== FALSE) {
while(!feof($fp)) {
$data = fgetcsv($fp , 0 , ',' , '"', '"' );
if(empty($data)) continue; //empty row
$rowCount++;
}
fclose($fp);
}
echo $rowCount;
I find this the most reliable:
$file = new SplFileObject('file.csv', 'r');
$file->setFlags(
SplFileObject::READ_CSV |
SplFileObject::READ_AHEAD |
SplFileObject::SKIP_EMPTY |
SplFileObject::DROP_NEW_LINE
);
$file->seek(PHP_INT_MAX);
$lineCount = $file->key() + 1;
I know this is an old post, but I've been googling this issue, and found that the only problem with the original code was that you need to define $row outside the while loop, like this:
if (($fp = fopen("test.csv", "r")) !== FALSE) {
$row = 1;
while (($record = fgetcsv($fp)) !== FALSE) {
$row++;
}
Just in case it helps someone :)
echo $row;
}
In case you are getting the file from a form
$file = $_FILES['csv']['tmp_name'];
$fp = new SplFileObject($file, 'r');
$fp->seek(PHP_INT_MAX);
echo $fp->key() + 1;
$fp->rewind();
Works like charm!!!!!!!!!!!!!!!!!!
$filename=$_FILES['sel_file']['tmp_name'];
$file=fopen($filename,"r");
$RowCount=0;
while ((fgetcsv($file)) !== FALSE)
{
$RowCount++;
}
echo $RowCount;
fclose($file);

CSV file read fail (PHP )

I am trying to read a CSV file (delimited by commas) but unfortunately, it isn't responding as it ought to. I am not so sure what I am doing wrong here, but I'll paste out the contents of the code and the CSV file both :
$row = 0;
if($handle = fopen("SampleQuizData.csv","r") !== FALSE)
{
// WORKS UNTIL HERE, SO FILE IS BEING READ
while(!feof(handle))
{
$line = fgetcsv($handle, 1024, ",") ;
echo $line[2]; // DOES NOT WORK
}
}
Here is the CSV file: (the emails and names have been changed here to protect the identities of the users)
parijat,something,parijatYkalia#hotmail.com
matthew,durp, mdurpdurp#gmail.com
steve,vai,stevevai#gmail.com
rajni,kanth,rajnikanth#superman.com
it lacks a '$' to the handle variable
while(!feof($handle)){
and not :
while(!feof(handle)){
Give this a try:
<?php
$row = 0;
if (($handle = fopen("SampleQuizData.csv", "r")) !== FALSE)
{
while(!feof($handle))
{
$line = fgetcsv($handle, 1024, ",") ;
echo "$line[2]";
}
}
?>
It's worth a mention but when I was working on CSV exports a few weeks ago, I had weird line ending inconsistencies. So I put this at the top of my php file and it worked splendid.
<?php
ini_set("auto_detect_line_endings", true);
?>

how to import CSV using zend

How do I import CSV files using zend framework? Should I use zend_file_transfer or is there any special class that I have to look into? Also if I use zend_file_transfer is there any special validator for CSV?
you don't have to use any zend libraries to import csv files, you can just use native php functions, take a look at fgetcsv
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
You could also use SplFileObject for reading CSV files.
From the php manual:
<?php
$file = new SplFileObject("animals.csv");
$file->setFlags(SplFileObject::READ_CSV);
foreach ($file as $row) {
list($animal, $class, $legs) = $row;
printf("A %s is a %s with %d legs\n", $animal, $class, $legs);
}
?>
http://php.net/manual/en/splfileobject.fgetcsv.php
There is currently no way to do this with the Zend Framework. How can one be sure?
For example, Zend_Translate supports translation with CSV files, but if you check the the source code of the respective adapter (Zend_Translate_Adapter_Csv), you can verify it uses fgetcsv, and not a specific Zend class. Besides, this CSV adapter comes with the following warning:
Note: Beware that the Csv Adapter has
problems when your Csv files are
encoded differently than the locale
setting of your environment. This is
due to a Bug of PHP itself which will
not be fixed before PHP 6.0
(http://bugs.php.net/bug.php?id=38471).
So you should be aware that the Csv
Adapter due to PHP restrictions is not
locale aware.
which is related with the problems of the fgetcsv function.
Here's a function that reads a csv file and returns an array of items that contain the first two column data values.
This function could read a file of first_name,last_name for example.
function processFile ($filename) {
$rtn = array();
if (($handle = fopen($filename, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$item = array();
$item[] = $data[0];
$item[] = $data[1];
$rtn[] = $item;
}
}
return $rtn;
}

CSV imports; all values is one row

I'm having a problem using a CSV file uploaded via a PHP form. Here is the code:
$row = 1;
if (($handle = fopen($_FILES['csv']['tmp_name'], "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
The only problem is, when I'm interrogating the variable $data it appears the contents of the CSV file is written to one row, rather than multiple rows. As a result, I get an array of 228 column values.
Why is this? Is my PHP script not detecting a new line correctly? If so, is there an option to fix this behaviour?
set the auto_detect_line_endings ini setting to true:
ini_set('auto_detect_line_endings', true);
Most likely problem is the line endings in your source data. Could you make a test CSV file with several columns and rows to confirm or eliminate the data you're testing with?
See also: http://www.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings

Categories