Jump to content

reading from flat file


Dragen

Recommended Posts

Hi,

I'm trying to write a script to calculate my hours for work.

I have a text file with my hours written down as a timestamp..

11:40 01/04/2007
13:30 01/04/2007

19:30 01/04/2007
19:40 01/04/2007

21:10 01/04/2007
00:15 01/04/2007

Basically the first line is my start time the one below is when I finish. Each work block is broken up by an empty line.

I've never tried a file based system before as I've always used databases, but I'm wanting to use a flat file system for this.

How can I take the information from the file?

 

I want it to read as something like:

$start = first line
$end = second line

 

Then I'd have a for each statement I guess.. so

foreach (block of work)
{
  echo "start: " . $start;
  echo "end: " . $end;
}

I'm not sure how to work with flat files so how would I go about reading from it and then defining what parts of the file is what?

Thanks

Link to comment
https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/
Share on other sites

well.. what i would have done first is seperating time and date with something else than a blank space.. maybe using ||

 

then i would use file()

 

$file = file(filename);

 

then i would do something like this this reads every line in the $file array

$work = array();
$i = 0;

foreach($file as $result) {
$i++;
$work[] = $result;
}

 

now you need to separate time from date.

$count = 0;
foreach($count <= $i) {
$workInfo = explode("||", $work)
$workTime = $workInfo[0];
$workDate = $workInfo[1];
$count++;
}

 

but i think it will be a conflict with the blank line.. and i'm not sure on how to bypass it ... but most likely with an if statement inside the last foreach that sais something about "if there's no || in $workInfo, skip it" or something like that.. think this should work

okay, what I've got is this

<?php
$file = file('hours.txt');
$work = array();
$i = 0;

foreach($file as $result) {
$i++;
$work[] = $result;
}

$count = 0;
foreach($count <= $i) {
$workInfo = explode("||", $work);
$workTime = $workInfo[0];
$workDate = $workInfo[1];
$count++;
}
?>

Although I'm recieving this error:

Parse error: parse error, unexpected ')' in /home/fhlinux181/g/gimppro.co.uk/user/htdocs/test/hours.php on line 21

can't find the problem though..

also, using '$file = file('hours.txt');', do I still need to include something like this:

$fp = fopen('hours.txt','r');
if (!$fp) {
echo 'ERROR: Unable to open file.'; exit;
}

line 21 is

