fopen mode w+ and reading the file? - php

I'm going through all the modes and trying to understand where can you apply some of them, and I stumbled upon w. Now I understand how that mode works, but what's the purpose of w+? Obviously if we use fopen right after opening the file, it won't work since the file will be truncated, so I assume it's good to write something in the file and then read from it later on, so I decided to test it like so:
$handle = fopen('new.txt', 'w+');
fwrite($handle, '123');
$file = fread($handle, filesize('new.txt'));
var_dump($file); // string '' (length=0)
fclose($handle);
For some reason it doesn't read the contains of the file later.
Could someone explain to me please where could it applicable, and what is wrong with my code? filesize returns 3, so it doesn't delete the contents of the file, I assume that the $handle might be used from the moment we opened the file and it doesn't update? Then it confuses me even more why would we use mode w+ and doing reading from a file at the same time?
Edit: I can understand even how I can write something in the file with r+ and then check what I've written with using fopen again, like so:
$handle = fopen('new.txt', 'r+');
fwrite($handle, '123');
$handle = fopen('new.txt', 'r+');
$file = fread($handle, filesize('new.txt'));
var_dump($file);
fclose($handle);
If I would do the same with w+, it would just delete the contents obviously, and I would not be able to read anything?

fopen() with w+ option opens the file for read/write at the beginning and truncates the length to 0. It's essentially the same as writing to a new empty file.
See fopen() usage here: http://php.net/manual/en/function.fopen.php
w+ is mainly used to "read back" what you've written. In your case you are using fread() function which reads "forward" from your pointer which is currently sitting at the end of the file after doing fwrite(), which would explain why you are getting empty contents.
I hope this answers your question.

#Ye. is right about the pointer. Once you have executed fwrite, then the pointer will be at the end of the file. What you need is fseek() to go back to the beginning of the file.
$handle = fopen('new.txt', 'w+');
fwrite($handle, '123');
fseek($handle, 0);
$file = fread($handle, filesize('new.txt'));
var_dump($file); // string '123' (length=3)
fclose($handle);

Related

fopen() with r+ acts like a?

This is some of the weirdest stuff I've ever honestly seen.
$filename = "/etc/httpd/conf/httpd.conf";
$handle = fopen($filename, "r+");
$size = filesize($filename);
$contents = fread($handle, $size);
fwrite($handle,$contents);
fclose($handle);
Shouldn't this read the contents of the file then write it again? Basically leaving the file unmodified? At this moment this piece of code does exactly what append does, it duplicates the contents of the file adding $contents at the end of the file, and I have no idea why. I tried changing the string a little before writing it and that's how I found out it writes to the end, not the beginning.
Your fread() is advancing the file pointer such that by the time you call fwrite, your file pointer is at the end and your write appends to the file from there.
If you want to write to the file starting at the beginning after reading it all in then:
rewind($handle);

Fwrite save a null file

I have a code in which should open an existing text file into my server, save the text into a variable, then filter the text contained within this variable and save again, as you can see below:
Text File:
Descrição: lorem impsum is a dollar do dolla do dolla style user humam
Source Code:
$filename = "prods/".$value;
$handle = fopen($filename, "w+");
$contents = fread($handle, filesize($filename));
$newcontent .= str_replace("Descrição:", "Descricao:", $contents);
fwrite($handle,$newcontent);
fclose($handle);
The problem is the command write is saving the file again with null text inside him, how can I solve this?
According to http://php.net/manual/en/function.fopen.php:
'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.
You are therefore reading an empty string, and writing such a string back too.
The simplest way to solve your problem might be:
$filename = "prods/".$value;
$contents = file_get_contents($filename);
$newcontent .= str_replace("Descrição:", "Descricao:", $contents);
file_put_contents($filename, $newcontent);
Your problem is the mode 'w+' you use for fopen.
I think a+ is the one you're looking for.
w+ mode truncates the file to 0 length. You want to use c+ or file_get_contents(), then file_put_contents() instead.

Why does fopen('file.txt', 'r+') followed by write() truncate the file?

I test this PHP code on windows and it first removes the file.txt contents and then write the new contents on it.
$f = fopen('file.txt', 'r+');
fwrite($f, "first-time");
fclose($f);
Every time I execute this code and see file.txt, it has ONE "first-time" in it.
I expect it to prepend "first-time" to the old file. like:
first-timefirst-timefirst-time and so on.
Why r+ acts like w+ in making zero length?
Answer to your question: Your code does not truncate the file, but simply overwrites the previous content.
Quick and dirty solution for the behaviour your want to achieve:
<?php
$file_data = "Stuff you want to add\n";
$file_data .= file_get_contents('file.txt');
file_put_contents('file.txt', $file_data);
?>
EDIT:
The answer can be found here:
How do I prepend file to beginning?
According to the PHP fopen manual:
'r+' Open for reading and writing; place the file pointer at the beginning of the file.
'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.
$f = fopen('file.txt', 'a+');
fwrite($f, "fisrt-time");
fclose($f);
So if you'd like to append content, use a+ mode.

How to clear a text file ready for fwrite

I have a text file that is being written with fwrite, how would I delete all the contents of this text file so that I can write onto it a fresh. I've tried to find another function but with no luck.
Example code I am using, I want to clear it before I enter this information:
$string = ', {"key": "'.$info['Name'].'", "value": "'.$info['Name'].'"}';
$fp = fopen('data_old.txt', 'a');
fwrite($fp, $string);
fclose($fp);
If you look at the PHP documentation for fopen, you will see the list of "modes" available in the second parameter. You are passing "a" which means append. You want to pass "w" which means "write".
'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.
'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 can change your mode parameter in fopen:
$fp = fopen('data_old.txt', 'w+');
By the way, I used w+ in case you want to read from it as well, for just writing you can use w.
Use the w option instead of the a option in fopen.
like fopen('file.txt','w');
this puts the pointer at the beginning of the file instead of the end
http://php.net/manual/en/function.fopen.php
To overwrite an existing file use the write only mode with fopen, which will open the file for writing and set the point to the beginning of the file and also truncate the file to zero length:
$string = ', {"key": "'.$info['Name'].'", "value": "'.$info['Name'].'"}';
$fp = fopen('data_old.txt', 'w');
fwrite($fp, $string);
fclose($fp);
You can do this another way
$file_destination = "./your_text_file_name.txt";
unlink($file_destination);
$your_data = "ABCabc";
$handle = fopen ($file_destination, "a+");
fputs($handle, $your_data);
fclose($handle);

How can I overwrite file contents with new content in PHP?

I tried to use fopen, but I only managed to append content to end of file. Is it possible to overwrite all contents with new content in PHP?
Use file_put_contents()
file_put_contents('file.txt', 'bar');
echo file_get_contents('file.txt'); // bar
file_put_contents('file.txt', 'foo');
echo file_get_contents('file.txt'); // foo
Alternatively, if you're stuck with fopen() you can use the w or w+ modes:
'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.
'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.
$fname = "database.php";
$fhandle = fopen($fname,"r");
$content = fread($fhandle,filesize($fname));
$content = str_replace("192.168.1.198", "localhost", $content);
$fhandle = fopen($fname,"w");
fwrite($fhandle,$content);
fclose($fhandle);
MY PREFERRED METHOD is using fopen,fwrite and fclose [it will cost less CPU]
$f=fopen('myfile.txt','w');
fwrite($f,'new content');
fclose($f);
Warning for those using file_put_contents
It'll affect a lot in performance, for example [on the same class/situation] file_get_contents too: if you have a BIG FILE, it'll read the whole content in one shot and that operation could take a long waiting time

Categories