PHP Modify a single line in a text file - php

I tried and looked for a solution, but cannot find any definitive.
Basically, I have a txt file that lists usernames and passwords. I want to be able to change the password of a certain user.
Contents of users.txt file:
user1,pass1
user2,pass2
user3,pass3
I've tried the following php code:
// $username = look for this user (no help required)
// $userpwd = new password to be set
$myFile = "./users.txt";
$fh = fopen($myFile,'r+');
while(!feof($fh)) {
$users = explode(',',fgets($fh));
if ($users[0] == $username) {
$users[1]=$userpwd;
fwrite($fh,"$users[0],$users[1]");
}
}
fclose($fh);

This should works! :)
$file = "./users.txt";
$fh = fopen($file,'r+');
// string to put username and passwords
$users = '';
while(!feof($fh)) {
$user = explode(',',fgets($fh));
// take-off old "\r\n"
$username = trim($user[0]);
$password = trim($user[1]);
// check for empty indexes
if (!empty($username) AND !empty($password)) {
if ($username == 'mahdi') {
$password = 'okay';
}
$users .= $username . ',' . $password;
$users .= "\r\n";
}
}
// using file_put_contents() instead of fwrite()
file_put_contents('./users.txt', $users);
fclose($fh);

I think when you get that file use file_get_contents after that use preg_replace for the particular user name
I have done this in the past some thing like here
$str = "";
$reorder_file = FILE_PATH;
$filecheck = isFileExists($reorder_file);
if($filecheck != "")
{
$reorder_file = $filecheck;
}
else
{
errorLog("$reorder_file :".FILE_NOT_FOUND);
$error = true;
$reorder_file = "";
}
if($reorder_file!= "")
{
$wishlistbuttonhtml="YOUR PASSWORD WHICH YOU WANT TO REPLACE"
$somecontent = $wishlistbuttonhtml;
$Handle = fopen($reorder_file, 'c+');
$bodytag = file_get_contents($reorder_file);
$str=$bodytag;
$pattern = '/(YOUR_REGEX_WILL_GO_HERE_FOR_REPLACING_PWD)/i';
$replacement = $somecontent;
$content = preg_replace($pattern, $replacement, $str,-1, $count);
fwrite($Handle, $content);
fclose($Handle);
}
Hope this helps....

The proper way of doing this is to use a database instead. Databases can do random access easily, doing it with text files less so.
If you can't switch to a database for whatever reason, and you don't expect to have more than about a thousand users for your system, then it would be far simpler to just read the whole file in, convert it to a PHP data structure, make the changes you need to make, convert it back into text and overwrite the original file.
In this case, that would mean file() to load the text file into an array with each element being a username and password as a string, explode all elements on the array at the comma to get the username and password separately, make the changes you need to make, then write the modified data to disc.
You might also find fgetcsv() useful for reading the data. If you SplFileObject and have a recent version of PHP then fputcsv() may also be available to write the data back out.
However, just using a database is a far better solution. Right tool for the job.

$fn = fopen("test.txt","r") or die("fail to open file");
$fp = fopen('output.txt', 'w') or die('fail to open output file');
while($row = fgets($fn))
{
$num = explode("++", $row);
$name = $num[1];
$sex = $num[2];
$blood = $num[3];
$city = $num[4];
fwrite($fp, "Name: $name\n");
fwrite($fp, "Sex: $sex\n");
fwrite($fp, "Blood: $blood\n");
fwrite($fp, "City: $city\n");
}
fclose($fn);
fclose($fp);

If you're on a *nix system you could use sed; I find it neater than playing with file handles etc:
exec("sed -i '/^$username,.\+\$/$username,$userpwd/g' ./users.txt 2>&1", $output, $return);
If not I'd agree with GordonM and parse the file into a PHP data structure, manipulate it, then put it back:
$data = file_get_contents('./users.txt');
$users = array_map(function($line) {
return explode(',', $line);
}, explode("\n", $data));
foreach ( $users as $i => $user ) {
if ( $user[0] == $username ) {
$user[1] = $userpwd;
$users[$i] = $user;
}
}
file_put_contents('./users.txt', implode("\n", array_map(function($line) {
return implode(',', $line);
}, $users)));
There are, of course, an infinite number of ways of doing that!

