What is wrong with my fopen() PHP - php

I've got this variable which I want to save which is:
$counter = $counter['counter']++;
to make it so that it increments when I refresh the page.
Therefore, I decided to use the fopen, override the $counter variable and then save it.
I am still a beginner and I do not know how the fopen, fgets, fclose works.
So I wrote something like this.
$fp = fopen("file.php","r");
fwrite($fp, $counter);
fclose($fp);
So I wanted to open the file(file.php)(the file which is I am writing this code FYI), and then override the variable after it had been incremented and then save it by closing.
But the code doesn't seem to want to work and the variable does not seem to want to increment.
What am I doing wrong?
Do I want to have this $counter in a different file and pull the variable from there.
FYI: I don't want to use session_start() and $_SESSION because I am using cron job and it will not work.
EDIT
$result = mysql_query('SELECT MIN(ID) AS min, MAX(ID) AS max FROM ytable') or exit(mysql_error());
$row = mysql_fetch_assoc($result);
if($counter['counter'] < $row['max']){
if (isset($counter['counter'])){
$counter = $counter['counter']++;
}else{
$counter = $counter['counter'] = 0;
}
}
This is more of the code for those who are confused

You could read file like this. Open the file with previous counter & fetch the counter, increment it like this
$counter = readfile("file.php");
$counter++;
To write to the file, open the file in write mode like this
$fp = fopen("file.php","w");
fwrite($fp, $counter);
fclose($fp);
Is that result you are looking for ?
As chris85 suggested, database is used for this kind of cases. Better to use database instead of file handling.

So say you have file.txt and that contains 5. In that same directory you have script.php; this file would have
$counter = file_get_contents('file.txt'); // this takes in whatever value is in the file e.g in this case '5'
$counter++; // increment the value by 1 so we are now at 6
file_put_contents('file.txt', $counter); //write the value '6' back to the file
file.txt would then have 6, after the first load.

Related

PHP File Handling (Download Counter) Reading file data as a number, writing it as that plus 1

I'm trying to make a download counter in a website for a video game in PHP, but for some reason, instead of incrementing the contents of the downloadcount.txt file by 1, it takes the number, increments it, and appends it to the end of the file. How could I just make it replace the file contents instead of appending it?
Here's the source:
<?php
ob_start();
$newURL = 'versions/v1.0.0aplha/Dungeon1UP.zip';
//header('Location: '.$newURL);
//increment download counter
$file = fopen("downloadcount.txt", "w+") or die("Unable to open file!");
$content = fread($file,filesize("downloadcount.txt"));
echo $content;
$output = (int) $content + 1;
//$output = 'test';
fwrite($file, $output);
fclose($file);
ob_end_flush();
?>
The number in the file is supposed to increase by one every time, but instead, it gives me numbers like this: 101110121011101310111012101110149.2233720368548E+189.2233720368548E+189.2233720368548E+18
As correctly pointed out in one of the comments, for your specific case you can use fseek ( $file, 0 ) right before writing, such as:
fseek ( $file, 0 );
fwrite($file, $output);
Or even simpler you can rewind($file) before writing, this will ensure that the next write happens at byte 0 - ie the start of the file.
The reason why the file gets appended it is because you're opening the file in append and truncate mode, that is "w+". You have to open it in readwrite mode in case you do not want to reset the contents, just "r+" on your fopen, such as:
fopen("downloadcount.txt", "r+")
Just make sure the file exists before writing!
Please see fopen modes here:
https://www.php.net/manual/en/function.fopen.php
And working code here:
https://bpaste.net/show/iasj
It will be much simpler to use file_get_contents/file_put_contents:
// update with more precise path to file:
$content = file_get_contents(__DIR__ . "/downloadcount.txt");
echo $content;
$output = (int) $content + 1;
// by default `file_put_contents` overwrites file content
file_put_contents(__DIR__ . "/downloadcount.txt", $output);
That appending should just be a typecasting problem, but I would not encourage you to handle counts the file way. In order to count the number of downloads for a file, it's better to make a database update of a row using transactions to handle concurrency properly, as doing it the file way could compromise accuracy.
You can get the content, check if the file has data. If not initialise to 0 and then just replace the content.
$fileContent = file_get_contents("downloadcount.txt");
$content = (!empty($fileContent) ? $fileContent : 0);
$content++;
file_put_contents('downloadcount.txt', $content);
Check $str or directly content inside the file

