I have a CSV file loaded from an URL, and I want to loop over the lines with PHP.
Here is a typical line of this CSV:
1004000018;active;"TEST1";"TEST2";"TEST3";"TEST4"
I would like to get this result, for each row:
1004000018
active
TEST1
TEST2
TEST3
TEST4
You can achieve this using the php function fgetcsv, this should work :
PHP
$file = fopen('file.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line[0] = '1004000018' in first iteration
print_r($line);
}
fclose($file);
This will help you for read csv:
if (($handle = fopen("$source_file", "r")) !== FALSE) {
$columns = fgetcsv($handle, $max_line_length, $delemietr);
if (!$columns) {
$error['message'] = 'Empty';
return ($error);
}
while (($rows = fgetcsv($handle, 10000, "\t")) !== false) {
if ($rows[1] && array(null) !== $rows) { // ignore blank lines
$data1 = $rows[1];
}
}
}
Related
I have a code where a csv file is uploaded ,the data is extracted from it and uploaded to database.Everything works fine,but how can i skip the empty rows and continue reading the rows with data in it.
This is the code where i extract data from csv file
if (($source = fopen( $csv_file, "r")) !== FALSE)
{
//read data from excel
while (($data = fgetcsv($source, 1000, ",")) !== FALSE)
{
$question=$data[0];
$point=$data[1];
$header=$data[2];
$footer=$data[3];
$type_value=$data[4];
$group_name=$data[5];
echo $question;
}// while end
}
If you use PHP's SplFileObject instead of the basic fgetcsv() function, it has built-in options to skip empty lines:
$file = new SplFileObject($csv_file);
$file->setFlags(SplFileObject::READ_CSV SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
foreach ($file as $data) {
...
}
if ($data[0] == NULL)
continue;
This is because fgetcsv returns a non-empty array with a null element inside.
Try it with
if ($data === null) continue;
I didn't test it, but I sthink it should work.
Try this
if (($source = fopen( $csv_file, "r")) !== FALSE)
{
// read data from excel
while (($data = fgetcsv($source, 1000, ",")) !== FALSE)
{
if ((string) $data[0] != '0' and empty($data[0]))
{
continue;
}
$question = $data[0];
$point = $data[1];
$header = $data[2];
$footer = $data[3];
$type_value = $data[4];
$group_name = $data[5];
echo $question;
}
}
I have a code that works just fine:
if (($handle = fopen("file.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 0, "|")) !== FALSE) {
echo $data[0].$data[1].$data[2]."<br />\n";
}
fclose($handle);
}
But it gets all the contents from file.csv and I want just last x lines. I tried slice method and etc. thanks in advance for your help.
If the command line utility tail is on your PATH, then you can use this snippet:
$x = 3;
if (($handle = popen(sprintf("tail --lines=%d file.csv", $x), "rb")) !== FALSE) {
while (($data = fgetcsv($handle, 0, ";")) !== FALSE) {
echo $data[0].$data[1].$data[2]."<br />\n";
}
fclose($handle);
}
The PHP function fgetcsv will always parse one row at a time.
The following code is what I am using to get an entire column of data from my csv files. (There are many columns, but I only need #2). This code will put all of the data into the array called $cbsmin. What I need to do is skip the very first piece of data in each file as it is the category name not actually a piece of data.
How would this best be done?
for($i=0;$i<count($files);$i++){
if (($handle = fopen($files[$i], "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$cbsmin[] = $data[2];
}
fclose($handle);
}
}
Just use a simple flag to mark if it is the first line. If it is, reset the flag to false and skip that line.
$isfirst = true;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($isfirst)
{
$isfirst = false;
continue;
}
$cbsmin[] = $data[2];
}
Just execute a single
fgetcsv($handle, 1000, ",");
before the while loop.
Just throw in an extra read prior to going into the while loop
for($i=0;$i<count($files);$i++){
if (($handle = fopen($files[$i], "r")) !== FALSE) {
// eat the header
fgetcsv($handle, 1000, ",");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$cbsmin[] = $data[2];
}
fclose($handle);
}
}
Another technique I use for this is to use the header row for keys in the data. This works if the header rows are consistent over time and from file to file.
for($i=0;$i<count($files);$i++){
if (($handle = fopen($files[$i], "r")) !== FALSE) {
// eat the header
$header = fgetcsv($handle, 1000, ",");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$data = array_combine($header, $data);
$cbsmin[] = $data["Customer Name"];
}
fclose($handle);
}
}
It beats having to use field offsets if you are doing anything non-trivial with a lot of the fields.
getHistory downloads a CSV file from Yahoo finance API, i am trying to get the CSV file, and insert the symbol infront of each of the entries in the file. After that is done i want to write the CSV file back to $symbol.csv. My data is the way i want it, i just cant seem to write it to a CSV file. What am i doing wrong? Or is there a better way to go about this?
$row = 1;
if (($handle = fopen(getHistory("T","2010-06-1"), "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
if($row = 1){array_unshift($data,"Symbol"); }
else { array_unshift($data, "T"); }
$fp = fopen('t.csv', 'w');
fputcsv($fp, $data);
fclose($fp);
$row++;
}
}
fclose($handle);
In your loop, you are opening and closing the file on each iteration. You should open the csv file before the loop, add to it, then close it when the loop is done.
Also, you should use === or == for comparisons.
$row = 1;
if (($handle = fopen(getHistory("T","2010-06-1"), "r")) !== FALSE) {
// This truncates the file to zero length
// so, we only need to do this once, before the loop
$fp = fopen('t.csv', 'w');
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
if($row === 1){array_unshift($data,"Symbol"); }
else { array_unshift($data, "T"); }
fputcsv($fp, $data);
$row++;
}
// Close it once we're all done
fclose($fp);
}
fclose($handle);
The test.php directory is the same as csv and text file. now i want to pass all the csv file name and all the text name to the following if condition. namely, replace one.csv with all the csv file name. replace one.txt with all the txt file name.
if (($handle = fopen("one.csv", "r")) !== FALSE && ($handle2 = fopen("one.txt", 'a')) !== FALSE) { ...}
the following is my code. after run the code,i found all the content in the text file are the same. it loops too many times. how to change the code?thank you.
$files = glob("./*.csv");
$files1 = glob("./*.txt");
foreach($files as $filepath){
foreach($files1 as $filepath1){
$row = 1;
if (($handle = fopen("one.csv", "r")) !== FALSE && ($handle2 = fopen("one.txt", 'a')) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if($row > 1) {
$url = $data[8];
foreach($result[0] as $url){
fwrite($handle2, $url."\r\n");
}
}
$row++;
}
fclose($handle);
fclose($handle2);
}
}
}
The txt file is empty. now, i want to read the csv file and extract some content of it then put them into the text file. thank you
You don't need to glob .txt files, just glob csv, and replace the extension .csv by .txt
$csv = glob('./*.csv');
foreach($csv as $file) {
$txt = preg_replace('#\.csv$#', '.txt', $file);
if (($handle = fopen($file, "r")) !== FALSE && ($handle2 = fopen($txt, 'a')) !== FALSE) {
//your code...
}
}
The problem is that you've got a loop within a loop. So every time the first loop loops it's doing everything in the second loop AGAIN.
Try something like this:
$csv_files = glob("./*.csv");
$txt_files = glob("./*.txt");
$csvs = array();
foreach($csv_files as $fp){
$csvs[] = fopen($fp, "r");
}
$txts = array();
foreach($txt_files as $fp){
$txts[] = fopen($fp, "r");
}
var_dump($csvs); // all csv file info
var_dump($txts); // all txt file info
You can test to see !== false in the separate loops if you wish. Otherwise, if you just want to use them then you can loop through the separate arrays and get the info out of them that way.