Counter stored in .txt file not incrementing - php

So I've just now edited the Code I've posted to make it much nicer to read...
This first block of code is my Counter Code used for the hits on a succesfull submition button. But for some reason the value of $Total will not increase by 1 even tho it was a succesfull submition.
<?php
$f = fopen('count.txt', 'r+'); // use 'r+' instead
$total = fgets ($f);
flock($f, LOCK_EX); // avoid race conditions with concurrent requests
$total = (int) fread($f, max(1, filesize('count.txt'))); // arg can't be 0
/*if someone has clicked submit*/
if (isset($_POST['submit'])) {
rewind($f); // move pointer to start of file so we overwrite instead of append
fwrite($f, ++$total);
}
fclose($f);
?>
And here is the submition button which I'm using to submit my form.
<input type="reset" value="Formular löschen" style="width:49%" />
<input type="submit" name="submit" value="Formular absenden" style="width:49%" />
Im trying to use this coed for my Club so that when the People submit the form they get the number as a refference Number also sent to them in the email sent.
I really hope thet there is a eays way of doing this without a DB.
Mark
If you want to see what i mean what the problem is, here is the page with the code impelemented.

First of all a couple of tips you may find useful when you are manipulating files:
You have to always check the files and folders permissions, just to make sure.
Be careful with multi-thread code, you may get really unexpected results when several threads are changing a file at the same time, so try to control that using locks, as you did.
I think you missed you <form> tag, so I had to invent my own one.
Use this code as a guide to make your own one:
<form method="post" action="test.php">
<input type="submit" name="submit" value="Submit" />
</form>
<?php
// Thread-safe <-- Use me
function incrementFile ($file){
$f = fopen($file, "r+") or die("Unable to open file!");
// We get the exclusive lock
if (flock($f, LOCK_EX)) {
$counter = (int) fgets ($f); // Gets the value of the counter
rewind($f); // Moves pointer to the beginning
fwrite($f, ++$counter); // Increments the variable and overwrites it
fclose($f); // Closes the file
flock($fp, LOCK_UN); // Unlocks the file for other uses
}
}
// NO Thread-safe
function incrementFileSimplified ($file){
$counter=file_get_contents('count.txt');
$counter++;
file_put_contents('count.txt', $counter);
}
// Catches the submit
if (isset($_POST['submit'])) {
incrementFile("count.txt");
}
?>
Hope this helps you! :)

This happens because you never set $total before writing it to the file.
You need to set $total by reading its value from the file, like this:
$total = fgets ($f) right after fopen function call.
However, you may have troubles with concurrency without exclusive file lock so you may lose some submissions count.

Related

How to put a submission limit on a form with PHP