Related

Need help writing and reading a file with PHP

So for an assignment, I have to create a form where users can post ride shares so other people can see and join their ride. I'm doing this by writing the form to a file data.txt, and reading the file to display all the rides on a board. My only problem is when I get the contents of data.txt, it's all combined together. I need to be able to display each ride separately. How would I go about doing this?
Here is my code so far:
The writing:
if (isset($_POST['name'])
&& isset($_POST['email'])
&& isset($_POST['date'])
&& isset($_POST['destination'])
&& isset($_POST['msg'])) {
$name = $_POST['name'];
$email = $_POST['email'];
$date = $_POST['date'];
$destination = $_POST['destination'];
$msg = $_POST['msg'];
//TODO the file write here VV, use 'a' instead of 'w' too ADD to the file instead of REWRITING IT.
$arr = [$name,$email,$date,$destination,$msg];
$write = json_encode($arr);
$file = fopen('data.txt', 'a');
fwrite($file, $write);
fclose($file);
}
And the reading:
$path = 'data.txt';
$handle = fopen($path, 'r');
$contents = fread($handle, filesize($path));
echo $contents;
fclose($handle);
$newarr = [json_decode($contents)];
foreach($newarr as $stuff)
{
echo $stuff[0];
}
And the output is something like:
["Simon Long","example#gmail.com","2109-01-01T01:01","canada","this is a message"] Simon Long
Let's say there are multiple postings in there, it would just print them all together. I need a way to separate postings so I can display them nicely on the board.
Use a multidimensional array.
$arr = [
"Simon Long","example#gmail.com","2109-01-01T01:01","canada","this is a message",
"John Doe","john#gmail.com","2109-01-01T01:01","canada","this is a message",
"Jane Doe","jane#gmail.com","2109-01-01T01:01","canada","this is a message"
];
Then you when you add to it just append to the final array and replace the whole file.
$contents = file_get_contents($path);
$decoded = json_decode($contents);
$decoded[] = [$name,$email,$date,$destination,$msg];
file_put_contents($path, json_encode($decoded)); //replace the entire file.
Also just as a side note. isset accepts multiple arguments so you don't need to use it as you are. You can do this:
if (isset($_POST['name'], $_POST['email'], $_POST['date'], $_POST['destination'] ...)
It's also a good idea to sanitise any input from the user.
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);

How do I read each line from a file in php?

I'm new to learning php and in one of my first programs I wanted to make a basic php website with login capabilities with and array of the user and passwd.
my idea is to store the username as a list parameter and have the passwd as the contents, like this:
arr = array(username => passwd, user => passwd);
now my problem is that I don't know how I can read from the file (data.txt) so I can add it into the array.
data.txt sample:
username passwd
anotherUSer passwd
I've opened the file with fopen and stored it in $data.
You can use the file() function.
foreach(file("data.txt") as $line) {
// do stuff here
}
Modify this PHP example (taken from the official PHP site... always check first!):
$handle = #fopen("/path/to/yourfile.txt", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
echo $buffer;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
to:
$lines = array();
$handle = #fopen("/path/to/yourfile.txt", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
lines[] = $buffer;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
// add code to loop through $lines array and do the math...
Be aware that you should not store login details in a textfile that in addition is not encrypted, this approach has severe security issues.
I know you are new from PHP, but the best approach is to store it in a DB and crypting the passwords with an algorithm such as MD5 or SHA1,
You shouldn't store sensitive information as plaintext, but to answer your question,
$txt_file = file_get_contents('data.txt'); //Get the file
$rows = explode("\n", $txt_file); //Split the file by each line
foreach ($rows as $row) {
$users = explode(" ", $row); //Split the line by a space, which is the seperator between username and password
$username = $users[0];
$password = $users[1];
}
Take a look at this thread.
This works for extremely large files as well:
$handle = #fopen("data.txt", "r");
if ($handle) {
while (!feof($handle)) {
    $line = stream_get_line($handle, 1000000, "\n");
//Do Stuff Here.
}
fclose($handle);
}
Use file() or file_get_contents() to create either an array or a string.
process the file contents as needed
// Put everything in the file in an array
$aArray = file('file.txt', FILE_IGNORE_NEW_LINES);
// Iterate throug the array
foreach ($aArray as $sLine) {
// split username an password
$aData = explode(" ", $sLine);
// Do something with the username and password
$sName = $aData[0];
$sPass = $aData[1];
}

