Timothy Timothy - 5 months ago 8
PHP Question

How to write into a file before something everytime

I'm trying to figure out how to use fwrite to always write before the
"RewriteRule .(gif|jpg|js|css)$ - [F]"



Here is my code


$website = 'mynewsite.com';

$f = fopen(".htaccess", "a+");
fwrite($f, "RewriteCond %{HTTP_REFERER} !^http://(www\.)?".$website."/.*$ [NC]\n");
fclose($f);




What I want the result to be:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?website1.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?website2.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?website3.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?mynewsite.com/.*$ [NC]
RewriteRule \.(gif|jpg|js|css)$ - [F]




I know you probably shouldn't use php to write to a .htaccess file but where the .htaccess file is located, there is really no security needed.

Thank you for your time! I hope someone can help me! :)

Answer

What you need to do is move the file pointer after opening the file / before writing to the file. There is several ways to do this.

PHP Provides the function fseek() for this. The manual states:

Note:
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.

So, first of all we need to change the mode we open the file in. r+, which is the same as a+ but places the pointer at the beginning seems like a good choice. (See PHP manual for fopen())

Next, we need to move the pointer to the right position.

fseek() can move the pointer based on: the beginning of the file (SEEK_SET), the end of the file (SEEK_END) or the current pointer position (SEEK_CUR). Positive numbers move forward, negative numbers move backwards.

In your case, the data at the end is fixed, so we count backwards from the end of the file.

RewriteRule \.(gif|jpg|js|css)$ - [F] has 37 characters.

The pointer is set in bytes, so the exact amount of data depends on your file encoding. Assuming ASCII, this makes 37 bytes. Note that a newline at the end of your file adds 1 or 2 more bytes, depending on your line-endings (LF or CRLF)

$website = 'mynewsite.com';

$f = fopen(".htaccess", "r+");
fseek($f, -38, SEEK_END);
fwrite($f, "RewriteCond %{HTTP_REFERER} !^http://(www\.)?".$website."/.*$ [NC]\n");
fclose($f);

Another, more portable (as it does not rely on fixed byte count in the line you want to write before, or on it being the last line) way is:

Use fgets() to read the file line-by-line. Compare the data you read to the data you expect to be in the line you are looking for (use regular expressions to compare if you do not know the exact contents).

If you found the line, count how many bytes it had, THEN use fseek() again to move the cursor that many byte back (fgets leaves the pointer at the end of the data it returned)

Then write.

Comments