Dragen Posted April 9, 2007 Share Posted April 9, 2007 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 More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 file_get_contents() followed by preg_match_all() followed by your foreach loop. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225010 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 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 Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225019 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 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; } Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225025 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 about the fopen... that's a no... file() automaticly reads the whole file into an array over to the error.. what's on on line 21? Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225033 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 $contents = file_get_contents('hours.txt'); $contents = explode("\n\n",trim($contents)); foreach ($contents as $value) echo 'Start: ',substr($value,0,15),echo "\nEnd: ",substr($value,17),"\n"; Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225035 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 hmm... yeah that's a good question... where the hell is that missing ) ?? hehe .. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225046 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 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... Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225063 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 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++; } ?> Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225069 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 but what does $scheFILE look like? I think it has problems with my file because of the blank lines dividing the work blocks. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225074 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 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. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225079 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 $scheFILE = sche/file.txt Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225086 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 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: Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225088 Share on other sites More sharing options...
kenrbnsn Posted April 9, 2007 Share Posted April 9, 2007 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 Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225090 Share on other sites More sharing options...
clown[NOR] Posted April 9, 2007 Share Posted April 9, 2007 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>"; } ?> Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225094 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 Try changing the pattern from /\s{2,}/ to /\s{4,}/. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225100 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 Try changing the pattern from /\s{2,}/ to /\s{4,}/. ah thanks, that worked! Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225109 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 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,}. Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225116 Share on other sites More sharing options...
kenrbnsn Posted April 9, 2007 Share Posted April 9, 2007 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 Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225120 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 thanks for all the help everyone! Just a thought though, if I wanted to seperate the times and dates as two seperate arrays or perhaps just different parts of the same array, how would I do that? Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225270 Share on other sites More sharing options...
kenrbnsn Posted April 9, 2007 Share Posted April 9, 2007 Look at the explode() function. Ken Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225276 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 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]); } Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225282 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 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 Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225365 Share on other sites More sharing options...
Dragen Posted April 9, 2007 Author Share Posted April 9, 2007 actually, I think I've got it now... 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); The \d means number. {4} is the blank line. not sure what the \s+ does though Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225369 Share on other sites More sharing options...
Wildbug Posted April 9, 2007 Share Posted April 9, 2007 \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." Link to comment https://forums.phpfreaks.com/topic/46263-reading-from-flat-file/#findComment-225384 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.