Removing slash in url (not trailing slash) - php

I have a folder named people on my server, and index.php in that folder
My url is like mydomain.com/people/?name=value1&age=value2
But I really want it to look like mydomain.com/people?name=value1&age=value2

Since "people" is a folder and your script is in that folder, the only way for this to work is if you turn off DirectoryIndex, which automatically redirects the browser to include a trailing slash for any request that's for a folder.
Note, this is a trailing slash, the URI ends with /people/. The ? and everything after it is the query string.
Turning off DirectoryIndex can be very dangerous, as it is used to prevent information disclosure. Without a trailing slash on your folders, requesting a folder will result in displaying the contents of that folder even if you have a directory index. In other words, index.php is ignored and instead, you get a listing of all your folder's contents. So to prevent that from happening, you have to internally add the slash back.
So something like this in the htaccess file of your document root:
DirectoryIndex Off
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /+people/\?
RewriteRule ^ /people [L,R]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/ [L]

Using mod_rewrite you can do it like this:
RewriteEngine On
RewriteRule ^(.+)/$ $1 [L,R,QSA]
QSA here is not required since it stands for Query String Append and it's on by default.

Related

htaccess - Force a slash to the end of a dynamic URL

I have a single index.php file in a /slug subdirectory and would like to load dynamic content based on the file path. Regardless of what the url is, the content should reference that index.php.
In my code below, the slash is not being added at the end of the url. For example, example.com/slug/33 should be displayed in the address bar as example.com/slug/33/.
I have the following .htaccess in /slug:
Options -Indexes
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# Dynamic url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /slug/index.php/?path=$1 [NC,L,QSA]
I tried adding a / between index.php and ?path=$ but I'm not getting the desired result. Is this even possible?
RewriteRule ^(.*)$ /slug/index.php/?path=$1 [NC,L,QSA]
Changing the substitution string here changes the target of your internal rewrite - it does nothing to change the visible URL. By adding a slash after index.php you are (unnecessarily) adding additional pathname information (path-info) to the resulting URL that your application receives.
To change the visible URL (to append the slash) you need to implement an external redirect. However, to confirm... you must already be linking to the correct canonical URL (ie. with a slash) in your internal links. Appending the slash to the URL in .htaccess is only if you have changed the URL and search engines or 3rd parties are still using the old non-canonical URL (without a trailing slash).
Since the .htaccess file is in the /slug subdirectory and you are rewriting to index.php in that subdirectory then you don't need to prefix the rewritten URL with /slug/. By default, a relative URL-path is relative to the directory that contains the .htaccess file. However, you must also remove the RewriteBase directive (or set this "correctly" to RewriteBase /slug).
To redirect to append a trailing slash you can add the following before the current rewrite:
# Append trailing slash if omitted
RewriteRule ^(.*(?:^|/)[^/.]+)$ /slug/$1/ [R=301,L]
This requires the /slug/ prefix on the substitution string (unless RewriteBase /slug is set), otherwise the external redirect will attempt to redirect to a file-path, which will "break".
The RewriteRule pattern ^(.*(?:^|/)[^/.]+)$ captures URL-paths that do not already end in a slash and do not contain a dot in the last path segment. This is to avoid matching URLs that already contain (what looks-like) a file extension, ie. your static resources (images, CSS, JS, etc.). This should avoid the need for a filesystem check (which are relatively expensive) - to check that the request does not already map to a file. Although, if you are not referencing any static resources with the /slug/ prefix in the URL then this can be simplified.
NB: You should first test with a 302 (temporary) redirect to avoid potential caching issues.
In context (with the use of RewriteBase):
Options -Indexes
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /slug
# Append trailing slash if omitted
RewriteRule ^(.*(?:^|/)[^/.]+)$ $1/ [R=301,L]
# Dynamic url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) index.php?path=$1 [QSA,L]
The use of RewriteBase avoids you having to specify /slug/ in the other directives.
In the regex ^(.*)$, the start-of-string (^) and end-of-string ($) anchors are superfluous. And you might as well change this to use the + quantifier, since you don't want to match the base directory anyway (saves two additional filesystem checks). The NC flag was also superfluous here.