add the contents of 2 txt files together

I have this small piece of code on my website that i use to count downloads.
its pretty simple really,
counter.php sends the command and counter.txt is just a 1 line text file with a number that auto goes up every time the link is clicked.
My question is, is it possible to have 2 counter.txt files and add them to a third counter.txt file? so it would look something like:
counter.txt + counter2.txt = counter3.txt ?
$counter = 'counter.txt';
$download = 'downloadurlhere';
$number = file_get_contents($counter); // read count file
$number++; // increment count by 1
$fh = fopen($counter, 'w'); // open count file for writing
fwrite($fh, $number); // write new count to count file
fclose($fh); // close count file
header("Location: $download"); // get download
So essentially i want to offer 2 downloads
a light version and a full version
and then keep track of each download count separately. but then also have a count for the total of both downloads.
oh and to make sure i include enough detail, on the download.php page i echo the counter.txt file with
<?php echo file_get_contents('counter.txt');?>
Adding the counters of two files should be easy. You just have to read each file and then the variables are added and written to third counter file or whatever you desire. An example:
<?php
$first=file_get_contents("counter1.txt");
$second=file_get_contents("counter2.txt");
$sum=$first+$second;
file_put_contents("counter3.txt",$sum);
?>
So here was the end result, I had to swap around the txt files for counter.txt and urls but this worked perfectly...
$count = 'counterfull.txt';
$total = 'total.txt';
$download = 'URL';
$number1 = file_get_contents($count);
$number1++;
$fh = fopen($count, w);
fwrite($fh, $number1);
fclose($fh);
$number2 = file_get_contents($total);
$number2++;
$fh = fopen($total, w);
fwrite($fh, $number2);
fclose($fh);
header("Location: $download");

replacing a single line of a .txt file using php

I am trying to use a php call through AJAX to replace a single line of a .txt file, in which I store user-specific information. The problem is that if I use fwrite once getting to the correct line, it leaves any previous information which is longer than the replacement information untouched at the end. Is there an easy way to clear a single line in a .txt file with php that I can call first?
Example of what is happening - let's say I'm storing favorite composer, and a user has "Beethoven" in their .txt file, and want's to change it to "Mozart", when I used fwrite over "Beethoven" with "Mozart", I am getting "Mozartven" as the new line. I am using "r+" in the fopen call, as I only want to replace a single line at a time.
If this configuration data doesn't need to be made available to non-PHP apps, consider using var_export() instead. It's basically var_dump/print_r, but outputs the variable as parseable PHP code. This'd reduce your code to:
include('config.php');
$CONFIG['musician'] = 'Mozart';
file_put_contents('config.php', '<?php $CONFIG = ' . var_export($CONFIG, true));
This is a code I've wrote some time ago to delete line from the file, it have to be modified. Also, it will work correctly if the new line is shorter than the old one, for longer lines heavy modification will be required.
The key is the second while loop, in which all contents of the file after the change is being rewritten in the correct position in the file.
<?php
$size = filesize('test.txt');
$file = fopen('test.txt', 'r+');
$lineToDelete = 3;
$counter = 1;
while ($counter < $lineToDelete) {
fgets($file); // skip
$counter++;
}
$position = ftell($file);
$lineToRemove = fgets($file);
$bufferSize = strlen($lineToRemove);
while ($newLine = fread($file, $bufferSize)) {
fseek($file, $position, SEEK_SET);
fwrite($file, $newLine);
$position = ftell($file);
fseek($file, $bufferSize, SEEK_CUR);
}
ftruncate($file, $size - $bufferSize);
echo 'Done';
fclose($file);
?>

File reading, searching and looping problems

