PHP Reading Lines from a Text File - php

I am trying to search a line in a text file and then print the following three lines. For example, if the text file has
1413X
Peter
858-909-9999
123 Apple road
then my PHP file would take in an ID ("1413X") through a form, compare it to lines in the text file - essentially a mock database - and then echo the following three lines. Currently, it is echoing only the phone number (with the second half of the numbers wrong??). Thanks for your help.
<?php
include 'SearchAddrForm.html';
$file = fopen("addrbook.txt", "a+");
$status = false;
$data = '';
if (isset($_POST['UserID']))
{
$iD = $_POST['UserID'];
$contact = "";
rewind($file);
while(!feof($file))
{
if (fgets($file) == $iD)
{
$contact = fgets($file);
$contact += fgets($file);
$contact += fgets($file);
break;
}
}
echo $contact;
}
fclose($file);
?>

It is better to set some flag that you found id and some counter to count lines after it to achieve your aim.
<?php
include 'SearchAddrForm.html';
// $file = fopen("addrbook.txt", "a+");
$file = fopen("addrbook.txt", "r");
$status = false;
$data = '';
if (isset($_POST['UserID']))
{
$iD = $_POST['UserID'];
$contact = "";
rewind($file);
$found = false;
$count = 1;
while (($line = fgets($file)) !== FALSE)
{
if ($count == 3) // you read lines you needed after you found id
break;
if ($found == true)
{
$contact .= $line;
$count++
}
if (trim($line) == $iD)
{
$found = true;
$contact = $line;
}
}
echo $contact;
}
fclose($file);
?>
This kind of example how you can achieve this. And as you see in comment you should use $contact .= value, not $contact += value.
Also instead of reading you can take the whole file in array line by line using function file.
And why are opening file for writing?

What I did:
<?php
//input (string)
$file = "before\n1413X\nPeter\n858-909-9999\n123 Apple road\nafter";
//sorry for the name, couldn't find better
//we give 2 strings to the function: the text we search ($search) and the file ($string)
function returnNextThreeLines($search, $string) {
//didn't do any check to see if the variables are not empty, strings, etc
//turns the string into an array which contains each lines
$array = explode("\n", $string);
foreach ($array as $key => $value) {
//if the text of the line is the one we search
//and if the array contains 3 or more lines after the actual one
if($value == $search AND count($array) >= $key + 3) {
//we return an array containing the next 3 lines
return [
$array[$key + 1],
$array[$key + 2],
$array[$key + 3]
];
}
}
}
//we call the function and show its result
var_dump(returnNextThreeLines('1413X', $file));

Related

(PHP, AJAX) Simple counter. Figured the problem, no solution

Apologies for having to ask.
In short I'm making a simple imageboard with a "like" button for each image. The number of clicks (likes) stores in 'counter.txt' file in the following format:
click-001||15
click-002||7
click-003||10
Clicking the buttons initiates a small php code via AJAX. counter.php:
<?php
$file = 'counter.txt'; // path to text file that stores counts
$fh = fopen($file, 'r+');
$id = $_REQUEST['id']; // posted from page
$lines = '';
while(!feof($fh)){
$line = explode('||', fgets($fh));
$item = trim($line[0]);
$num = trim($line[1]);
if(!empty($item)){
if($item == $id){
$num++; // increment count by 1
echo $num;
}
$lines .= "$item||$num\r\n";
}
}
file_put_contents($file, $lines);
fclose($fh);
?>
So when I run the website and testclick my buttons I get the following message:
Notice: Undefined offset: 1 in C:\wamp64\www\wogue\counter.php on line
18
I figured that the script 'counter.php' creates a whitespace on a new string in 'counter.txt' and so it fails to 'explode' and thus make a [1] index. The way I figured that is by backspacing the last empty line in .txt file and saving it. It ran without errors until I clicked a button a few times then the same error appeared.
The piece of code in index looks like this:
<?php
$clickcount = explode("\n", file_get_contents('counter.txt'));
foreach($clickcount as $line){
$tmp = explode('||', $line);
$count[trim($tmp[0])] = trim($tmp[1]);
}
?>
Any ideas?..
Trim $line and if it is not empty - do what you need:
$line = trim(fgets($fh));
if ($line) {
$line = explode('||', $line);
$item = trim($line[0]);
$num = trim($line[1]);
if(!empty($item)){
if($item == $id){
$num++; // increment count by 1
echo $num;
}
$lines .= "$item||$num\r\n";
}
}
Or check with empty this way:
$line = explode('||', fgets($fh));
if(!empty(line[0]) && !empty($line[1])){
if(line[0] == $id){
$line[1]++; // increment count by 1
echo $line[1];
}
$lines .= "{$line[0]}||{$line[1]}\r\n";
}
}
You are writing using \r\n as a line separator in counter.php and reading the same file exploding only for \n. You should be consistent.
Just removing the \n should be enough to avoid the extra "space" you're seeing.
<?php
$file = 'counter.txt'; // path to text file that stores counts
$fh = fopen($file, 'r+');
$id = $_REQUEST['id']; // posted from page
$lines = '';
while(!feof($fh)){
$line = explode('||', fgets($fh));
$item = trim($line[0]);
$num = trim($line[1]);
if(!empty($item)){
if($item == $id){
$num++; // increment count by 1
echo $num;
}
$lines .= "$item||$num\n"; //removing the \r here
}
}
file_put_contents($file, $lines);
fclose($fh);
?>

