Duplicate entries with file_put_contents when RewriteEngine on

I am setting up a logging system in an app and while testing writing a log to a file using file_put_contents() I noticed it was writing each log to the file twice.

To try to isolate the cause, I wrote the relevant code directly into the entry file (index.php) as follows:


$logfile = '..\\Logs\	est.log';
$str = "Hello\
";
file_put_contents($logfile, $str, FILE_APPEND);

At each load, this would append "Hello
Hello
" to the file.

It appears that the double entries are somehow related to the rewrite rules in the .htacess file.

.htaccess file contains the following:


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

If I change RewriteEngine to off, and reload the page, it only appends the text once, i.e. "Hello
"

Any ideas why these duplicate entries are occurring and how I can prevent them?

Windows 7
XAMPP 1.7.4
PHP 5.3.5

First off…Your rewrite rule makes no sense, why do you have two of them?


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-s [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? index.php [NC,L]

There thats all you need…

Thanks for your response, logic_earth.

I admit I am no expert when it comes to writing rewrite rules, but my understanding of what I had is that the first rule would be applied if the conditions were met and the second would be applied if they were not. Your version is more concise though.

Regardless, the issue still occurs even with your version.

@KiwiJohn,

Using the rewrite rules you have shown and the PHP code you have shown, I only get 1 Hello in the log file for each page load.

Crap! Then it must be something else specific to my system.

Thanks for letting me know.

This is crazy!

I just set up a totally separate folder to test in. Here is the structure:


C:
|
+ xdev
    |
    +logtest
        |
        + .htaccess
        |
        + index.php
        |
        + Logs (folder)

In httpd-vhosts.conf I have:


<VirtualHost *:80>
    ##ServerAdmin postmaster@dummy-host2.localhost
    DocumentRoot "C:/xdev/logtest"
    ServerName lt.tld
    ServerAlias lt.tld
    ErrorLog "logs/lt.tld-error.log"
    CustomLog "logs/lt.tld-access.log" combined
</VirtualHost>

In index.php I have:


<?php
$logfile = 'Logs\	est.log';
$str = "Hello\
";
file_put_contents($logfile, $str, FILE_APPEND);

In .htaccess I have:


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-s [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]

I enter lt.tld into the browser, hit enter, and C:\xdev\Logs\ est.log is created with the following:


Hello
Hello


And every time I hit refresh, it adds 2 more lines of “Hello”

What could possibly be causing this?

I’m not sure, but I’ll copy your virtual host and see if I get the same thing. Granted, I am on a different setup than you, I am actually running Apache2 on a Linux box.

Hmmm… the plot thickens…

I have been testing with Google Chrome, but just tried some other browsers to see what would happen.

With Firefox 12 and IE 9 only one line is added on each refresh.

With Opera 11.64 and Chrome 19 two lines are added on each refresh.

Okay, I can recreate it now. I’m investigating.

Thanks! I appreciate you taking the time to help. I have no idea what to try next.

Okay, I got this figured out now.

First your Rewrite Cond are wrong. You DO NOT want to use [OR} as effectively you are stating if the request is Not a File with Size, or Not a Symbolic Link, or Not a Directory, then run this rule. Nothing can be ALL three of those things.

So now you have

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]

If you run that again, you will still get two entries. Why? Well, for this you need to look at the access.log file. You will notice there is a GET for index.php and a GET for favicon.ico. If your setup is like mine, you don’t have a favicon.ico, so your Rewrite Rule kicks in and redirects it to index.php which causes a second log entry.

So I created a blank favicon.ico (just right-click create text file, and rename it to favicon.ico removing the .txt extension)

Now, run it again, and you MAY still get two entries. Why? Because your favicon.ico has a size of 0. The !-s means a file WITH SIZE. So you can either create a REAL favicon.ico or you can change your rewrite rule to be !-f like so:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]

Enjoy!

YOU ARE AWESOME!!!

Worked a charm. Thanks for the help. I especially appreciate your detailed explanation of what was causing the problem and how to solve it.