PHP - Notice Undefined offset - php

I have an issue in my php script which I don't understand. I know there are several questions regarding this issue but none fits to my issue.
I actually have one input file delimited by tabulation named testfile.txt.
With this txt file, I create a new file named result.txt where I take content of testfile in column 0 and column 7.
When I execute my php script, I get this error:
Notice: Undefined offset: 7
The thing that I don't understand is, my result.txt is well created with data contained in my column 0 and 7 from my testfile.txt. If I do:
echo $dataFromTestFile[7];
I have in output contents in column 7.
So I don't really understand why I have this notice and how to remove it.
Here's my php script:
<?php
if (false !== ($ih = fopen('/opt/lampp/htdocs/ngs/tmp/testfile.txt', 'r'))) {
$oh = fopen('/opt/lampp/htdocs/ngs/tmp/result.txt', 'w');
while (false !== ($dataFromTestFile = fgetcsv($ih,0,"\t"))) {
// this is where I build my new row
$outputData = array($dataFromTestFile[0], $dataFromTestFile[7]);
fputcsv($oh, $outputData);
//echo $dataFromTestFile[7];
}
fclose($ih);
fclose($oh);
}
?>
Sample data of testfile.txt:
Input Errors AccNo Genesymbol Variant Reference Coding Descr. Coding
aaa ddd fdfd dfdf fefefd ref1 fdfdfd fdfdf dfdfde