PHP Add or Edit line in text File

I'm trying to search a text file, if a line contains a specific key ID I want to update the entire line, if not add a new line.
So based on this text file :
admin,1234,ID1345,NW
staff,1325,ID1001,NE
staff,2157,ID2003,SW
staff,8519,ID3001,NS
I want to search for ID1345 and then update that line only, the other lines stay exactly as they are. If no lines contain ID1345 then add a new line to the text file.
So far I've got:
$search = 'ID1345';
$result = 'admin,6698,ID1345,OP';
$reading = fopen('myfile', 'r');
$writing = fopen('myfile.tmp', 'w');
$replaced = false;
while (!feof($reading)) {
$line = fgets($reading);
if (stristr($line, $search)) {
$line = "$result\n";
$replaced = true;
}
fputs($writing, $line);
}
if (!$replaced) fputs($writing, "$result\n");
fclose($reading); fclose($writing);
rename('myfile.tmp', 'myfile');
This seems to work for the find and replace, but if the line doesn't exist it keeps adding it not just once.
I know this is due to the if (!$replaced) line, but I'm not sure how to do this.
The example above is small, but there could be a few thousand entries in the file..
Thanks
function file_properties($fileProperties) {
$result = array();
$lines = split("\n", $fileProperties);
$key = "";
$isWaitingOtherLine = false;
foreach($lines as $i=>$line) {
if(empty($line) || (!$isWaitingOtherLine && strpos($line,"#") === 0)) continue;
if(!$isWaitingOtherLine) {
$key = substr($line,0,strpos($line,'='));
$value = substr($line,strpos($line,'=') + 1, strlen($line));
} else {
$value .= $line;
}
/* Check if ends with single '\' */
if(strrpos($value,"\\") === strlen($value)-strlen("\\")) {
$value = substr($value, 0, strlen($value)-1)."\n";
$isWaitingOtherLine = true;
} else {
$isWaitingOtherLine = false;
}
$result[$key] = $value;
unset($lines[$i]);
}
return $result;
}
This will read and write values to file with any extension like .env in Laravel or anything *.properties in Java

Group all lines with the same word in first column in csv

