IIS Rewrite problems - catching all .php files

131 views Asked by At

In a folder I have several .php files (more than 10)

aaa.php
bbb.php
ccc.php
ddd.php
index.php

What I'm trying to achieve is properly re-writing them so as to have friendly URLs. The rewrites are:

www.domain.com/data -> www.domain.com/data/index.php
www.domain.com/data/ -> www.domain.com/data/index.php
www.domain.com/data/aaa -> www.domain.com/data/aaa.php
www.domain.com/data/aaa/ -> www.domain.com/data/aaa.php
www.domain.com/data/aaa/chapter1 -> www.domain.com/data/aaa.php?c=chapter1

www.domain.com/data/bbb -> www.domain.com/data/bbb.php
www.domain.com/data/bbb/ -> www.domain.com/data/bbb.php
www.domain.com/data/bbb/chapter1 -> www.domain.com/data/bbb.php?c=chapter1

...

By using the following rules I achieve what I want for single php files

<rule name="Friendly1" stopProcessing="true">
    <match url="^aaa$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="aaa.php" appendQueryString="false" />
</rule>
<rule name="Friendly2" stopProcessing="true">
    <match url="^aaa/$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="aaa.php" appendQueryString="false" />
</rule>
<rule name="Friendly3" stopProcessing="true">
    <match url="^aaa/(.+)\.(.+)$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}.{R:2}" appendQueryString="false" />
</rule>
<rule name="Friendly4" stopProcessing="true">
    <match url="^aaa/(.+)$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="aaa.php?c={R:1}" appendQueryString="false" />
</rule>

That works. However it's not efficient and it's error prone copypasting those rules for every php file in the folder.

So, I thought of exchanging the aaa with (.+) in the rules and it doesn't work for some cases.

<rule name="Friendly1" stopProcessing="true">
    <match url="^(.+)$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}.php" appendQueryString="false" />
</rule>
<rule name="Friendly2" stopProcessing="true">
    <match url="^(.+)/$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}.php" appendQueryString="false" />
</rule>
<rule name="Friendly3" stopProcessing="true">
    <match url="^(.+)/(.+)\.(.+)$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}.php/{R:2}.{R:3}" appendQueryString="false" />
</rule>
<rule name="Friendly4" stopProcessing="true">
    <match url="^(.+)/(.+)$" ignoreCase="true"/>
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}.php?c={R:2}" appendQueryString="false" />
</rule>

It works for the following cases:

www.domain.com/data -> www.domain.com/data/index.php
www.domain.com/data/ -> www.domain.com/data/index.php
www.domain.com/data/aaa -> www.domain.com/data/aaa.php

It doesn't work for the following cases:

www.domain.com/data/aaa/ -> www.domain.com/data/aaa.php
www.domain.com/data/aaa/chapter1 -> www.domain.com/data/aaa.php?c=chapter1

For which cases I get a "not found". Am I doing something wrong? How can I solve this ?

IIS = 7.5+

Thank you in advance.

1

There are 1 answers

0
Scott Anderson On

How about this...

<rewrite>
   <rules>
       <rule name="Friendly1" stopProcessing="true">
           <match url="^data/([-a-zA-Z0-9]*)/[-a-zA-Z0-9]*)$" ignoreCase="true" />
           <action type="Rewrite" url="data/{R:1}.php?c={R:2}" />
        </rule>
       <rule name="Friendly2" stopProcessing="true">
           <match url="^data/([-a-zA-Z0-9][-a-zA-Z0-9]*)$" ignoreCase="true" />
           <action type="Rewrite" url="data/{R:1}.php" />
        </rule>
        <rule name="Friendly3" stopProcessing="true">
           <match url="^data(/.*)$" ignoreCase="true" />
           <action type="Rewrite" url="data/index.php" />
        </rule>
    </rules>
</rewrite>