I want to create a registration system on my site where only limited users will be able to create their account. I want to use a .txt file for storing usernames and passwords.
I have the following code so far :
$uname=$_POST['usr'];
$pass=$_POST['pwd'];
if(empty($_POST["ok"])){echo "Could not insert data!";}
else
{$file=fopen("user.txt","w");
echo fwrite($file,$uname);
fclose($file);}
This receives the user data from a form and puts it in user.txt file.
My problem is that when new data is inserted to txt file the old data get deleted.
I want to keep the data in txt file like
foo:12345~bar:1111
username and password are seprated by : and new user is seprated by ~ ,later I will use regex to get the data from txt file.
How can i correct my code to keep both new and old data?
You need to open file in append mode
http://php.net/manual/en/function.fopen.php
<?php
$uname = $_POST['usr'];
$pass = $_POST['pwd'];
if (empty($_POST["ok"])) {
echo "Could not insert data!";
} else {
$file = fopen("user.txt", "a");
$srt="foo:".$uname."~bar:".$pass;// create your string
echo fwrite($file, $srt);
fclose($file);
}
If we want to add on to a file we need to open it up in append mode.
So you need to change from write only mode to append mode.
$file=fopen("user.txt","a");
To answer your question: you have to explicitly pass $mode argument to fopen() function equals to 'a'.
However, it looks like a bad idea to use plain files for this task. Mainly because of concurent writes troubles.
This is really a bad choice: there are a lot of drawbacks for security, for read/write times, for concurrent requests and a lot more.
Using a database isn't difficult, so my suggestion is to use one.
Anyway, your question is asked yet here: php create or write/append in text file
Simple way to append to a file:
file_put_contents("C:/file.txt", "this is a text line" . PHP_EOL, FILE_APPEND | LOCK_EX);
Related
I have a small web-page that delivers different content to a user based on a %3 (modulo 3) of a counter. The counter is read in from a file with php, at which point the counter is incremented and written back into the file over the old value.
I am trying to get an even distribution of the content in question which is why I have this in place.
I am worried that if two users access the page at a similar time then they could either both be served the same data or that one might fail to increment the counter since the other is currently writing to the file.
I am fairly new to web-dev so I am not sure how to approach this without mutex's. I considered having only one open and close and doing all of the operations inside of it but I am trying to minimize time where in which a user could fail to access the file. (hence why the read and write are in separate opens)
What would be the best way to implement a sort of mutual exclusion so that only one person will access the file at a time and create a queue for access if multiple overlapping requests for the file come in? The primary goal is to preserve the ratio of the content that is being shown to users which involves keeping the counter consistent.
The code is as follows :
<?php
session_start();
$counterName = "<path/to/file>";
$file = fopen($counterName, "r");
$currCount = fread($file, filesize($counterName));
fclose($file);
$newCount = $currCount + 1;
$file = fopen($counterName,'w');
if(fwrite($file, $newCount) === FALSE){
echo "Could not write to the file";
}
fclose($file);
?>
Just in case anyone finds themselves with the same issue, I was able to fix the problem by adding in
flock($fp, LOCK_EX | LOCK_NB) before writing into the file as per the documentation for php's flock function. I have read that it is not the most reliable, but for what I am doing it was enough.
Documentation here for convenience.
https://www.php.net/manual/en/function.flock.php
I'm trying to create a simple waiting list and display to use a piece of equipment. Users will enter their name using a PHP form, and I can write the name to the end of a text file using something like this:
<?php
$name = $_GET['name'];
$fp = fopen("./name.txt", 'w');
if (!$fp)
{
echo '<html><body><p>Failed to open file.</body></html>';
exit;
}
$outputstring = "$name\r\n";
fwrite($fp, $outputstring, strlen($outputstring));
echo "\0";
end;
?>
I was planning to use PHP to read the text file, and pull off the name at the top of the list to display on a web site. However, I'm not sure if it is possible to delete the name once I request it from the text file. I'd also like to clear the text file daily. Are there better alternative ways to create this waiting list? What would you recommend instead?
Ok so I have this thing setup to write things to text, but it will not actually write the txt to the file.
It deletes the file then creates it again with the data inside.
$_POST['IP']=$ip;
unlink('boot_ip.txt');
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt","wb");
fwrite($fp,$IP) ;
fclose($fp);
Your variables were not properly set and were done the other way around.
Quick note: wb means to write binary. Unless that is not your intention, I suggest you use only w.
Your filename ending in .txt is text, therefore use the w switch. That will overwrite previous content.
You had:
$_POST['IP']=$ip;
unlink('boot_ip.txt');
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt","wb");
fwrite($fp,$IP);
fclose($fp);
This => $_POST['IP']=$ip; where it should be $ip=$_POST['IP'];
and this fwrite($fp,$IP); should be fwrite($fp,$ip);
You had the $IP in uppercase when it should be in lowercase as you declared in your variable.
NOTE: The unlink part of the code may need to reflect your folder's place on your server.
However, I suggest you do not use unlink because using it will throw an error right away, because the file may not be found to begin with, since it would have already been unlinked.
You can either not use it, or use an if statement. See my example following my code below.
Plus, using the w switch, will automatically overwrite previously written content.
If you need to append/add to the file, then you will need to use the a or a+ switch.
If that is the case, then you will need to use the following:
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt","a");
fwrite($fp,$ip . "\n");
Reformatted (tested and working)
$ip=$_POST['IP'];
unlink('boot_ip.txt');
// use the one below here
// unlink($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt");
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt","wb");
fwrite($fp,$ip);
fclose($fp);
Using the following form:
<form action="handler.php" method="post">
<input type="text" name="IP">
<input type="submit" value="Submit">
</form>
Using an if statement method.
$ip=$_POST['IP'];
if(!file_exists($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt")) {
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/boot/boot_ip.txt","wb");
fwrite($fp,$ip);
fclose($fp);
}
Traditionally, That's exactly how text files work. It's a sequential access file rather than a random access file. Everything needs to be re written every time you add new information to a file. That's why it's slow and inefficient for large scale projects.
There's no way around it. Either read the data from the file, and re-write it with the new information, or make a random access file. That's how it's taught in most languages and in classrooms. It's mostly so you understand the processes.
In practice though if you're only appending data to the end:
unlink(); in php deletes a file, so you don't need it.
ALSO
see: http://www.w3schools.com/php/php_file.asp
for how to write to a file and the parameters you can use for behaviour
specifically look at the parameters for write modes: r, w, rw+, etc....
a is probably the one you want.
It still re-creates the file like I said, but does all the reading and rewriting for you so you don't have to do it yourself.
the parameter you entered "wb" DOES contain a w. so i assume a part of it is the same as simply "w" which, like i said earlier, would clear the file if it exists before writing new data.
My solution for you is aka, TL;DR version:
$fp=fopen("boot_ip.txt","a");
(I didn't use the full form like you did, but the import change is the second parameter a rather than wb) and exclusion of unlink(); )
then do your writes. This should add new data to the end of the file.
I'm using this code below that simply takes the name of an artist submitted through a form and saves it as a html file on the server.
<?php
if (isset($_GET['artist'])) {
$fileName = $_GET['artist'].".html";
$fileHandler = fopen($fileName, 'w') or die("can't create file");
fclose($fileHandler);
}
?>
What I'm trying to work out is how I could possibly add any code within the file before it is saved. That way every time a user adds an artist I can include my template code within the file. Any help would be great :)
Use fwrite.
Two things:
file_put_contents as a whole will be faster.
Your design is a very bad idea. They can inject a file anywhere on your filesystem, e.g. artist=../../../../etc/passwd%00 would try to write to /etc/passwd (%00 is a NUL byte, which causes fopen to terminate the string in C - unless that's been fixed).
fwrite() allows you to write text to the file.
if (isset($_GET['artist'])) {
$fileName = $_GET['artist'].".html";
$fileHandler = fopen($fileName, 'w') or die("can't create file");
fwrite($fileHandler, 'your content goes here');
fclose($fileHandler);
}
Warning - be very careful about what you write to the filesystem. In your example there is nothing stopping someone from writing to parts of the filesystem that you would never have expected (eg. artist='../index'!).
I sincerely recommend that you think twice about this, and either save content to a database (using appropriate best practices, ie http://php.net/manual/en/security.database.sql-injection.php) or at least make sure that you limit the characters used in the filename strings (eg. only allow characters A-Z or a-z and '_', for example). It's dangerous and exploitable otherwise, and at the very least you run the risk of your site being defaced or abused.
As others have said - you should be able to write php code to the filesystem with fwrite.
i am creating an under construction page where users can leave their email to be notified when the site launch
i need to add those emails to a text file called list.txt
my question is two parts
how can i add user#example.com to the text file ?
and how i can later delete certain email from a text file ?
thanks for help
You'd be better off using a database because these operations can step on each other.. but:
Add:
$fp = fopen("list.txt","a"); //a is for append
fputs($fp,"user#example.com" . "\n");
fclose($fp);
Remove:
$file = file_get_contents("list.txt");
unlink("list.txt"); //delete existing file
$fp = fopen("list.txt","w"); //w is for write/new
$lines = split("\n",$file);
while (list(,$email) = each($lines)) {
if ($email != "user#example.com") fputs($fp,$email . "\n");
}
Again... highly recommended to use a database... this is not optimal.
As for saving, you can fopen() in appending mode and just fwrite() to it. As for deleting a certain email: you'll have to load the whole file as a string and save it to file (effectively replacing the entire contents). Without some elaborate locking mechanism a race condition can occur when saving the file, causing you to lose the / a latest signup(s).
I would recommend a simple drop-in sqlite database (or another database if you already have one in production), so you can easily save & delete certain emails, and locking / avoiding race conditions is done automatically for you. If you still need a text file for some other purpose, export the subscription list to that file before using it.