foreach($count <= $i) {

 

and wildbug I tried your suggesstion and it outputted the data like this

Start: 11:40 01/04/200
End: 13:30 01/04/2007 19:30 01/04/2007 19:40 01/04/2007 20:00 01/04/2007 20:03 01/04/2007 21:10 01/04/2007 00:15 01/04/2007

It seems to have a problem once it reaches the blank line..

Is there a better way of putting the data into the flat file, so that I can display it easily?

As I've said I've never used flat files before, so I just wrote my txt file how I thought easy to read...

hmm... weird... i'm using the exact same code for my calendar script... to grab entries for selected date...

 

this is my exact code (copy/paste):

<?php
			$file = file("$scheFILE");
			$i = 0;
			$sche = array();
			foreach ($file as $result) {
				$i++;
				$sche[] = $result;
			}
			$cnt = 0;
			while ($cnt < $i) {
				$schInfo = explode("||", $sche[$cnt]);
				$schTime = $schInfo[0];
				$schTitle = $schInfo[1];
				$schMessage = $schInfo[2];
				echo $schTime." :: ".$schTitle."<br>";
				echo $schMessage."<hr size=1 color=#000000>";
				$cnt++;
			}
?>

Ah, damn.  I didn't test it.  It's possible that it's a DOS file and has \r\n instead of \n or that there's more whitespace on that blank line.  Perhaps you could use preg_split('/\s{2,}/',$contents) instead of explode (or {4,} if \r\n, maybe).

 

If you've been careful about entering your data, i.e., consistent, then it should be no trouble to parse it automatically, whatever method you end up using.

My file is just a .txt file. There is no whitespace on the blank lines except the actual existence of the blank line itself.. no spaces etc.

 

I've now got the code as:

<?php
$contents = file_get_contents('hours.txt');
$contents = preg_split('/\s{2,}/',$contents);
foreach ($contents as $value) {
echo "<p align=\"left\">Start: " . substr($value,0,16);
echo "<br />End: " . substr($value,17) . "</p>";
}
?>

which works to an extent.

For some reason it outputs everythings as start, and I get nothing for end.

Start: 11:40 01/04/2007
End:

Start: 13:30 01/04/2007
End:

Start: 19:30 01/04/2007 // this should be under the end above
End:

Start: 19:40 01/04/2007
End:

Start: 20:00 01/04/2007
End:

Start: 20:03 01/04/2007
End:

Start: 21:10 01/04/2007
End:

Start: 00:15 01/04/2007
End: 

Here is some basic code that should help you on your way:

<?php
$ts = file('timesheet.txt');
for ($i=0;$i<count($ts);$i += 3) {
$tmp = array();
$tmp[] = 'Start: ' . trim($ts[$i]);
$tmp[] = 'End: ' . trim($ts[$i+1]);
echo implode('<br>', $tmp) . '<br><br>';
}
?>

 

Ken

this should work

 

<?php
$contents = file_get_contents('hours.txt');
$contents = preg_split('/\s{2,}/',$contents);
$value = array();
foreach ($contents as $value) {
echo "<p align=\"left\">Start: " . substr($value[0],0,16);
echo "<br />End: " . substr($value[1],17) . "</p>";
}
?>

I'm glad that worked; I was almost out of ideas  :-)

 

Your file is probably a DOS (Windows) format which uses two characters to indicate a carriage return (\r\n) whereas UNIX uses just the one (\n - newline), so the whitespace pattern indicator (\s) will match at each of these -- \r and \n.  To break at the blank lines I was assuming a double space -- \n\n, but it was really \r\n\r\n.  Thus, \s{4,} is needed instead of \s{2,}.

That's one of reasons to use the trim() function. It will remove the newline character from the end of a line whether the new line character consists of "\n", "\r\n", or "\r". If you use the trim() function, your code is portable across different OS's.

 

Ken

You could use substr() since you have a nice, even, zero-padded format.  I like regular expressions, though, so I might jump right to that.  In fact, you could replace the previous code we've discussed with a preg_match_all() like so:

 

$contents = file_get_contents('hours.txt');
preg_match_all('|(\d\d:\d\d) (\d\d/\d\d/\d{4})\s+(\d\d:\d\d) (\d\d/\d\d/\d{4})|',$contents,$matches,PREG_SET_ORDER);
foreach ($matches as $value) {
printf("Start time: %s\nStart date: %s\n End time: %s\n End date: %s\n\n",
	$value[1],$value[2],$value[3],$value[4]);
}

thanks. That works.. could you please explain to me what this actually means?

preg_match_all('|(\d\d:\d\d) (\d\d/\d\d/\d{4})\s+(\d\d:\d\d) (\d\d/\d\d/\d{4})|',$contents,$matches,PREG_SET_ORDER);

I can't quite figure it out and if I'm told what it means then I can learn from it easier.

thanks

\d is a numerical digit, same as the character class [0-9]

{4} is a quantifier.  \d{4} means "four digits" (the year).  It's equivalent to \d\d\d\d, but takes less space.

\s+ means "one or more whitespace characters."  \s is a whitespace character -- tab, space, return, both \r and \n.  The plus sign is also a quantifier, meaning "one or more."  This matches the line break between the start and end timestamps.

The parentheses, in this case, capture the subpatterns for inclusion in the $matches array.

 

More on quantifiers (not all relevant to the preceeding pattern):

 

* means "zero or more," same as {0,}.

? means "zero or one," same as {0,1} (Edit: forgot this one.)

+ means "one or more," same as {1,}.

{5,10} means "from five to ten occurences."

{,50} means "a maximum of 50 occurences (including zero)."

{50,} means "at least 50 occurences."

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.