I'm attempting to write data to a .txt file using php file_put_contents with the following code.
file_put_contents($filevar, $userID, FILE_APPEND);
This successfully writes the $userID to $filevar, however even though FILE_APPEND is set, the file is overwritten on every execution.
I found my error,
I was working on getting the file to open earlier and was using some test statements. Opening problem was a permissions issue.
I was using fopen($filevar, 'w') to test if I could open the file, and this line was preventing the APPEND from working.
Related
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);
}
I am making an Android application that need to be able to push files onto a server.
For this I'm using POST and fopen/fwrite but this method only appends to the file and using unlink before writing to the file has no effect. (file_put_contents has the exact same effect)
This is what I have so far
<?php
$fileContent = $_POST['filecontent'];
$relativePath = "/DatabaseFiles/SavedToDoLists/".$_POST['filename'];
$savePath = $_SERVER["DOCUMENT_ROOT"].$relativePath;
unlink($savePath);
$file = fopen($savePath,"w");
fwrite($file,$fileContent);
fclose($file);
?>
The file will correctly delete its self when I don't try and write to it after but if I do try and write to it, it will appended.
Anyone got any suggestions on overwriting the file contents?
Thanks, Luke.
Use wa+ for opening and truncating:
$file = fopen($savePath,"wa+");
fopen
w+: Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
a+: Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
file_put_contents($savePath,$fileContent);
Will overwrite the file or create if not already exist.
read this it will help show all the options for fopen
http://www.php.net/manual/en/function.fopen.php
Found the error, i forgot to reset a string inside of my application
I seem to have some problem with my code here. It creates a file from the php file, but I get an error on the include path.
include('../include/config.php');
$name = ($_GET['createname']) ? $_GET['createname'] : $_POST['createname'];
function buildhtml($strphpfile, $strhtmlfile) {
ob_start();
include($strphpfile);
$data = ob_get_contents();
$fp = fopen ($strhtmlfile, "w");
fwrite($fp, $data);
fclose($fp);
ob_end_clean();
}
buildhtml('portfolio.php?name='.$name, "../gallery/".$name.".html");
The problem seems to be here:
'portfolio.php?name='.$name
Any way I can replace this, and still send the variable over?
Here's the error I get when I put ?name after the php extension:
Warning: include(portfolio.php?name=hyundai) [function.include]: failed to open stream: No such file or directory in D:\Projects\Metro Web\Coding\admin\create.php on line 15
Warning: include(portfolio.php?name=hyundai) [function.include]: failed to open stream: No such file or directory in D:\Projects\Metro Web\Coding\admin\create.php on line 15
Warning: include() [function.include]: Failed opening 'portfolio.php?name=hyundai' for inclusion (include_path='.;C:\php\pear') in D:\Projects\Metro Web\Coding\admin\create.php on line 15
Now I saw your code in the comment to a previous answer I'd like to point few things out
function buildhtml($strhtmlfile) {
ob_start(); // redundant
$fp = fopen ($strhtmlfile, "w"); // redundant
file_put_contents($strhtmlfile,
file_get_contents("http://host/portfolio.php?name={$name}"));
// where does $name come from?? ---^
close($fp); // also redundant
ob_end_clean(); // also redundant
}
buildhtml('../gallery/'.$name.'.html');
In PHP as in many other languages you can do things in different ways. What you've done is you took three different ways and followed only one (which is absolutely enough). So when you use functions file_put_contents() and file_get_contents() you don't need the buffer, that is the ob_ family of functions, because you never read anything in the buffer which you should then get with ob_get_contents(). Nor you need the file handles created and used by fopen(), fclose(), because you've never written to or read from the file handle i.e. with fwrite() or fread().
If I'm guessing correctly that the purpose of your function is to copy html pages to local files, my proposal would be the following:
function buildhtml($dest_path, $name) {
file_put_contents($dest_path,
file_get_contents("http://host/portfolio.php?name={$name}"));
}
buildhtml('../gallery/'.$name.'.html', $name);
file_put_contents($strhtmlfile, file_get_contents("http://host/portfolio.php?name={$name}"))
Is it ok?
The output of:
'portfolio.php?name='.$name, "../gallery/".$name.".html";
is:
portfolio.php?name=[your name]../gallery/[your name].html
Are you sure that's what you want ?
include/require statements in PHP allow you to access the code contained in a file which is already stored on the server
What you are trying to achieve is including the output result of executing the code in that file with specific parameters
The suggested example offered by MrSil allows you to request the execution of the code in those files and offer parameters. The reason it shows you a blank page is because file_put_contents 'saves data to a file' and file_get_contents does not echo the result, it returns it. Remove the file_put_contents call, and add an echo at the beginning of the line before file_get_contents and it should work.
echo file_get_contents('http://domain.com/file.php?param=1');
As a warning this approach forces the execution of 2 separate PHP processes. An include would have executed the code of the second file within the first process.
To make the include approach work you need to include the file as you first did but without specifying parameters. Before including each file you need to setup the parameters it is expecting such as $_GET['name'] = $name
I have a file with the contents:
a:12:{s:12:"a2.twimg.com";i:1308768611;s:12:"a1.twimg.com";i:1308768611;s:12:"a0.twimg.com";i:1308768612;s:12:"a3.twimg.com";i:1308768612;s:8:"this.com";i:1308768613;s:15:"f.prototype.com";i:1308768613;s:15:"c.prototype.com";i:1308768614;s:15:"a.prototype.com";i:1308768614;s:5:"w.com";i:1308768615;s:5:"s.com";i:1308768615;s:5:"f.com";i:1308768615;s:5:"h.com";i:1308768615;}
(It's an array of domains listed on twitter.com as keys and a timestamp as values)
If I call:
unserialize(fread($recentfile, filesize("./neptune_output/recent")))
("./neptune_output/recent" is the location of the $recentfile)
It fails, but if I call unserialize with that string pasted in, it works.
I use the following code to open the file.
$recentfile = fopen("./neptune_output/recent", 'a+')
I've tried putting the fopen mode as 'c+' and 'a+b' but it won't work.
Do I need to post more code?
Why don't you just read it with file_get_contents() rather than messing about with opening it and working out the file size?
a+ means: "Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it."
If you just want to read "r" is enough:
$recentfile = fopen("./neptune_output/recent", 'r')
See http://nl2.php.net/manual/en/function.fopen.php
This is my code:
$zplHandle = fopen($target_file,'w');
fwrite($zplHandle, $zplBlock01);
fwrite($zplHandle, $zplBlock02);
fwrite($zplHandle, $zplBlock03);
fclose($zplHandle);
When will the file be saved? Is it immediately after writing to it or after closing it?
I am asking this because I have Printfil listening to files in a folder and prints any file that is newly created. If PHP commits a save immediately after fwrite, I may run into issues of Printfil not capturing the subsequent writes.
Thank you for the help.
PHP may or may not write the content immediately. There is a caching layer in between. You can force it to write using fflush(), but you can't force it to wait unless you use only one fwrite().
I made a tiny piece of code to test it and it seems that after fwrite the new content will be detected immediately,not after fclose.
Here's my test on Linux.
#!/usr/bin/env php
<?php
$f = fopen("file.txt","a+");
for($i=0;$i<10;$i++)
{
sleep(1);
fwrite($f,"something\n");
echo $i," write ...\n";
}
fclose($f);
echo "stop write";
?>
After running the PHP script ,I use tail -f file.txt to detect the new content.And It shows new contents the same time as php's output tag.
the file will be saved on fclose. if you want to put the content to the file before, use fflush().
Assuming your working in PHP 5.x, try file_put_contents() instead, as it wraps the open/write/close into one call.
http://us3.php.net/manual/en/function.file-put-contents.php