skip to Main Content

I am unable to find a satisfiable answer to my problem. It’s been three days of surfing and finding nothing that actually works.

My site structure is the following:

·
|__data
|__controllers
|__helpers
|__partials
|__layouts
|__images
|__javascripts
|__stylesheets
|__public
   |__index.php
   |__subfolder
      |__index.php
      |__other-content.php

Since I am allowed to only use the www or html or html_public directory in my server, I want to separate content from all the php and other stuff that users won’t ever see nor use.

I created a directory called /public and put all content the user will see. But now I want to prettify urls for SEO reasons.

I am trying to remove the php and html extention, to remove index.php and to remove the trailing slash from all links including anchors, queries and directories.

Examples:

http://www.domain.com/ must be http://domain.com/

http://domain.com/ must be http://domain.com

http://domain.com/public/ must be http://domain.com

http://domain.com/public/index.php must be http://domain.com

http://domain.com/public/subfolder/ must be http://domain.com/subfolder

http://domain.com/public/subfolder/index.php must be http://domain.com/subfolder

http://domain.com/public/subfolder/#anchor must be http://domain.com/subfolder#ancor

http://domain.com/public/subfolder/?query must be http://domain.com/subfolder?query

http://domain.com/public/subfolder/other-content.php must be http://domain.com/subfolder/other-content

http://domain.com/public/subfolder/other-content.php#ancor must be http://domain.com/subfolder/other-content#ancor

http://domain.com/public/subfolder/other-content.php?query must be http://domain.com/subfolder/other-content?query

I actually don’t use queries yet so it is not important to make them be in those ways, since I should prettify them…

In my htaccess I managed to redirect www to non-www; make /public content as root and hide it from url; remove trailing slash (not in dirs, nor in #ancors); remove index.php

I am trying to force removing the trailing slash from directories but I always get a 403 message, I am also trying to remove the extention but I get a 404 message.

Here is my htaccess:

# Options
Options +FollowSymLinks +MultiViews -Indexes
DirectorySlash off

# Enable Rewrite Engine
RewriteEngine on
RewriteBase /

# Exceptions
RewriteCond %{REQUEST_URI} ^/(images|javascripts|stylesheets)/ [NC]
RewriteRule ^ - [L]

# www to non-www
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301]

# Make /public like it was root
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]

# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^(.+)/$ /$1 [L,R=301]

# Remove index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s(.*)/index.php [NC]
RewriteRule ^ %1 [R=301,L]

# Remove .php extention
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*.php$ %{REQUEST_FILENAME}.php [QSA,L]

# Error pages
ErrorDocument 403 /errors/403.php
ErrorDocument 404 /errors/404.php
ErrorDocument 500 /errors/500.php

EDIT

I have tried the solution from this question but it still give me 403 on directories without trailing slash plus 404 su files without the php extension!

Plus if I type http://domain.com/public it will give me 403. If I type http://domain.com/public/ it will not redirect to root.

# Options
Options +FollowSymLinks +MultiViews -Indexes
DirectorySlash off

# Enable Rewrite Engine
RewriteEngine on
RewriteBase /

# Exceptions
RewriteCond %{REQUEST_URI} ^/(images|javascripts|stylesheets)/ [NC]
RewriteRule ^ - [L]

# www to non-www
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301]

# Make /public like it was root
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]

# remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} s(.+?)/+[?s]
RewriteRule ^(.+?)/$ /$1 [R=301,L]

# To internally forward /dir/file to /dir/file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]

2

Answers


  1. Most of what you are asking for here can be done with:

    Options +MultiViews
    

    One of the results of that directive is that when a resource is requested, such as /whatever MultiViews will transparently serve /whatever.php by scanning the directory for matching resources.

    The trailing slash stuff is not actually necessary, for so-called “SEO reasons” or otherwise. See https://webmasters.googleblog.com/2010/04/to-slash-or-not-to-slash.html for further detail, and save yourself some time and hassle.

    Login or Signup to reply.
  2. Have it this way with MultiViews turned off:

    Options +FollowSymLinks -MultiViews -Indexes
    DirectorySlash off    
    RewriteEngine on
    RewriteBase /
    
    # Exceptions
    RewriteCond %{REQUEST_URI} ^/(images|javascripts|stylesheets)/ [NC]
    RewriteRule ^ - [L]
    
    # www to non-www
    RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
    RewriteCond %1##%{HTTPS}s ^(.+)##(?:on(s)|)
    RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301,NE]
    
    # Make /public like it was root
    RewriteCond %{THE_REQUEST} s/+public/(S*?)/?s [NC]
    RewriteRule ^ /%1 [L,R=301,NE]
    
    # remove trailing slash from all URLs
    RewriteCond %{THE_REQUEST} s(.+?)/+[?s]
    RewriteRule ^(.+)/$ /$1 [R=301,L,NE]
    
    # To externally redirect /dir/file.php to /dir/file
    RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
    RewriteRule ^ /%1 [R=301,NE,L]
    
    # Make /public like it was root
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^.*$ public/$0 [L]
    
    # internally add trailing / to directories
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule !/$ %{REQUEST_URI}/ [L]
    
    # To internally forward /dir/file to /dir/file.php
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
    RewriteRule ^(.+?)/?$ $1.php [L]
    

    But keep in mind that for a web server http://domain.com/ is same as http://domain.com and web server gets / in both cases. It is your browser that adds a / after http://domain.com.

    Clear your browser cache when testing this change.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search