Add Trailing Slash with Apache Files and ForceType

Discuss practical ways rearrange URLs using mod_rewrite.

Add Trailing Slash with Apache Files and ForceType

Postby DamonG » Mon May 26, 2008 8:30 pm

Richard, thanks for answering everyone's questions. This site is a great resource.

I have a problem that I can't find the answer to anywhere. We'll maybe I've found the answer, but didn't realise it.

I'm using Apache's <Files> and ForceType with some PHP code to create directory-style URLS for my dynamic site.

The problem is that the pages work with or without trailing slashes. The application consistently uses trailing slashes; I would like to add trailing slashes to URLs missing the trailing slash. I found some rewrite rules here that look like they should work, but don't.

The script that creates the URLs looks like this:

Code: Select all
<A HREF=myscript/".str_replace("%20", "_", rawurlencode($var1))."/".str_replace("%20", "_", rawurlencode($var2))."/>".Anchor Text</A>


My .htaccess file looks like this:

Code: Select all
Options +FollowSymlinks
RewriteEngine On

# If it's not a request for a real file.
RewriteCond %{SCRIPT_FILENAME} !-f
# Add the trailing slash. I removed the L flag because I want to process the next rule, <Files myscript>, but it's not actually a mod_rewrite rule so maybe I can leave it in.
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301]

<Files myscript>
ForceType x-mapp-php4
</Files>

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) http://mydomain.com/error.php [L]

rewriteCond %{http_host} ^www.mydomain.com [nc]
rewriteRule ^(.*)$ http://mydomain.com/$1 [r=301,nc,L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php
RewriteRule ^index\.php$ http://mydomain.com/ [R=301,L]



And the script, named myscript (without extension) in the above .htaccess file, looks like this:

Code: Select all

$data = explode("/", $HTTP_SERVER_VARS['PATH_INFO']);
$var1_name = $data[1];
$var1_name = str_replace("_", " ", $var1);
$query = "MySQL query that selects corresponding unique ID";
$select = mysql_query($query);
$var1id = mysql_result($select, 0);

$var2_name = $data[2];
$var2_name = str_replace("_", " ", $var2_name);
$query = "MySQL query that selects corresponding unique ID";
$select = mysql_query($query);
$var2id = mysql_result($select, 0);



Thanks for any help.

Damon
[/code]
DamonG
 
Posts: 10
Joined: Mon May 26, 2008 7:39 pm

Postby richardk » Wed May 28, 2008 2:25 pm

The problem with it is a request to /myscipt is for an existing file. Are there a lot of them to add slashes to? Do they ever contain "."s? Do they ever contain "/"s?

I removed the L flag because I want to process the next rule, <Files myscript>, but it's not actually a mod_rewrite rule so maybe I can leave it in.

You should have the L flag when doing redirects as you want that done before any other processing. You are correct in thinking <Files> is not affected by the L flag.

Cleaned up the other bits
Code: Select all
Options +FollowSymLinks
ErrorDocument 404 /error.php

RewriteEngine On

RewriteCond %{THE_REQUEST} \ /index\.php(\?.*)?\  [NC]
RewriteRule ^index\.php$ http://mydomain.com/ [R=301,L]

RewriteCond %{HTTP_HOST} ^www\.(mydomain\.com)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

<Files myscript>
    ForceType x-mapp-php4
</Files>
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby DamonG » Wed May 28, 2008 3:49 pm

I really appreciate your help with this. Thanks a lot.

Are there a lot of them to add slashes to?


I wrote trailing slashes in to the application, so, from the application end, there aren't any rewrites to be done.

I just want the rule to prevent duplicate content issues from people linking to a page without the slash and to be consistent.


Do they ever contain "."s? Do they ever contain "/"s?


It's user-submitted content so yes, but they do get put through the PHP rawurlencode function first. Actually, I'm still trying to get URLs with "/' in them to work.

One question. Does Apache or ModRewrite read encoded characters like %F2 (the slash "/" character)?

