fREAD a text file to count amount of name values - PHP - php

I've created a form which users input numbers into, this data is then being written to a text file using fwrite.
Now my question is, is there a way to read the file in a sense, but only a certain post.. then count up how many of those have occurred, for example...
$data = sprintf("((%s,%s,%s))$s",
$_POST['shapeType'],
$_POST['circleRadius'],
$_POST['circleColour'],
PHP_EOL ); // automatically use the Operating System appropriate new line character sequence.
fwrite($handle, $data); }
fclose($handle);
?>
above is the fwrite, now 'shapeType' is circle on this specific write, is there a way to locate all the shapeType posts (other shapes like square etc..) therefore producing a
There are x amount of Shapes stored within the site.
x obviously replacing the counted amount, any ideas? im quite new to this so it may be impossible altogether.
update!! - what text file looks like
((Circle,120,Red))((Triangle,190,120,90,Blue))
((Circle,90,Blue))((Circle,20,Red))

You can read each line of the file into an array and then loop through that array. While you're looking at each line, just check to see if it matches 'circle' or whatever and if so, increment a counter.
<?php
$shape_type = $_POST['shapeType'];
$shape_counter = 0;
$lines = file($file_name);
foreach ($lines AS $line) {
if (preg_match('/'.$shape_type.'/', $line)) {
$shape_counter++;
}
}
print "There are ".$shape_counter." amount of ".$shape_type."s stored within the site.";
EDIT:
If you're just wanting to get the total number of lines, it's even easier. Just do this:
<?php
$lines = file($file_name);
print "There are ".count($lines)." amount of shapes stored within the site.";

Related

How to delete array in text file PHP

I have a text file. I want to delete some lines with a query of search.
The array is line by line. I want to made it like http://keywordshitter.com/
The logic is,
SEARCH --> IN ARRAY --> OUTPUT IS ARRAY WITHOUT "QUERY OF SEARCH"
Code I have tried:
$fileset = file_get_contents("file.txt");
$line = explode("\n", $fileset);
$content = array_search("query",$line);
print_r($content);
MY file.txt
one
two
three
apple
map
I have used array_search but not working.
you can do search like
$fileset=file("file.txt"); // file function reads entire file into an array
$len=count($fileset);
for($i=0;$i<$len;$i++)
{
if($fileset[$i]=="query")
{
$fileset[$i]="";
break; //then we will stop searching
}
}
$fileset_improve=implode($fileset); //this will again implode your file
$handle=fopen("file.txt","w"); //opening your file in write mode
fwrite($handle,$fileset_improve); //writing file with improved lines
fclose($handle); //closing the opened file
remember this lines will make your search line blank....
if you wanna then you can arrange whole array i.e. shifting following indexed data to previous index to decrease line counts but this will increase your programming complexity.
Hope this will work for you.
Thanks
Use PHP_EOL on your explode function instead of "\n". PHP_EOL will handle the correct line break character(s) of the server platform.

Storing last line of file in an array continuously in PHP

So i have a little issue with some PHP read functionality. What I am trying to do is basically grab data into an array from a file that is being continuously updated from a python script reading values from a micro controller. So basically, the file would look something like this.
ID, Datetime, Count, Name
ID, Datetime, Count, Name
ID, Datetime, Count, Name
What i need is for it to read the new line that is being added in (eof) and store it into an array. So what i have so far is allowing read access into the file
<?php
$myfile = fopen("read.txt", "r")
For the storing the lines in an array i figured something like an array map would be efficient
$result = array();
// some loop
$parts = array_map('trim', explode(':', $line_of_text, 2)));
$result[$parts[0]] = $parts[1];
However i am not to sure on how to structure the loop to have it read the new line that is being updated in the file without exiting the loop.
while (feof($file)) {
}
fclose($file);
?>
Any help would be appreciated!!
Can you do this?
Read the lines of the file to an array using $lines = file("filename");.
Use the $lines[count($lines) - 1] to get the last line?
You can even trim off the empty lines before you wanna do this.
Trim Empty Lines
Use this function:
$lines = array_filter($lines);
Since the file is continually being appended, you'd have to read until you hit the end of file, sleep for a while to let more data be appended, then read again.
e.g.
while(true) {
while(!feof($file)) {
... process data
}
sleep(15); // pause to let more data be appended
}
However, I'm not sure if PHP will cache the fact that it hit eof, and not try again once the sleep() finishes. It may be necessary to record your current position ftell(), close the file, reopen it, then fseek() to the stored location.
I've came up with this solution
$filename = "file.txt";
$file = fopen($filename, "r");
$lines = explode("/n", fread($file, filesize($filename)));
$last = $lines[count($lines)-1];
If the file is going to get big, it could take some time to parse, so its also possible to adjust the fread() function so it only reads the last 100 characters for example.

Reading a log file into an array reversed, is it best method when looking for keyword near the bottom?