how to remove the .php extension from url, for a file named same like a folder

I used this code
## remove the php extention
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
This works for some files the e.g. example.com/contact, but doesn't work when I have a .php file that is also a directory. For example, in the root folder:
science.php
science - folder
The articles are in categories e.g. http://example.com/science/themost-blabla.php - this works, the .php extionsion doesn't appear in the URL.
So I want to know if is any possible to hide the .php extension to science.php because when I type example.com/science ... it redirects me to the content of the science folder....
Index of /science directory:
afla-care-a-fost-primul-meci-televizat-de-fotbal-din-lume-1937-arsenal.php
cazinoul-din-constanta.php cele-7-minuni-ale-lumii.php
descoperire-colosala-a-epavei-navei-spaniole-san-jose-ce-avea-la-bord-o-avere-impresionanta.php
imagini/ mitologia-greaca.php poenaru.php
top-10-cele-mai-importante-inventii-romanesti-din-istorie.php
top-5-enigme-ale-lumii.php turnul-eiffel.php
So, can I do something to hide the extension to this page? Or do I need to change the name of the file - to not be the some as the folder?
Try this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
One of the "problems" is that mod_dir will try to "fix" the URL when accessing a directory by appending a slash to the end of the URL. However, this can be disabled.
# Prevent mod_dir from automatically appending slashes to directories
DirectorySlash Off
# Disable directory listings
# In cases where there is a directory with no similar .php file and no DirectoryIndex
Options -Indexes
# If a PHP file exists for the requested URL then rewrite to this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*) $1.php [L]
If required, bare directories (or rather, the DirectoryIndex) can be accessed by explicitly appending a slash to the URL. eg. example.com/science/. However, this is presumably unnecessary (and probably best avoided to avoid user confusion) since I assume example.com/science (no trailing slash, ie. science.php) returns your "science" category content. Without a DirectoryIndex document, example.com/science/ will simply return a 403 Forbidden. Alternatively you could explicitly remove trailing slashes from such URLs with an external redirect.

How to do both internal and external .htacces rewrite to completely remove ALL QUERY_STRING elements from ALL URIs, with relative path

I want to remove all client request querystrings whatsoever, no exceptions.
I have tried everything I can find, and everything I know about regular expressions, and this task puzzles me. I have been able to achieve removal of the query strings, but now all requests have the full file path prepended to the working directory upon rewrite and redirect.
Examples: there is no http in these because stackoverflow won't let me post URLs.
I access the file: /localhost/testing/dogs/pups.txt
Yes, pups.txt exists and lives right there.
Server returns this to browser: /localhost/home/user/public_html/testing/dogs/pups.txt
If I access it with a query string appended:
/localhost/testing/dogs/pups.txt?bark=woof
I get the same output to the browser:
/localhost/home/gost/public_html/testing/dogs/pups.txt
So I know the query string is being nixed, while the full root path is being added to the hypertext address.
How do I tell mod_rewrite to keep the relative path of the existing files, so that this prepending of the full file path stops, and accurately cause it to rewrite internally and externally so that no query string ever makes it to php-land?
Here is the current .htaccess file. It resides in directory /home/user/public_html/testing. Where deployed online, it is NOT possible to put it in the root web directory, the obvious move that would instantly resolve this problem.
# These are commented out on purpose because they kill access to the server.
# The weird rules for regex in Apache configurations is baffling me. This
# does remove all QUERY_STRING characters, but, it then rewrites by
# prepending the web root path to the current directory, causing error 404.
# RewriteCond %{QUERY_STRING} ^
# RewriteRule (.*) $1? [R=301,L]
# These rules work fine. Whatever does not end with a media or document
# extension gets sent to index.php
RewriteRule ^.*\.(gif|jpe?g|png|txt|svg|pdf|rtf|odt|doc|docx)$ - [L]
RewriteRule ^.*\.(tex|epub|mobi|csv|ods|xls|swf|flv)$ - [L]
RewriteRule ^ index.php [L]
Change this RewriteCond %{QUERY_STRING} ^ to this RewriteCond %{QUERY_STRING} .
and add the directory to the rule since you can't use rewritebase. So it should look like this
RewriteCond %{QUERY_STRING} .
RewriteRule (.*) /testing/$1? [R=301,L]
I can't accept my own answer for two days, so if anyone wants to add logic about mod_rewrite for future questioners, have at it. Per Panama Jack's advice, this .htaccess file does the job and this question is answered.
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule (.*) /testing/$1? [R=301,L]
RewriteRule ^.*\.(gif|jpe?g|png|txt|svg|pdf|rtf|odt|doc|docx)$ - [L]
RewriteRule ^.*\.(tex|epub|mobi|csv|ods|xls|mm|)$ - [L]
RewriteRule ^ test.php [L]

