Writing value to file - php

Struggling!
The following code is supposed to take the value from a form, add that value to a value which it reads from data.php then rewrite the new value to data.php
<?php
//get form value
$add_value = $_GET["txt_InterimDonationSubtotal"]; //Will always be a number (10.00, for example)
echo $add_value;
// get contents of a file into a string
$filename = "../assets/files/donation_total/data.php";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
//Say what you got!
echo $contents;
//Get the numbers outta there :) (Will be some kind of number '100.00' for example)
$value = substr($contents, 13);
$value_cleaned = substr($value, 0, -4);
//Add the two numbers together
$new_total = $value_cleaned + $add_value;
//Rewrite the values back to the file
$new_data_content = "<?php $$data=$new_total;?>";
file_put_contents('../assets/files/donation_total/data.php', $new_data_content);
?>
The output does not echo anything, as it should (just for now, I'll remove it when i know it's working), it does write something back to data.php, but not what it should. The following is what I get in data.php when I open it in Sublime:
<?php $=0;?>
As you can see, the name of the variable 'data' is not being saved in the file, and it is not adding the values together! Why?!
Desired output is along the lines of:
<?php $data='125.85';?>
Thanks to the help of people answering I've got this far:
<?php
//get form value
$add_value = $_GET["txt_InterimDonationSubtotal"]; //Will always be a number (10.00, for example)
echo $add_value;
// get contents of a file into a string
$contents = file_get_contents('../assets/files/donation_total/data.php');
//Say what you got!
echo "contents:".$contents;
//Get the numbers outta there :) (Will be some kind of number '100.00' for example)
$value = substr($contents, 13);
$value_cleaned = substr($value, 0, -4);
//Add the two numbers together
$new_total = $value_cleaned + $add_value;
echo "newtotal:".$new_total;
//Rewrite the values back to the file
$new_data_content = "<?php $data='".$new_total."';?>";
file_put_contents('../assets/files/donation_total/data.php', $new_data_content);
?>
This now naming the variable just fine, but the contents are not being read and echoed (why?!) and the values are not being added together, because it's not doing a great job of getting the file contents to being with I'm guessing.

This is because strings with double quotes have variables within them magically interpreted. When PHP sees the string "<?php $$data=$new_total;?>" it says where are the variables $data and $new_total then evaluates those variables within the string. $new_total is a defined variable and its value is written to the string but $data is not so it's value is not.
You could however write your string where it is not evaluated at all using single quotes like this '<?php $$data=$new_total;?>'. However then all the text would be written literally to your file.
What I think you want is to concat the string with the value. '<?php $data="' . $new_total . '";?>'
Did you try serialization?
<?php
$add_value = $_POST["txt_InterimDonationSubtotal"];
$contents = file_get_contents("../assets/files/donation_total/data.txt");
if($contents) {
$contents = unserialize($contents);
} else {
$contents = 0;
}
$contents += $add_value;
file_put_contents('../assets/files/donation_total/data.txt', serialize($contents));
?>

Related

I'm getting wrong result in php code where I have to return the total sum of all the numbers from a file

I have to write a function that return the sum of all the numbers in a file.
The text file is numbers.txt:
1
1
2
3
5
8
13
21
The code I write is:
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while ($number = fgets($file)) {
$total += $number;
}
fclose($file);
return $total;
}
The output should be 54 whereas my output is 124712203354.
Please help me to figure out what I did wrong.
You can use file() for this purpose and simplifiy your code:
$trimmed = file('<provide file path here>', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$sum = array_sum($trimmed);
echo $sum;
In case you added values as string into file then you need to convert them to Integer first.
Add below line before array_sum() line:
$trimmed = array_map('intval', $trimmed);
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while (!feof($file)) { #this will give you a true value until it reaches end of the numbers.txt last line
$total += (int) fgets($file); # this will read file lines one by one
}
fclose($file);
return $total;
}
What happens if you modify your code to be like this:
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while ($number = fgets($file)) {
// Making sure to add integer values here
$total += (int)$number;
}
fclose($file);
return $total;
}
I have the feeling that your number values from your input file are being read in as strings instead of ints. Using something like (int) should be able to help with this type of issue. You could also potentially use (integer) or intval() instead of (int) for the conversion part. More info about this can be found here.
Update:
After seeing CBroe's comment, I removed my earlier part about the string concatenation conjecture.
When checking the sumFromFileInput() function locally and using var_dump($number) to show the $number variable's type, I can verify that it is a string. This is why I still recommend using something like (int), like in my added lines of code earlier in this answer. Without doing that, I get PHP notices in PHP 7.3.19 for these values that read like: PHP Notice: A non well formed numeric value encountered in [...].
Interestingly enough, though, I still get a total of 54 (as an int) with your original posted code. This gets me to thinking: it would be interesting to see the code you used to call your sumFromFileInput() function, because perhaps that might help explain why your output was what now appears to me to be a running sum total of the $total.
Also, this might not be as important, but it looks like your $fileName parameter isn't currently being used in your sumFromFileInput() function. Maybe this could be connected in the future?

