PHP Understanding stream_get_contents on existing file opened with w+ - php

I was trying to figure out file pointers in PHP, so I wrote a small script to test it out:
$fp = fopen('test.me', 'w+');
fwrite($fp, '12345');
rewind($fp);
echo 'contents: ['.stream_get_contents($fp)."]\n";
fseek($fp, 0, SEEK_END);
fwrite($fp, '6789');
fclose($fp);
echo 'contents: ['.file_get_contents('test.me')."]\n";
Nice and easy. Open a file to read/write from it. Write to it. Go back to the beginning of the file, print out its contents. Go to the end of the file, append some more to it. Finally, print out the entire contents of the file.
I run it and get the exact results that I expect:
contents: [12345]
contents: [123456789]
Being so proud of myself for writing this masterpiece, I go to my terminal and hit up and enter to run it again.
This time:
contents: []
contents: [123456789]
Turns out that if the file exists at the start of the script, the first block is always contents:[]. If I delete the test.me file, then the first block is contents:[12345].
What's going on here?

Related

Update/Modify existing file on server

I want to add content to file on every page load, but it overwrite file, not updating content. my original code:
$file_handle = fopen('log.txt', 'w');
fwrite($file_handle, $message);
fclose($file_handle);
After i searching, nothing found to solve my prolem:
How to edit/update a txt file with php
PHP Modify a single line in a text file
I used w+ and r+ but it didn't work.
$file_handle = fopen('log.txt', 'w+');
fwrite($file_handle, $message);
fclose($file_handle);
Both write file with new content, not keep old contents. I want to keep old contents, just append new content to existing file.
You are trying to append to a file so you need the mode 'a':
$file_handle = fopen('log.txt', 'a');
fwrite($file_handle, $message);
fclose($file_handle);
From the docs:
'a': Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it. In this mode, fseek() has no effect, writes are always appended.

Why is PHP mixing two fopen handles on one file?

I noticed while testing two fopen() handles on one file, that the handles or channels mix, and the file contents empty when i call fread(). One handle is read, and one handle is write.
Example code:
$rh = fopen('existingfilewithcontent.txt', 'r');
$wh = fopen('existingfilewithcontent.txt', 'w');
echo fread($rh, 1000);
fclose($rh);
fclose($wh);
// file is now blank
This is tested on Linux & Windows.
I could not find anything in the PHP docs about it.
Please do not ask my why I would want two handles on one file as that is not the question.
Thankyou
Opening a file for write is destructive.
Manual says:
'w' - Open for writing only; 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.
You probably want:
'r+' - Open for reading and writing; place the file pointer at the beginning of the file.
OR
'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. In this mode, fseek() only affects the reading position, writes are always appended.
See manual: http://php.net/manual/en/function.fopen.php

php fopen() and fwrite() under heavy ddos attack

In normal condition , everything is ok, an I can write and create new files with fopen() and fwrite() but under "heavy" DDOS attacks , when file pointer is located at 0 , i cant write anything to file.eg. using "w" mod ,result will be a blank file , but by using "a" or "c" mod , if file not exist or be empty, nothing will be written (and just create a blank file too) , but if file has some characters , it will writes after characters or will clear and rewrite new characters respectively.
and when DDOS stopped , everything would be Ok.
here is simple code that I'm using for test, what is the problem? Can I fix it?
I'm using php5 in ubuntu with apache and lighttpd...
<?php
$fp = fopen('data.txt', 'w');
fwrite($fp, '1');
fputs($fp, '23');
fclose($fp);
?>
The way I understood the question is that you have problems running this code when there are multiple requests accessing the .php file (and thus the file you are writing to) at the same time.
Now, while it is far from being foolproof, flock() is there to help with this. The basic concept is that you'd ask for a lock of the file before writing and only write to a file if you're able to get the lock to that file, like
$fp = fopen( $filename,"w"); // open it for WRITING ("w")
if (flock($fp, LOCK_EX | LOCK_NB)) {
// do your file writes here
// when you're done,
// flush your file writes to a file before unlocking
fflush($fp);
// unlock the file
flock($fp, LOCK_UN);
} else {
// flock() returned false, no lock obtained
print "Could not lock $filename!\n";
}
fclose($fp);
You can read some more details from the manual entry or this article.

Why PHP file handler doesn't work properly?

I have this content on 'test.txt' file: lucas
I want to seek pointer in the file and override info ahead. Supposed I do:
$f = new SplFileObject('test.txt', 'a');
$f->fseek(-5, SEEK_END);
var_dump($f->ftell());
$f->fwrite('one');
This should produce: oneas But the result of execution: lucasone
I'm crazy about the code logic or even doesn't works?
How is the right way to do what I want?
You opened the file for appending:
$f = new SplFileObject('test.txt', 'a');
which means you cannot seek in the file. Instead, open it for reading and writing:
$f = new SplFileObject('test.txt', 'r+');
They also say it in the fseek documentation:
If you have opened the file in append (a or a+) mode, any data you write to the file will always be appended, regardless of the file position, and the result of calling fseek() will be undefined.

PHP file writing problem

I'm trying to write to a file in PHP to cache the output of a small portion of code.
ob_start();
echo "Hello";
$fp = fopen("cache/ttcache.php", 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush();
The file exists and is blank. The fwrite function points to the correct location. It just doesn't write.
Any help?
Try to write first small word or sentence first.
fwrite($fp, 'hello')
Also check your file permission's should be writable.
Make sure ob_get_contents() is really not empty. Then try
fflush($fp);
right before fclose().

Categories