I suspect this is the line that's causing the error:
$outputData = array($dataFromTestFile[0], $dataFromTestFile[7]);
You are trying to use array elements at specific index without checking if they actually exists.
Also, you are trying to write an array object to the result file, did you mean to create a comma separated value in that file?
Try this:
$source = '/opt/lampp/htdocs/ngs/tmp/testfile.txt';
$result = '/opt/lampp/htdocs/ngs/tmp/result.txt';
if (($handle = fopen($source, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
if (isset($data[0]) && isset($data[7])) {
file_put_contents($result, $data[0] .','. $data[7] ."\r\n");
}
}
fclose($handle);
}
Alternatively, you could write the result as a csv like this also:
$sourceFile = '/opt/lampp/htdocs/ngs/tmp/testfile.txt';
$resultFile = '/opt/lampp/htdocs/ngs/tmp/result.txt';
$resultData = array();
// Parse source file
if (($handle = fopen($sourceFile, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
if (isset($data[0]) && isset($data[7])) {
$resultData[] = array($data[0], $data[7]);
}
}
fclose($handle);
}
// Write result file
if (sizeof($resultData)) {
$h = #fopen($resultFile, 'w');
if (!$h) {
exit('Failed to open result file for writing.');
}
foreach ($resultData as $resultRow) {
fputcsv($h, $resultRow, ',', '"');
}
fclose($h);
}

make sure the column 7 exists in your testfile.txt - i guess when starting from zero it may be column number 6 - also you can
var_dump($dataFromTestFile)
in order to get the content of the variable - array keys and values might be of interest for your issue

Related

Modify a csv file line by line

I have a big file that I want to modify every line in it.
I want to use PHP to do it quickly :
My file is CSV file ;
20010103,02,00,00,0.9496
20010103,03,00,00,0.9504
20010103,04,00,00,0.9499
I want to make it like this to be able to use it late with Highchart:
[Date.UTC(2001,01,03,02,00,00),0.9496],
[Date.UTC(2001,01,03,03,00,00),0.9504],
[Date.UTC(2001,01,03,04,00,00),0.9499],
How canI loop every line and make this modification ?
See the fgetcsv and fputcsv PHP functions. It will basically be something like:
if (($handle1 = fopen("input.csv", "r")) !== FALSE) {
if (($handle2 = fopen("output.csv", "w")) !== FALSE) {
while (($data = fgetcsv($handle1, 1000, ",")) !== FALSE) {
// Alter your data
$data[0] = '...';
// Write back to CSV format
fputcsv($handle2, $data);
}
fclose($handle2);
}
fclose($handle1);
}
Try this code:
<?php
$filename = 'info.csv';
$contents = file($filename);
foreach($contents as $line) {
$data = explode(",",$line);
$val = "[Date.UTC(".substr($data[0],0,4).",".(substr($data[0],4,2)).",".substr($data[0],6,2).",".$data[1].",".$data[2].",".$data[3]."),".$data[4]."],";
}
?>

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

Replace a particular line in a text file using php?

I have a text file that stores lastname, first name, address, state, etc as a string with a | delimiter and each record on a separate line.
I have the part where I need to store each record on a new line and its working fine; however, now I need to be able to go back and update the name or address on a particular line and I can't get it to work.
This how to replace a particular line in a text file using php? helped me here but I am not quite there yet. This overwrites the whole file and I lose the records. Any help is appreciated!
After some edit seems to be working now. I am debugging to see if any errors.
$string= implode('|',$contact);
$reading = fopen('contacts.txt', 'r');
$writing = fopen('contacts.tmp', 'w');
$replaced = false;
while (!feof($reading)) {
$line = fgets($reading);
if(stripos($line, $lname) !== FALSE) {
if(stripos($line, $fname) !== FALSE) {
$line = "$string";
$replaced = true;
}
}
fwrite($writing, "$line");
//fputs($writing, $line);
}
fclose($reading); fclose($writing);
// might as well not overwrite the file if we didn't replace anything
if ($replaced)
{
rename('contacts.tmp', 'contacts.txt');
} else {
unlink('contacts.tmp');
}
It seems that you have a file in csv-format. PHP can handle this with fgetcsv() http://php.net/manual/de/function.fgetcsv.php
if (($handle = fopen("contacts.txt", "r")) !== FALSE) {
$data = fgetcsv($handle, 1000, '|')
/* manipulate $data array here */
}
fclose($handle);
So you get an array that you can manipulate. After this you can save the file with fputcsv http://www.php.net/manual/de/function.fputcsv.php
$fp = fopen('contacts.tmp', 'w');
foreach ($data as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
Well, after the comment by Asad, there is another simple answer. Just open the file in Append-mode http://de3.php.net/manual/en/function.fopen.php :
$writing = fopen('contacts.tmp', 'a');

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

Parse CSV file of links to php array, feed these links to simplehtmldom

I have a php code that will read and parse csv files into a multiline array, what i need to do next is to take this array and let simplehtmldom fire off a crawler to return some company stocks info.
The php code for the CSV parser is
$arrCSV = array();
// Opening up the CSV file
if (($handle = fopen("NASDAQ.csv", "r")) !==FALSE) {
// Set the parent array key to 0
$key = 0;
// While there is data available loop through unlimited times (0) using separator (,)
while (($data = fgetcsv($handle, 0, ",")) !==FALSE) {
// Count the total keys in each row $data is the variable for each line of the array
$c = count($data);
//Populate the array
for ($x=0;$x<$c;$x++) {
$arrCSV[$key][$x] = $data[$x];
}
$key++;
} // end while
// Close the CSV file
fclose($handle);
} // end if
echo "<pre>";
echo print_r($arrCSV);
echo "</pre>";
This works great and parses the array line by line, $data being the variable for each line. What i need to do now is to get this to be read via simplehtmldom, which is where it breaks down, im looking at using this code or something very similar, im pretty inexperienced at this but guess i would be needing a foreach statement somewhere along the line.
This is the simplehtmldom code
$html = file_get_html($data);
$html->find('div[class="detailsDataContainerLt"]');
$tickerdetails = ("$es[0]");
$FileHandle2 = fopen($data, 'w') or die("can't open file");
fwrite($FileHandle2, $tickerdetails);
fclose($FileHandle2);
fclose($handle);
So my qyestion is how can i get them both working together, i jave checked out simplehtmldom manual page several times and find it a littlebit vague in this area, the simplehtmldom code above is what i use in another function but by direclty linking so i know that it works.
regards
Martin
Your loop could be reduced to (yes, it's the same):
while ($data = fgetcsv($handle, 0, ',')) {
$arrCSV[] = $data;
}
Using SimpleXML instead of SimpleDom (Since it's standard PHP):
foreach ($arrCSV as $row) {
$xml = simplexml_load_file($row[0]); // Change 0 to the index of the url
$result = $xml->xpath('//div[contains(concat(" ", #class, " "), " detailsDataContainerLt")]');
if ($result->length > 0) {
$file = fopen($row[1], '2'); // Change 1 to the filename you want to write to
if ($file) {
fwrite($file, (string) $result->item(0));
fclose($file);
}
}
}
that should do it if I understood correctly...

Categories