I have two columns in my csv file: first_column and second_column. I would like to group all the rows in second column into one string separated by "," if they all have the same word in the first column then output them into a text file.
first_column second_column
a Chris
a Jake
a Paula
b Anita
b Lionel
b Sheila
Desired output
a: Chris, Jake, Paula
b: Anita, Lionel, Sheila
This is what I tried. I seem to be only getting the first letter from the second_column. Any pointers would be great.
$csv_file = fopen("test.csv", "r");
$text_file = fopen("test.txt","w");
$data = array();
if ($csv_file)
{
while (($line = fgets($csv_file)) !== false)
{
$column_1 = $line[0];
$column_2 = $line[1];
if (!empty($column_1))
{
$data [$column_1] = column_2;
}
}
fclose($csv_file);
fclose($text_file);
}
else
{
// error opening the file.
}
//print_r($data);
This should work for you:
Here I first get your .csv file into an array with file(). Then I loop through each line and create an array, where the first column is the key and the second column a value of the sub array.
After this you can loop through your created array and implode() each sub array with the key to the expected line which you want. Then you can just save the data with file_put_contents() into your .txt file.
<?php
$csv_file = "test.csv";
$text_file = "test.txt";
$lines = file($csv_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
array_shift($lines);
foreach($lines as $line) {
list($key, $value) = explode(",", $line); //Change your .csv delimiter here, if you use something else than ,
$data[$key][] = $value;
}
foreach($data as $key => $arr)
$content[] = $key . ": " . implode(",", $arr) . PHP_EOL;
file_put_contents($text_file, $content);
?>
Storing result in an data array and then wring it bacj to text file should work.
$csv_file = fopen("test.csv", "r");
$text_file = fopen("test.txt","w");
$data = array();
if ($csv_file)
{
while (($line = fgets($csv_file)) !== false)
{
$column_1 = $line[0];
$column_2 = $line[1];
if (!isset($data[$column_1]))
{
$data[$column_1] = column_2
} else {
$data[$column_1] = $data[$column_1] .',' . $column_2
}
}
foreach($data as $k=>$d ){
fputs($text_file, "$k: $d") ;
}
fclose($csv_file);
fclose($text_file);
}
else
{
// error opening the file.
}

How to update files in PHP

I have some PHP function that requires the line number of a CSV file used as database. Once it has line, it navigates to the specific value that needs to be changed, changes it and rewrites the whole files. Here is my code:
<?php
function update($file, $id, $field, $value)
{
//$id is the line number
$contents = explode("\n", file_get_contents($file));
$fh = fopen($file, "w");
$lines = array();
foreach($contents as $line)
{
if($line == "")
continue;
$fields = explode("|", $line);
if($fields[0] == $id)
{
$line = null;
for($i = 0; $i<count($fields); $i++)
{
if($i == $field)
$fields[$i] = $value;
if($i != count($fields)-1)
$line .= $fields[$i]."|";
else
$line .= $fields[$i];
}
}
$line .= "\n";
fwrite($fh, $line);
}
fclose($fh);
$contents = null;
return true;
}
$id = $_SESSION['id'];
$uid = $_GET['p'];
$myfile = "myfile.txt";
if(update($myfile, 12, 14, "somevalue"))
echo "updated!";
?>
I am unable to find the problem because whenever I run the code, it outputs "updated!" just as it should but when check the file, I find it has not been updated. I do not know why, but it always remains the same! Thanks.
Check that fwrite() is not failing.
Do something like this:
...
$writeSuccess = (fwrite($fh, $line) !== false);
}
fclose($fh);
$contents = null;
return $writeSuccess;
}
...
If it is failing, check that your filesystem permissions are correctly set. The Apache user needs to have write access to whatever file/folder you are writing the file to.
I found out what the problem was.
$id = $_SESSION['id'];
$uid = $_GET['p'];
$myfile = "myfile.txt";
if(update($myfile, 12, 14, "somevalue"))
The line number pointed to the previous line, which made it impossible to update the first line of the file. So all I had to do was
$line ++;

Search through CSV, returning only exact fit value

Again I'm working on a working CSV filter. It will search through about 500 lines of promotional code and return its amount to ajax receiver. The weird thing is, if I only enter 2 letters, instead of searching for exact fit, the php processor would return the result once it has found a value which contains my entered letters! I need it to look for only exact fit of 4-strings value.
Here's my code so far:
<?php
// if data are received via POST, with index of 'test'
if (isset($_POST['test'])) {
$promocodevalid = false;
$file = fopen('test.csv', 'r');
$coupon = array($_POST['test']);
$coupondef = $_POST['test']; // get data
$coupon = array_map('preg_quote', $coupon);
$regex = '/'.implode('|', $coupon).'/i';
while (($line = fgetcsv($file)) !== FALSE) {
list($promocode, $amount) = $line;
if(preg_match($regex, $promocode)) {
$validity = 1;
echo $amount."[BRK]".$promocode."[BRK]".$validity;
$promocodevalid = true;
break;
}
}
if(!$promocodevalid) {
$validity = 0;
echo $amount."[BRK]".$promocode."[BRK]".$validity;
}
}
?>
Try to avoid regexes where they are not needed. Search for str* function you need.
Above code should look like:
if (isset($_POST['test'])) {
$promocodevalid = false;
$file = fopen('test.csv', 'r');
$coupondef = $_POST['test']; // get data
while (($line = fgetcsv($file)) !== FALSE) {
list($promocode, $amount) = $line;
// remove strtolower if you are have lowercase promocode,
// but probably leave a $coupondef lowered.
if(strpos(strtolower($promocode), strtolower($coupondef)) === 0) {
$validity = 1;
echo $amount."[BRK]".$promocode."[BRK]".$validity;
$promocodevalid = true;
break;
}
}
if(!$promocodevalid) {
$validity = 0;
echo $amount."[BRK]".$promocode."[BRK]".$validity;
}
}

Categories