Removing A Specific Line From A File

I have a text file like this:
1
2
3
4
5
6
7
8
9
10
And I want to remove specific lines which numbers are in an array like this:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
//wanna remove these lines
So I tried this code but It didn't work and It just doubles the text and ruins everything:
<?php
$myfile='txt.txt';
$remove=array(1,3,5,7,10);
$lines=file($myfile);
$countline=sizeof($lines);
$data=file_get_contents($myfile);
for ($i=0; $i < $countline+1; $i++) {
if (in_array($i, $remove)) {
$editeddata=str_replace($lines[$i], "", $data);
$removeline = file_put_contents($myfile, $editeddata.PHP_EOL , FILE_APPEND | LOCK_EX);
}
}
?>
I couldn't use ((for)) properly and I think it will just ruin the text because it deletes lines one after another have been deleted and it changes the order so I should have a code to remove them all at once.
And please don't give a code to just replace numbers because the main text file is not only numbers and contains word,etc...
Thanks A lot!
You're reading the file twice (with file and file_get_contents), which I think is confusing the later code. You have everything you need with the first call - an array of all the lines in the file. You're also using str_replace to remove the content, which seems a bit dangerous if any of the content is repeated.
I'd refactor this to simply filter the array of lines based on their line-number, then write it back to the file in a single operation:
$myfile = 'txt.txt';
$remove = [1, 3, 5, 7, 10];
// Read file into memory
$lines = file($myfile);
// Filter lines based on line number (+1 because the array is zero-indexed)
$lines = array_filter($lines, function($lineNumber) use ($remove) {
return !in_array($lineNumber + 1, $remove);
}, ARRAY_FILTER_USE_KEY);
// Re-assemble the output (the lines already have a line-break at the end)
$output = implode('', $lines);
// Write back to file
file_put_contents($myfile, $output);
If the file fits in memory then you can do the simple:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
file_put_contents($myfile, implode(PHP_EOL,array_diff($file($myfile,FILE_IGNORE_NEW_LINES), $remove)));
Note: Because it's a bit ambiguous whether $remove has the content or the lines you want to remove, the above code removes the content . If you want to remove lines change array_diff($file($myfile,FILE_IGNORE_NEW_LINES), $remove) to array_diff_keys($file($myfile,FILE_IGNORE_NEW_LINES), array_flip($remove))
If your file is large then you need to resort to some sort of streaming. I suggest against reading and writing to the same file and doing something like:
$myfile='txt.txt';
$remove=array(1,3,6,7,10);
$h = fopen($myfile,"r");
$tmp = fopen($myfile.".tmp", "w");
while (($line = fgets($h)) !== false) {
if (!in_array(rtrim($line, PHP_EOL), $remove)) {
fwrite($tmp, $line);
}
}
fclose($h);
fclose($tmp);
unlink($myfile);
rename($myfile.".tmp", $myfile);

Printing text file contents into columns

I have this text file:
https://drive.google.com/file/d/0B_1cAszh75fYSjNPZFRPb0trOFE/view?usp=sharing
I can print it using the following code:
$file = fopen("gl20160630.txt","r");
while(! feof($file))
{
echo fgets($file). "<br />";
}
fclose($file);
But it looks like this:
I want the contents of this text file to be separated into four columns -Line, Description, Legacy GL Code and Closing Balance. If any one of these columns is empty it should remain empty. I just want to print those lines that start with ====>
Could you please help me find a way to print the text file like the way I want?
It's actually pretty simple, since your file has a strict number of character for each column.
All you need to do is a substr on each line starting by '====>{line}', then you can read each column by there position in the file.
Here is an example using your file :
$file = fopen("gl20160630.txt","r");
while(! feof($file))
{
$fullLine = fgets($file);
$line = substr($fullLine, 5, 4);
if (is_numeric($line)) {
$liability = trim(substr($fullLine, 10, 30));
$legacy = trim(substr($fullLine, 40, 39));
$balance = trim(substr($fullLine, 79, 15));
if ($liability != null && $legacy != null && $balance != null)
echo $line." ".$liability." ".$legacy." ".$balance."\n";
}
}
fclose($file);
You can see that all I do is:
check if the character in the column 'Line' are numbers
then I get all the other element
I 'clean' them by getting rid of unwanted characters (spaces, ...) with trim
After that, I check that all elements are filed
And I finally display them
I hope that this will help you, have a nice day ;)