fwrite - need a new line after variable - PHP

When my script writes to the file, it doesn't break the added content onto a new line.
Instead of:
user1:password1
user2:password2
It writes:
user1:password1user2:password2
Originally, my fwrite looked like this fwrite($fh, $data); and from searching other questions, I changed my code to this:
fwrite($fh, $data . "\n");
This does not seem to work though.
Here is my code
<?php
if (isset($_POST['submit']))
{
$username = $_POST['user'];
$password = $_POST['password'];
$confirmpw = $_POST['confirmpw'];
$username = strtolower($username);
//Check if passwords match
if ($password != $confirmpw){
print "Passwords do not match, please try again.";
}
else{
//the data
$data = "$username:$password\n";
//open the file and choose the mode
$fh = fopen("passwd.txt", "a+");
// Cycle through the array
$match_found = false;
while (($buffer = fgets($fh, 4096)) !== false)
{
// Parse the line
list($usercheck, $passwordcheck) = explode(':', $buffer);
if (trim($usercheck) == $username)
{
print "The username is already in our system. Please use another one.";
$match_found = true;
break;
}
}
if(!$match_found)
{
fwrite($fh, $data . "\n");
// Set cookies for an hour
$hour = time() + 3600;
setcookie("username", $username, $hour);
//Redirect to home page
header("location: index.php");
}
}
//close the file
fclose($fh);
}
?>
What you need to use is \r\n.
For me only worked PHP_EOL (xampp on windows 7 php 5.3.8)
Use PHP_EOL for the platform dependent newline character. However, \n actually represents the newline character in the *NIX-world, but some windows editors denies to show them as newline (thats what happens in your case). You should consider using an other IDE and always use \n for compatibility (if the file should be usable on other platforms).
"\r\n" use this instead will work like a charm

php writing additional lines to encrypted files?

I'm trying to open an encrypted file that will store a list of information, then add a new ID with information, and save the file back as it was originally encrypted. I have xor/base64 functions that are working, but I am having trouble getting the file to retain old information.
here is what I am currently using:
$key = 'some key here';
$id = $_GET['id'];
$group = $_GET['group'];
$file = "groups.log";
$fp = fopen($file, "w+");
$fs = file_get_contents($file);
$filedec = xorstr(base64_decode($fs),$key);
$info = "$id: $group";
$filedec = $filedec . "$info\n";
$reencode = base64_encode(xorstr($filedec,$key));
fwrite($fp, $reencode);
fclose($fp);
function xorstr($str, $key) {
$outText = '';
for($i=0;$i<strlen($str);)
{
for($j=0;$j<strlen($key);$j++,$i++)
{
$outText .= $str[$i] ^ $key[$j];
}
}
return $outText;
}
?>
It should save an entire list of the ID's and their corresponding groups, but for some reason it's only showing the last input :(
I wouldn't call this encryption. "cereal box decoder ring", maybe. If you want encryption, then use the mcrypt functions. At best this is obfuscation.
The problem is that you're doing fopen() before doing file_get_contents. Using mode w+ truncates the file to 0-bytes as part of the fopen() call. So by the time file_get_contents comes up, you've deleted the original file.
$fs = file_get_contents(...);
$fh = fopen(..., 'w+');
in that order will fix the problem.

how to implement FILTER_SANITIZE_SPECIAL_CHARS

here's what I've got so far - i really need to ban any tags from being entered as it's like a guestbook, but this doesn't seem to work:
<?php
$txt = $_POST['txt'];
//the data
$data = "
$txt";
//my attempt to implement a filter
var_dump(filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS));
//open the file and choose the mode
$fh = fopen("users.txt", "a");
fwrite($fh, $data);
//close the file
fclose($fh);
header('Location: http://www.google.com/');
?>
You need to assign the returned value of filter_var
$data = filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS);
filter_var can return FALSE if the filter fails. So, to be complete, you really should do something like:
$filtered_data = filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS);
if($filtered_data !== FALSE) {
//write $filtered_data
} else {
//handle error
}

Categories