mod_rewrite with Trailing Slash breaks CSS/IMG/SCRIPTS paths

I'm trying to make mod_rewrite the first sub-directory string from url in order to create similar functionality as 'jsfiddle.net saved url's within a class/db. The script works fine and does the rewrite.
e.g. of url
http://jsfiddle.net/RyEue/
This works fine (loads all css, scripts, etc.):
http://www.domain.com/787HHJ2
This is what I've used in the past which does the trick.
The problem Is when ending URL with last slash, script, css and others loose path.
http://www.domain.com/787HHJ2/
rewrite script:
DirectoryIndex index.php index.html
Options +FollowSymlinks
RewriteEngine On # Turn on the rewriting engine
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !.
RewriteRule ^.+/?$ index.php [QSA,L]
Unsure if this has to do with Rewritebase, I've tried multiple ways.
PS. I've tried setting paths to absolute (e.g. src="/img/theimage.jpg") without luck.
1. Make sure you have css/images/js etc linked relative to root folder (with leading slash): /styles/main.css
2. Add one of these ruls before current one:
# do not touch files with .css/.js/.jpg etc extensions
RewriteRule \.(css|js|jpg|png|gif)$ - [L]
or
# do not touch any resources in images/css/js folders
RewriteRule ^(images|css|js)/ - [L]
3. Clear browser caches and restart (sometimes browser may display cached page/resource when rewrite rule was fixed which brings a lot of confusion).
Try escaping
RewriteRule ^.+\/?$ index.php [QSA,L]

Why does .htaccess only receive index.php as input

I have added a .htaccess file to my root folder, and i wanted everything written after the / to be sent to the index.php file as get data.
My root path looks like this http://www.site.com/folder/ and my .htaccess is located in the folder directory together with index.php
This is my .htaccess file:
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*) index.php?args=$1
Now, what ever i write behind folder/ in my url, args is "index.php". So when i visit www.site.com/folder/lots/of/bogey the args variable is "index.php"
My goal is obviously to have the args variable be "lots/of/bogey". Any ideas what I'm doing wrong?
You don't need a RewriteCond. The following will work:
RewriteRule ^(.*)$ index.php?args=$1 [L,QSA]
The L makes it stop matching rewrite rules, and QSA is for appending to query string in a rewrite rule. Refer to mod_rewrite
I think that's because after executing the RewriteRule and getting index.php?args=... the RewriteRule gets called again. Now index.php is your filename, so it get's passed as args. After this mod_rewrite aborts due to recursion. To fix this, add a RewriteCond which enures the file isn't index.php.
You'll have at least to exclude index.php from the redirect:
RewriteCond $0 !^index\.php$
RewriteRule .* index.php?args=$0 [QSA,B]

Categories