I am reading from log files which can be anything from a small log file up to 8-10mb of logs. The typical size would probably be 1mb. Now the key thing is that the keyword im looking for is normally near the end of the document, in probably 95% of the cases. Then i extract 1000 characters after the keyword.
If i use this approach:
$lines = explode("\n",$body);
$reversed = array_reverse($lines);
foreach($reversed AS $line) {
// Search for my keyword
}
Would it be more efficent than using:
$pos = stripos($body,$keyword);
$snippet_pre = substr($body, $pos, 1000);
What i am not sure on is with stripos does it just start searching through the document 1 character at a time so in theory if there is 10,000 characters after the keyword then i wont have to read those into memory, whereas the first option would have to read everything into memory even though it probably only needs the last 100 lines, could i alter it to read 100 lines into memory, then search another 101-200 lines if the first 100 was not successful or is the query so light that it doesnt really matter.
I have a 2nd question and this assumes the reverse_array is the best approach, how would i extract the next 1000 characters after i have found the keyword, here is my woeful attempt
$body = $this_is_the_log_content;
$lines = explode("\n",$body);
$reversed = array_reverse($lines);
foreach($reversed AS $line) {
$pos = stripos($line,$keyword);
$snippet_pre = substr($line, $pos, 1000);
}
Why i don't think that will work is because each $line might only be a few hundred characters so would the better solution be to explode it every say 2,000 lines and also keep the previous $line as a backup variable so something like this.
$body = $this_is_the_log_content;
$lines = str_split($body, 2000);
$reversed = array_reverse($lines);
$previous_line = $line;
foreach($reversed AS $line) {
$pos = stripos($line,$keyword);
if ($pos) {
$line = $previous_line . ' ' . $line;
$pos1 = stripos($line,$keyword);
$snippet_pre = substr($line, $pos, 1000);
}
}
Im probably massively over-complicating this?
I would strongly consider using a tool like grep for this. You can call this command line tool from PHP and use it to search the file for the word you are looking for and do things like give you the byte offset of the matching line, give you a matching line plus trailing context lines, etc.
Here is a link to grep manual. http://unixhelp.ed.ac.uk/CGI/man-cgi?grep
Play with the command a bit on the command line to get it the way you want it, then call it from PHP using exec(), passthru(), or similar depending on how you need to capture/display the content.
Alternatively, you can simply fopen() the file with the pointer at the end and move the file pointer forward in the file using fseek() searching for the string as you move along the way. Once you find you needle, you can then read the file from that offset until you get to the end of file or the number of log entries.
Either of these might be preferable to reading the entire log file into memory and then trying to work with it.
The other thing to consider is whether 1000 characters is meaningful. Typically log files would have lines that vary in length. To me it would seem that you should be more concerned about getting the next X lines from the log file, not the next Y characters. What if a line has 2000 characters, are you saying you only want to get half of it? That may not be meaningful at all.

Processing structured data into a database from a giant text file using PHP?

I have text files containing structured data (it is a proprietary format and not something simple or common like CSV). I'm trying to put this data into a database. The text files are as large as 50GB so it's impossible for me to read the entire file into memory, extract it into an array, then process it into the database.
The text files are structured in such a way that data on a particular "item" (a specific id in the database) can have multiple lines (new lines) of information in the text file. Items in the text file always start with a line that begins with '01' and can have an infinite number of additional lines (all one after the other), that will all start with 02 or 03 ... up to 08. A new item begins when a new line starts with 01.
01some_data_about_the_first_item
02some_more_data_about_the_first_item
05more_data_about_the_first_item
01the_first_line_of_the_second_item
I'd like to use PHP to process this data.
How can I load a piece of this text file into memory where I can analyze it, get all the lines for an item, and then process it? Is there a way to load all lines up to the next line that starts with 01, process that data, then begin the next scan of the text file at the end of the last scan?
Processing the data once I've loaded pieces of it into memory is not the problem.
Sure. Since you tagged the question with csv, I'll assume you have a CSV file. In that case, fgetcsv is a good function to use, which get one line from the file at a time. Using that you can get as many lines as you need for one record, then process it, then continue with the next one. Rough mockup:
$fh = fopen('file.csv', 'r');
$record = array();
do {
$line = fgetcsv($fh);
if ($line && $line[0] != '01') {
// any line that does not start with 01 is part of the current record,
// adjust condition as necessary
$record[] = $line;
} else if ($record) {
/* put current $record into database */
// start next record
$record = array($line);
}
} while ($line);
Here is a start:
<?php
$fp=fopen('big.txt','r');
while($line=fgets($fp)){
$number=substr($line,0,2);
$data=substr($line,2);
// proccess each line
echo $number.' - '.$data;
}
fclose($fp);
?>

Read CSV from end to beginning in PHP

I am using PHP to expose vehicle GPS data from a CSV file. This data is captured at least every 30 seconds for over 70 vehicles and includes 19 columns of data. This produces several thousand rows of data and file sizes around 614kb. New data is appended to end of the file. I need to pull out the last row of data for each vehicle, which should represent the most the recent status. I am able to pull out one row for each unit, however since the CSV file is in chronological order I am pulling out the oldest data in the file instead of the newest. Is it possible to read the CSV from the end to the beginning? I have seen some solutions, however they typically involve loading the entire file into memory and then reversing it, this sounds very inefficient. Do I have any other options? Thank you for any advice you can offer.
EDIT: I am using this data to map real-time locations on-the-fly. The data is only provided to me in CSV format, so I think importing into a DB is out of the question.
With fseek you can set the pointer to the end of the file and offset it negative to read a file backwards.
If you must use csv files instead of a database, then perhaps you could read the file line-by-line. This will prevent more than the last line being stored in memory (thanks to the garbage collector).
$handle = #fopen("/path/to/yourfile.csv", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// old values of $last are garbage collected after re-assignment
$last = $line;
// you can perform optional computations on past data here if desired
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
// $last will now contain the last line of the file.
// You may now do whatever with it
}
edit: I did not see the fseek() post. If all you need is the last line, then that is the way to go.

Categories