PHP not writing to file - php

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.

Related

Securely delete file in php

I would like to securely delete a file in PHP. I thought of the following options
Use shredthrough a system call. (exec, shell_exec, ....), but in most shared hostings, those functions are disabled and are forbidden if safe mode is on.
Open it through fopenand overwriting it with random data and unlinkit. Correct me if I'm wrong, but doing my research I found it was disabled on some servers.
The best option I thought of, is using file_put_contentto overwrite its data with zeros, and then deleting it.
Question is: is file_put_content guaranteed to overwrite the file ? I wrote a simplistic approach in the following example: would this code delete a file securely ? Would there be a considerable performance hit ? How do I make it more "large file friendly" ?
function secure_delete($file_path)
{
$file_size = filesize($file_path);
$new_content = str_repeat('0', $file_size);
file_put_contents($file_path, $new_content);
unlink($file_path);
}
UPDATE: The code I posted is more about demonstrating the overwriting of a file: the actual code would be an implementation of DoD 5220.22-M
It's not so simply. If you erase file with '0' values it can be still posible to restore. You should use any of algorihms for really secure deletion. For example: Gutmann method
It use 35 consecutive writes per file.
Found a PHP library that does this https://github.com/DanielRuf/secure-shred

php User registration system without mysql database

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);

About PHP parallel file read/write

Have a file in a website. A PHP script modifies it like this:
$contents = file_get_contents("MyFile");
// ** Modify $contents **
// Now rewrite:
$file = fopen("MyFile","w+");
fwrite($file, $contents);
fclose($file);
The modification is pretty simple. It grabs the file's contents and adds a few lines. Then it overwrites the file.
I am aware that PHP has a function for appending contents to a file rather than overwriting it all over again. However, I want to keep using this method since I'll probably change the modification algorithm in the future (so appending may not be enough).
Anyway, I was testing this out, making like 100 requests. Each time I call the script, I add a new line to the file:
First call:
First!
Second call:
First!
Second!
Third call:
First!
Second!
Third!
Pretty cool. But then:
Fourth call:
Fourth!
Fifth call:
Fourth!
Fifth!
As you can see, the first, second and third lines simply disappeared.
I've determined that the problem isn't the contents string modification algorithm (I've tested it separately). Something is messed up either when reading or writing the file.
I think it is very likely that the issue is when the file's contents are read: if $contents, for some odd reason, is empty, then the behavior shown above makes sense.
I'm no expert with PHP, but perhaps the fact that I performed 100 calls almost simultaneously caused this issue. What if there are two processes, and one is writing the file while the other is reading it?
What is the recommended approach for this issue? How should I manage file modifications when several processes could be writing/reading the same file?
What you need to do is use flock() (file lock)
What I think is happening is your script is grabbing the file while the previous script is still writing to it. Since the file is still being written to, it doesn't exist at the moment when PHP grabs it, so php gets an empty string, and once the later processes is done it overwrites the previous file.
The solution is to have the script usleep() for a few milliseconds when the file is locked and then try again. Just be sure to put a limit on how many times your script can try.
NOTICE:
If another PHP script or application accesses the file, it may not necessarily use/check for file locks. This is because file locks are often seen as an optional extra, since in most cases they aren't needed.
So the issue is parallel accesses to the same file, while one is writing to the file another instance is reading before the file has been updated.
PHP luckily has a mechanisms for locking the file so no one can read from it until the lock is released and the file has been updated.
flock()
can be used and the documentation is here
You need to create a lock, so that any concurrent requests will have to wait their turn. This can be done using the flock() function. You will have to use fopen(), as opposed to file_get_contents(), but it should not be a problem:
$file = 'file.txt';
$fh = fopen($file, 'r+');
if (flock($fh, LOCK_EX)) { // Get an exclusive lock
$data = fread($fh, filesize($file)); // Get the contents of file
// Do something with data here...
ftruncate($fh, 0); // Empty the file
fwrite($fh, $newData); // Write new data to file
fclose($fh); // Close handle and release lock
} else {
die('Unable to get a lock on file: '.$file);
}

How can I include custom text inside a file saved from a php form?

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.

PHP write to included file

I need to include one PHP file and execute function from it.
After execution, on end of PHP script I want to append something to it.
But I'm unable to open file. It's possible to close included file/anything similar so I'll be able to append info to PHP file.
include 'something.php';
echo $somethingFromIncludedFile;
//Few hundred lines later
$fh = fopen('something.php', 'a') or die('Unable to open file');
$log = "\n".'$usr[\''.$key.'\'] = \''.$val.'\';';
fwrite($fh, $log);
fclose($fh);
How to achieve that?
In general you never should modify your PHP code using PHP itself. It's a bad practice, first of all from security standpoint. I am sure you can achieve what you need in other way.
As Alex says, self-modifying code is very, VERY dangerous. And NOT seperating data from code is just dumb. On top of both these warnings, is the fact that PHP arrays are relatively slow and do not scale well (so you could file_put_contents('data.ser',serialize($usr)) / $usr=unserialize(file_get_contents('data.ser')) but it's only going to work for small numbers of users).
Then you've got the problem of using conventional files to store data in a multi-user context - this is possible but you need to build sophisticated locking queue management. This usually entails using a daemon to manage the queue / mutex and is invariably more effort than its worth.
Use a database to store data.
As you already know this attempt is not one of the good ones. If you REALLY want to include your file and then append something to it, then you can do it the following way.
Be aware that using eval(); is risky if you cannot be 100% sure if the content of the file does not contain harmful code.
// This part is a replacement for you include
$fileContent = file_get_contents("something.php");
eval($fileContent);
// your echo goes here
// billion lines of code ;)
// file append mechanics
$fp = fopen("something.php", "a") or die ("Unexpected file open error!");
fputs($fp, "\n".'$usr[\''.$key.'\'] = \''.$val.'\';');
fclose($fp);

Categories