I'm trying to create a .php page that contains a form with a submission limit. I'm looking for these steps in order:
User arrives to form
User see's that form is still open
User submits info for form
Form adds +1 to a txt file that will +1 upon every form submission until the txt file reaches the number 10.
If the txt file equals the preset of 10 I would like the form to disappear and allow no more submissions.
I've tried using fopen, and making it work using $limit = fopen("count.txt", "r") but im so confused as to what needs to happen first. The code I'm using are snippets from other php codes I've written and found online. Normally I can figure out things like this as I know its most likely simple.
<?php
$limit = fopen("count.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("count.txt"));
if ($limit = 10){
echo ("Cannot Submit Anymore");}
else{
echo ('<form>
First name:<br>
<input type="text" name="firstname"><br>
Last name:<br>
<input type="text" name="lastname">
</form>');}
fclose($myfile);
$limit = fopen('count.txt', 'c+');
flock($limit, LOCK_EX);
$count = (int)fread($limit, filesize('count.txt'));
ftruncate($limit, 0);
fseek($limit, 0);
fwrite($limit, $count + 1);
flock($limit, LOCK_UN);
fclose($limit);
?>
I'm completely stuck and not sure of the order in which everything needs to be to work.
Figured out what I needed to do, although I don't know if the code is compliant. Anyway, here is what I did:
5 Pages Total:
index.php [Landing Page]
tally.php [PHP code for updating the different txt files]
count.txt [How many seats purchased. In this case it had the number 0 typed into it]
left.txt [How many seats left. In this case it had the number 10 typed into it]
max.txt [How many seats im selling. In this case it had the number 10 typed into it]
index.php [Landing Page]:
<?php
$max = file_get_contents('max.txt');
$limit = file_get_contents('count.txt');
$left = file_get_contents('left.txt');
$maxed = 'Sorry, All Seats Have Been Sold';
if ($limit >= $max){
echo $maxed;}
else{
echo '
<form action="tally.php"> // This form can be edited to your needs
First name:<br><input type="text"><br>
Last name:<br><input type="text">
<input type="submit" value="Submit">
</form>' . 'Seats Remaining:' . $left;}
?>
tally.php [PHP code for updating the different txt files]:
<?php
$limit = fopen("count.txt", "c+");
flock($limit, LOCK_EX);
$count = (int)fread($limit, filesize("count.txt"));
ftruncate($limit, 0);
fseek($limit, 0);
fwrite($limit, $count + 1);
flock($limit, LOCK_UN);
fclose($limit);
$left = fopen("left.txt", "c+");
flock($left, LOCK_EX);
$remaining = (int)fread($left, filesize("left.txt"));
ftruncate($left, 0);
fseek($left, 0);
fwrite($left, $remaining - 1);
flock($left, LOCK_UN);
fclose($left);
header('Location: http://www.yoursite.com/'); // this links back to your submission form
exit;
?>
count.txt [How many seats purchased]:
0
left.txt [How many seats left]
10
max.txt [How many seats im selling]
10
Hope this helps someone in the future, this code throws up tons of error logs when ran on my server that I can see in the backend but it works for me and for what I need. If someone can improve upon this one day I and many others in the future would be very grateful.

Form search save in file & display result

What is the most elegant and efficient way of search a string against injected script file in PHP.
The flow:
i want make form search when user input strings & click search, data searched save on txt/php file with auto create new file based on month & year ex: -201601.php / txt
then data was saved on safety query with serial key on each string
then if data on -201601.php contents have more than 1000+ query, the data old was deleted automatic
then how showing 50 strings based on random strings on -201601.php
then in -201601.php there are no double string or same string
If you have a solution for my issue and want to post an answer, please add some explanation so that I can understand why/how you did it so that I won't come asking the same questions all over again. Thanks
Im search & create file that i want making it with my plot imagination. Here is what I have so far manually :
<center>
<form action="./cari.php?q=" method="GET">
<input type="text" name="q" value="" placeholder=" Cari .." style="cursor: pointer;width:69%"/>
<input type="submit" value="Search"/>
</form>
</center><?php
if(isset($_GET['q'])) {
$data = ''.$_GET['q']."<br>\n";
$ret = file_put_contents('rcnt.php', htmlspecialchars($data), FILE_APPEND | LOCK_EX);
if($ret === false) {
die('There was an error writing this file');
}
else {
//echo "$ret bytes written to file";
}
}
//else {die('no post data to process');}
?>
Im stuck searching with cant find related tutorial & hope find answer :(
Please your help, i want learn more with this, i use XAMPP 5.6
First step, the ?q= var the browser will create, you don`t need to set this on your form action.
<form method="get">
<input type="text" name="q" placeholder="search">
</form>
The PHP code will be:
<?php
if(!empty($_GET["q"]))
{
$file = fopen(date("Ym") . ".txt","a+");
fwrite($file, $_GET["q"] . "\r\n"); //\r\n jump the line
flose($file);
}
?>
If today is the 1st search of the 1st day of the month, the file will not exists, then, the PHP will create it, otherwise, will open and write on it.
Hope it could help you.
We could try this way:
<?php
$theFile = date("Ym") . ".txt";
$myFile = file($theFile);
for($i = 0; $i < 100; $i++){ //deleting the first 100 lines
unset($myFile[$i]);
}
//rewriting the file without the 100st first lines
file_put_contents($theFile, implode($myFile));
?>

PHP - Stop while loop after reading every single line from text file

I want the Code below to read individual line of text from dataFile.txt and show it in input field.
Problem is After reading first line from text document it shows all remaining lines of text from text file into input field. But on clicking submit it should show second line only then again on submitting it should show third line only, inside input field. please help.
<?php
$file = __DIR__."/dataFile.txt";
$f = fopen($file, "r");
$array1 = array();
<form action="datagGet.php" method="get">
<input type="text" value="
<?php while ( $line = fgets($f, 100) )
{
$nl = mb_strtolower($line);
echo $nl;
if(isset($_GET['done']))
{
$nl++;
}
else
{
break;
}
}
?>"
name="someText">
<input type="submit" name="done" >
</form>
You have several problems with you code. And the first comment above points to many of the. Key is the fact that the $_GET['done'] is set for the form submit and therefore you will echo all the lines of the output. It never breaks.
Also there is the fact that you are opening the file for reading each submit of the form. Although I don't see a simple way around this unless you store the file contents between requests.
One possible option is to use 'file()' to read the entire contents into an array. And then use sessions to store which line has been read. Then on each submit, look for the index of the array from the session read; advance it by one read the file again and return that line. Wow wasteful. But okay for simple site.
so use file to get the lines in an array.
output the first line into the value.
store the next index to be read in the $_SESSION variable like $_SESSION['next_line'] = 1
then upon further submissions. read it all back in. look up the 'next_line', and output that line.
so, for example
$array = file('your file name');
$output = $array[0];
if (isset($_SESSION['next_line']))
$_SESSION['next_line'] = intval($_SESSION['next_line']) + 1;
else
$_SESSION['next_line'] = 1;//prime the pump
echo the form with $output
then rinse and repeat. e.g. read, get output (next_line) with file, set $_session = next_line + 1; render output in form.
ps. some extra notes
* of course you'll need to start session on each request.
* you'll need to check if the $_SESSION['next_line'] is set. if not, set it to 1 (prime it)

Make checks for submit buttons

I encountered some problems, I want this script to:
Open test.txt file.
Check if user have added any text to the txt file.
If user have added any text, delete the existing line and replace it with the new. From $_POST.
If user have not, add $_POST in test.txt
Problem:
When I spam the submit button, the .txt will mess up. Anyone know how to make checks, so it does not mess up?
Please don't suggest MYSQL, I need these in .txt file.
Thanks.
function cutline($filename,$line_no=-1) {
$strip_return=FALSE;
$data=file($filename);
$pipe=fopen($filename,'w');
$size=count($data);
if($line_no==-1) $skip=$size-1;
else $skip=$line_no-1;
for($line=0;$line<$size;$line++)
if($line!=$skip)
fputs($pipe,$data[$line]);
else
$strip_return=TRUE;
return $strip_return;
}
if ($userid = 1) {
if(!isset($_POST['submit'])){
?>
<center><form action="" method="POST">
<b>HWID</b>
<input type="text" name="HWID" />
<input type="submit" value="Add HWID" name="submit">
</form>
</center>
<?php
}else{
$userid= 1;
$userid = "user=" . $userid;
$file = "test.txt";
$lines = file($file);
$count = 1;
foreach ($lines as $e) {
if(strpos($e, $userid) !== FALSE){
cutline($file,$count);
++$count;
}
}
$fh = fopen($file, 'a') or die("can't open file");
$stringData = $userid . $_POST['HWID'] . "\n";
fwrite($fh, $stringData);
}
}
}else{
echo "You're not logged in";
}
?>
I am not 100% sure how the text file is messing up, but I guess locking won't help here as locks are released when the script finished (or is reloaded).
It looks like you just "kill" your cutline while in progress and the remaining lines will not be written. One way to fix this could be to save the new content of the file in a temporary variable and call fwrite only once. (I am not 100% sure if this will work)
Another possibility is to write the results of cutline into a temporary file and replace the old file with the new one, when the cutline method is done. This can happen inside the method.
In either ways the existing file will not be touched if the script gets killed in an unsafe state. But you can still loose the new input from the user when he manages to reload the page right after the function call of cutline and before you add the new input in this line
fwrite($fh, $stringData);
I think this is really hard to force as this operation is quite fast.
EDIT:
Don't forget to test the script using multiple users at the same time, if this is a valid use case. If two or more guys are editing the same file at the same time it will mess up as well. So you might end up with some locking but that will not solve the problem described here.

How to Pass Variables Into PHP Ajax Handler Script?

I have a small ajax php application, which outputs data from a mysql db into a table. The rows are links, which when clicked will call an ajax function, which in turn will call another php file, which displays a different query from the same database in a layer without reloading the page.
I would like to know how to synchronize queries between both php files. So when I click on a row in the base page, the layer will be expanded to include additional information, or indeed the whole query.
I was thinking I could do this by having the primary key in the first query for the table, however I don't want it displayed and was wondering if there was a better approach to this?
with jQuery it's very simple, and I would definitely recommend using it in ajax calls and etc. Let's say you have a table like this;
<table>
<?php
// I'm using mysqli class by the way.
$ga = $DB->query("SELECT something FROM table");
for ($a = 0; $a < $ga->num_rows; $a++) {
$aa = $DB->fetch_assoc($ga); // I'm not sure about this, I have my own functions.
echo "
<tr class="clickable" id="<?=$aa["Id"] ?>">
<td>".$aa["NameOfColumn"]."</td>
</tr>
";
}
?>
</table>
and for the javascript part;
<script type="text/javascript">
$(document).ready(function() {
$(".clickable").on("click", function() {
// Get our row Id from the rows "id" attribute.
$id = $(this).attr("id");
alert($id);
});
</script>
Instead of displaying an alert you have to change what you need to do. For starters I would recommend using a preloaded div, and changing its content while using it like;
<div id="displayData" style="display: none;"> </div>
and for the JS function you can use it like;
$("#displayData").html($id).css("display","block");
The examples are numerous, and you should find what suits you best.
You can do in following way
There should be a hidden textbox in each row of table which will hold the promary key.
when you click the row it will call the javascript function and will pass the id through this like Text.
3.when the user clikc the row it will call the Callfunction in javascript and it will furthur call the ajax and passing the paramanter using GET ot POST method
You don't want it displayed, does that mean for security issues or something else.
If you want to lose the primary key in the table you can go with a query cache placed into a session object and then just retreive by place in array.
so something like:
page1:
create array with db objects
store array into session
display objects in table
add display layer function for eachrow in table using the index from the array as a parameter.
page2:
retrieve session object
show data for array spot
The best and easiest way to handle this would be the following:
USE A FRAMEWORK for your Ajax handling. It will make your life easier and they take care of a lot of stuff that generally you don't need to worry about like how to handle the XMLHttpRequest object across browsers and stuff.
When you load the first table, create a second tr for each tr that displays but make it hidden. You'll populate this second table row with the information from the ajax request.
Modify your ajax function to take the primary key as a parameter. Pass this parameter via either GET or POST to your second php script. You can look here for further clarification on that issue.
Specify the id of the second, hidden tr as the div to update with the response from your ajax request.
Current contents of file:
';
$myFile = "how-to-pass-variables-into-php-ajax-handler-script.php";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
}
?>
<?php
if (isset($_POST['submit'])) {
$myFile = "/posts/edit/644203";
$fh = fopen($myFile, 'w') or die("can't open file");
$stringData = stripslashes($_POST['sf']);
fwrite($fh, $stringData);
fclose($fh);
('Location: edit.php?a=done');
}
?>
<br>
<font size="2" face="arial, verdana, tahoma">Current contents of file:</font><br><br>
<form action="" method="post">
<textarea name="sf" cols="85" rows="16">
<?php
$myFile = "/posts/edit/644203";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
?></textarea>
<br />
<input type="submit" name="submit" value="Save & Upload" />
</form>
<?php
if ($_GET['a'] == 'done') {
echo 'The file was saved and now it says:<br /><br />';
$myFile = "/posts/edit/644203";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
}
?>

Categories