PHP: Get specific content of a website

I want to get specific content of a website into an array.
I have approx 20 sites to fetch the content and output in other ways i like.Only the port is always changing (not 27015, its than 27016 or so...)
This is just one: SOURCE-URL of Content
For now, i use this code in PHP to fetch the Gameicon "cs.png", but the icon varies in length - so it isn't the best way, or? :-/
$srvip = '148.251.78.214';
$srvlist = array('27015');
foreach ($srvlist as $srvport) {
$source = file_get_contents('http://www.gametracker.com/server_info/'.$srvip.':'.$srvport.'/');
$content = array(
"icon" => substr($source, strpos($source, 'game_icons64')+13, 6),
);
echo $content[icon];
}
Thanks for helping, some days are passed from my last PHP work :P
You just need to look for the first " that comes after the game_icons64 and read up to there.
$srvip = '148.251.78.214';
$srvlist = array('27015');
foreach ($srvlist as $srvport) {
$source = file_get_contents('http://www.gametracker.com/server_info/'.$srvip.':'.$srvport.'/');
// find the position right after game_icons64/
$first_occurance = strpos($source, 'game_icons64')+13;
// find the first occurance of " after game_icons64, where the src ends for the img
$second_occurance = strpos($source, '"', $first_occurance);
$content = array(
// take a substring starting at the end of game_icons64/ and ending just before the src attribute ends
"icon" => substr($source, $first_occurance, $second_occurance-$first_occurance),
);
echo $content['icon'];
}
Also, you had an error because you used [icon] and not ['icon']
Edit to match the second request involving multiple strings
$srvip = '148.251.78.214';
$srvlist = array('27015');
$content_strings = array( );
// the first 2 items are the string you are looking for in your first occurrence and how many chars to skip from that position
// the third is what should be the first char after the string you are looking for, so the first char that will not be copied
// the last item is how you want your array / program to register the string you are reading
$content_strings[] = array('game_icons64', 13, '"', 'icon');
// to add more items to your search, just copy paste the line above and change whatever you need from it
foreach ($srvlist as $srvport) {
$source = file_get_contents('http://www.gametracker.com/server_info/'.$srvip.':'.$srvport.'/');
$content = array();
foreach($content_strings as $k=>$v)
{
$first_occurance = strpos($source, $v[0])+$v[1];
$second_occurance = strpos($source, $v[2], $first_occurance);
$content[$v[3]] = substr($source, $first_occurance, $second_occurance-$first_occurance);
}
print_r($content);
}

How do I choose a specific line from a file?

I'm trying to make (as immature as this sounds) an application online that prints random insults. I have a list that is 140 lines long, and I would like to print one entire line. There is mt_rand(min,max) but when I use that alongside fgets(file, "line") It doesn't give me the line of the random number, it gives me the character. Any help? I have all the code so far below.
<?php
$file = fopen("Insults.txt","r");
echo fgets($file, (mt_rand(1, 140)));
fclose($file);
?>
Try this, it's easier version of what you want to do:
$file = file('Insults.txt');
echo $file[array_rand($file)];
$lines = file("Insults.txt");
echo $lines[array_rand($lines)];
Or within a function:
function random_line($filename) {
$lines = file($filename) ;
return $lines[array_rand($lines)] ;
}
$insult = random_line("Insults.txt");
echo $insult;
use file() for this. it returns an array with the lines of the file:
$lines = file($filename);
$line = mt_rand(0, count($lines));
echo $lines[$line];
First: You totally screwed on using fgets() correctly, please refer to the manual about the meaning of the second parameter (it just plainly not what you think it is).
Second: the file() solution will work... until the filesize exceeds a certain size and exhaust the complete PHP memory. Keep in mind: file() reads the complete file into an array.
You might be better off with reading line-by-line, even if that means you'll have to discard most of the read data.
$fp = fopen(...);
$line = 129;
// read (and ignore) the first 128 lines in the file
$i = 1;
while ($i < $line) {
fgets($fp);
$i++;
}
// at last: this is the line we wanted
$theLine = fgets($fp);
(not tested!)

Categories