I played with the cleaned up rules a bit and was curious about the reasoning for changing the code that removes index.php. The original version removes index.php from all subdirectories so mysite/blog/index.php gets rewritten to mysite/blog/ and mysite/media/index.php gets rewritten to mysite/media/ whereas your rule only works with the root.

Is it better (faster, easier on the server) to create a rule for each index, or to create the slightly more complicated rule that applies globally?

Thanks.

d.
DamonG
 
Posts: 10
Joined: Mon May 26, 2008 7:39 pm

Postby richardk » Sun Jun 01, 2008 10:41 am

Are there a lot of them to add slashes to?

I wrote trailing slashes in to the application, so, from the application end, there aren't any rewrites to be done.

The amount of URLs (or types of URLs) that will need matching. How many different PHP files are there? Do all the URLs you need the trailing slash added to start with one of these file names?

It's user-submitted content so yes, but they do get put through the PHP rawurlencode function first. Actually, I'm still trying to get URLs with "/' in them to work.

Right.

One question. Does Apache or ModRewrite read encoded characters like %F2 (the slash "/" character)?

It works for me.

I played with the cleaned up rules a bit and was curious about the reasoning for changing the code that removes index.php. The original version removes index.php from all subdirectories so mysite/blog/index.php gets rewritten to mysite/blog/ and mysite/media/index.php gets rewritten to mysite/media/ whereas your rule only works with the root.

This?
Code: Select all
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php
RewriteRule ^index\.php$ http://mydomain.com/ [R=301,L]

It should not.

If that is what
Code: Select all
RewriteCond %{THE_REQUEST} \ /(.+/)?index\.php(\?.*)?\  [NC]
RewriteRule ^(.+/)?index\.php$ http://mydomain.com/$1 [R=301,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby DamonG » Sun Jun 01, 2008 1:33 pm

The amount of URLs (or types of URLs) that will need matching. How many different PHP files are there? Do all the URLs you need the trailing slash added to start with one of these file names?


There are four PHP files all of them use Apache's Files and ForceType. The URL's all have the following format:

mysite.com/myscript1/user-submitted_category/user-submitted_title/

myscript1 is the name of the PHP file (without extension). Each PHP file has a different name in this position.


user-submitted_category is a category with with spaces replaced with the underscore (_) character. The likelihood of a slash (/) here is very low, but periods (.) are a definite possibility.


user-submitted_title is used to identify the correct data to pull from the database. There are slashes and periods that need to be accounted for.

All other files in the site either have the .php extension or are *real* directories. The files with .php extension don't need to have trailing slashes added.

I hope that covers everything.

d.
DamonG
 
Posts: 10
Joined: Mon May 26, 2008 7:39 pm

Postby richardk » Tue Jun 03, 2008 1:53 pm

The URL's all have the following format:

mysite.com/myscript1/user-submitted_category/user-submitted_title/

myscript1 is the name of the PHP file (without extension). Each PHP file has a different name in this position.

Excellent, then it can be limited to those 4 prefixes
Code: Select all
Options +FollowSymLinks
ErrorDocument 404 /error.php

RewriteEngine On

# Add missing trailing slashes.
RewriteRule ^(file1|file2|file3|file4)(/.*[^/])?$ http://mydomain.com%{REQUEST_URI}/ [R=301,L]

RewriteCond %{THE_REQUEST} \ /(.+/)?index\.php(\?.*)?\  [NC]
RewriteRule ^(.+/)?index\.php$ http://mydomain.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^www\.(mydomain\.com)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

<FilesMatch "^file1|file2|file3|file4$">
    ForceType x-mapp-php4
</FilesMatch>
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby DamonG » Thu Jun 05, 2008 10:12 am

Excellent.

Thanks for your help.

d.
DamonG
 
Posts: 10
Joined: Mon May 26, 2008 7:39 pm


Return to Friendly URLs with Mod_Rewrite

Who is online

Users browsing this forum: No registered users and 89 guests

cron