So i've been trying to write this little piece of code to read a file (status.txt), search it for 1 of 4 keywords and loop until either time runs out (5 minutes) or it finds one of the words. I've already written a few simple php scripts to write the words to a txt file, but I can't seem to get this part to work. It either doesn't clear the file in the beginning or seems to hang and never picks up the changes. Any advice would be hugely helpful.
<?php
//Variables
$stringG = "green";
$stringR = "red";
$stringB = "blue";
$stringO = "orange";
$clear = "";
$statusFile = "status.txt";
//erase file
$fh = fopen($statusFile, 'w'); //clear the file with "clear"
fwrite($fh, $clear);
fclose($fh);
//Insert LOOP
$counter = 0;
while ( $counter <= 10 ) {
//echo "loop begun";
// Read THE FILE
$fh = fopen($statusFile, 'r');
$data = fread($fh, filesize($statusFile));
fclose($fh);
//process the file
if(stristr($data,$stringG)) {
echo "Green!";
$counter = $counter + 30; //stop if triggered
}
elseif (stristr($data,$stringR)) {
echo "Red";
$counter = $counter + 30; //stop if triggered
}
elseif (stristr($data,$stringB)) {
echo "Blue";
$counter = $counter + 30; //stop if triggered
}
elseif (stristr($data,$stringO)) {
echo "Orange";
$counter = $counter + 30; //stop if triggered
}
else {
//increment loop counter
$counter = $counter + 1;
//Insert pause
sleep(10);
}
}
?>
You should open the file before your read loop, and close it after the loop. As in :
open the file
loop through the lines in the file
close the file
Also, if you clear the file before you read it, isn't it going to be empty every time?
Well, first of all, you don't need to "clear" the file this way... The "w" option in fopen will already do that for you.
Also, I wouldn't try to read the whole file at once, because, if it's very large, that won't work without intense memory usage.
What you should do is read the file sequentially, which means you always read a fixed amount of bytes and look for the keywords. To avoid losing keywords which are cut in half by your reading mechanism, you could make your reads overlay a bit (the length of your longest keyword-1), to solve that problem.
Then you should modify your while loop so that it also checks if you are at the end of the file ( while(!feof($fh)) ).
PS: It has been mentioned that you clear your file before reading it. What I understood is that your file gets a lot of input really fast, so you expect it to already have content again when you reopen it. If that's not the case, you really need to rethink your logic ;)
PPS: You don't need to abort your while loop by incrementing your counter variable past the boundaries you define. You can also use the break-keyword.
You haven't included the code which deletes the file in the while loop, so it only clears the file once. Also, I'd use unlink($statusFile); to delete the file.
You should rather use for cycle. And to your problem - you clear the file, then get the data from it. Try dumping this $data, you'll end up with string(0) "" for sure. First, save the data, then clear the file.
Edit: If you are changing the file in the loop itself in another thread, there's another problem. You should look after anatomic file stream. For example, you can use Nette SafeStream class.

Is there a function that can read a php function post-parsing?

I've got a php file echoing hashes from a MySQL database. This is necessary for a remote program I'm using, but at the same time I need my other php script opening and checking it for specified strings POST parsing. If it checks for the string pre-parsing, it'll just get the MySQL query rather than the strings to look for.
I'm not sure if any functions do this. Does fopen() read the file prior to parsing? or file_get_contents()?
If so, is there a function that'll read the file after the php and mysql code runs?
The file with the hashes query and echo is in the same directory as the php file reading it, if that makes a difference.
Perhaps fopen reads it post-parse, and I've done something wrong, but at first I was storing the hashes directly in the file, and it was working fine. After I changed it to echo the contents of the MySQL table, it bugged out.
The MySQL Query script:
$query="SELECT * FROM list";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
echo $row['hash']."<br>";
}
What I was using to get the hash from this script before, when it was just a list of hashes:
$myFile = "hashes.php";
$fh = fopen($myFile, 'r');
$theData = fread($fh, filesize($myFile));
fclose($fh);
$mystring = $theData;
$findme = $hash;
$pos = strpos($mystring, $findme);
The easiest thing to do would be to modify your first php file which echoes everything, along these lines:
change every instance of echo to e.g. $data[] =
at the bottom, do foreach($data as $d) echo $d (this will produce the same result as you have right now)
you now still have your $data array which you can loop through and do whatever you like with it.
To provide working code examples, it would be great if you could post the current code of your file.
EDIT
If you change your script like so:
$query="SELECT * FROM list";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
$data[] = $row['hash']."<br />";
}
foreach($data as $d) {
echo $d;
}
...you'll have the array $data that contains each hash in a key. You can then loop through this array like so:
foreach($data as $d) {
//do something
}

Categories