my boss wants me to code an URLrewriting for, let's say "http://our.domain.com/SomeText" -- that is, if the URL does NOT contain ".php" or ".html", it should be processed by a script like "http://our.domain.com/process.php?string=SomeText".
Is this possible with a simple regex? I just cannot find the right expression to do this.
I started by redirecting requests to some special subdir, but now it should work directly without any further subdir, so I somehow have to separate regular requests for exuisting pages to requests that don't contain ".php" or ".html"...
Any advice or link for me?
Best regards,
Roman.
Something like this should do the trick
RewriteEngine on
RewriteCond %{REQUEST_URI} !\.php
RewriteCond %{REQUEST_URI} !\.html
RewriteRule (.*) /process.php?string=$1 [QSA]
there are some caveats regarding if this will go in .htaccess or directly in the VirtualHost definition (to put or not a leading /).
Additionally you should load mod_rewrite.
All this supposing you are actually using Apache and can use mod_rewrite.
What this does is that if the requested URI doesn't contain the strings .php and .html it then internally redirects the requests to the process.php file with what was written as a query string argument.
If you have problems with this then use
RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 9
and check how it is working. For this to work you have to control the server, as it has to be used in a main configuration file (no .htaccess possible).
Using mod_rewite you could do this to re-write .php and .html URLs like this:
RewriteEngine on
RewriteRule !\.(php|html)$ process.php/$1 [NC] [QSA]
However you may also want to stop it from re-writing URLs to files which actually exist. (There may be other files lying around - images/css etc. which you don't want to be re-written) You could amend the above to add checks:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(php|html)$ process.php/$1 [NC] [QSA]
Adding this check may mean that you don't actually need check whether the extension is anything other than .php or .html, because you know that it will only be rewritten if the requested file does not exist, so you could amend the RewriteRule line to be this:
RewriteRule ^(.*)$ process.php/$1 [NC] [QSA]
This will mean any requested URL that does not exist as a file will be handled by process.php.
why you dont use mod rewrite ?
link to explain :
http://www.workingwith.me.uk/articles/scripting/mod_rewrite
At least with mod_rewrite you can use a regex which matches .php and .html, and then prepend that with a !, which should negate it.
Related
I'm trying to figure out how to combine rewriting and redirecting URLs with .htaccess. My specific example is: initially I wanted to remove file extensions from page URLs, so I set this up to make /page display the content of /page.php:
# URLs without file extension lead to the file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
But then I found that if a trailing slash is mistakenly added, it will still cause an error - i.e. /page/ doesn't work. I'd like someone to be able to navigate to /page/ (because if it gives a 404, that really suggests that /page doesn't exist, even though it does) - but I also want to rewrite their URL to remove the slash so the mistake doesn't happen again.
So, I want two things to happen when someone navigates to /page/.
The URL is rewritten to /page.
The page loads content from /page.php.
While also keeping the rule that navigating to /page itself will load /page.php.
Is there a way to combine this behaviour into one rewrite rule? If not, how do I make it happen with two separate rules and prevent feedback loops?
The “problem” here is this check,
RewriteCond %{REQUEST_FILENAME}\.php -f
If page/ was requested, you will have to cut off that trailing slash here, before you append .php and check if that’s an existing file. But that’s not that easy to do when you only have %{REQUEST_FILENAME} available, and not much in terms of “string functions” …
But, the RewriteRule is evaluated first anyway, so you can achieve this by matching what comes before an (optional) trailing slash inside the rule first, and then use the back reference this creates inside the condition to perform this check:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1.php -f
RewriteRule ^(.*)/?$ $1.php [NC,L]
So far for the theory, not tested in practice ;-) Not too sure whether checking for an existing file works with a relative path only - otherwise, you might have to prefix that with a different variable such as maybe the DOCUMENT_ROOT.
Might be that you need to be a bit more specific in what your rule is allowed to match also, because right now it would allow for something like folder/page as well, not sure whether you want to handle that the same way or not.
Solved! I added this rule to remove the trailing slash from URLs which aren't directories, before the file extension rule.
# Non-directory URLs with trailing slash change to without
RewriteCond %{REQUEST_URI} ^(.*)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ https://%{HTTP_HOST}%1 [R,L]
The line in Dusan Bajic's comment didn't work on its own - it rewrote the address with the absolute file path instead of the original URL path. But it did find the slash correctly, so I rewrote the substitution to explicitly give the correct address minus the slash.
So, I'm not very good with Apache config or .htaccess rewrite rules.... And I'm trying to do some modifications to how my localhost server works...
What I'm trying to do is return a 404 error on any request with the extension '.php'. If the uri does not have an extension, then route the request to 'ini.php'. If the uri contains an extension that isn't of '.php', then it should just follow normal procedures in fetching the file.
What I have now:
Rewrite Engine on
DirectorySlash off
RewriteCond $1 (.php)
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond $1 !^(.+)
RewriteRule ^(.*)$ ini.php [L,NC]
My logic is that if it's not a .php, and it doesn't have an extension, then route it to ini.php. Otherwise it should route normally.
Right now it looks like the .php rule is working in returning 404 errors.. However, if a request for a path without an extension is received, it tries to route to ini.php and hits a 404 page. Is it maybe processing like the second rule and then hitting the first rule?
Anyways, can someone help me sort it out and give me some guidance on it? I tried google and a bunch of different solutions, but I couldn't find something that worked for this situation...
UPDATE:
I changed the code to the following and added ini.php to the DirectoryIndex settings in httpd:
RewriteEngine on
RewriteCond %{REQUEST_URI} (\.[php^\\/]+)$
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond %{REQUEST_URI} !(\.[^\\/]+)$
RewriteRule ^.+$ / [L,NC]
Can you check if it looks alright?
I've turned on DirectorySlash again. Thanks.
This will do it:
RewrieEngine on
# 404 any URL ending .php (ignoring any query string)
RewriteRule ^(.+)\.php$ - [R=404,L,NC]
# Rewrite any URL that does not contain a dot (.), and therefore has no extension, to ini.php
RewriteRule ^([^.]*)$ ini.php [END]
I am assuming it will go in a .htaccess file from what you said. It would need changing to go in the main config.
Don't turn DirectorySlash off. It's a security risk to do so (see the link) and it only applies to existing directories anyway so is not causing any problems for you. There is no space in RewriteEngine.
I was trying to prettify URLs for dynamically generated pages on my website, so that when a user visited the virtual URL topicview/interesting-user-friendly-text he would really be seeing, under the hood, topicview.php?topicid=123
I added the necessary code to my .htaccess file to replace the topicview/interesting-text part of the URL with topicview.php?topicname=interesting-test, but the Regex kept misfiring.
So, I changed the Regex to return the entire URL so I could see why it wasn't working with this code:
#Allow for topicview/topic-name URLs
RewriteRule (.+)$ topicview.php?topicname=$1 [L]
I then visited topicview/user-friendly-text. I'm not sure if this is unique to Network Solutions hosting, however, when I examined the topicname GET paramter, I got this string in return:
data/1/2/323/232/823238/user/999999/htdocs/topicview.php
This URL was not displayed in the topicname GET parameter, just a regular file, like index.php or topicview.php, if I just visit the URL index.php or topicview.php
Why is the URL internally represented like this to the Apache server, and how can I rewrite my mod_rewrite code to get a more user friendly virtual URL for the topicview.php?topicid=1 pages?
thanks
For the friendly URL try this in your .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?topicview/([^/.*]+)/?$ topicview.php?topicname=$1 [L,QSA]
The pattern matched in a RewriteRule is normally the similar to the REQUEST_URI but the behaviour you describe suggests it is matching against the REQUEST_FILENAME or something similar which is the file path including the full document root.
This would suggest your RewriteRule is not in your .htaccess file but instead in your or rules in the Apache config files, correct?
Instead you should try getting the value you want using a RewriteCond so you can guarantee you are matching against the REQUEST_URI, for example:
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteRule . topicview.php?topicname=%1 [L]
Note the %1 rather than $1 which allows you to use values captured in the RewriteCond.
I am trying to capture a url such as
http://www.mysite.com/somepage.php?sometext=somevalue
and redirect it to.
http://www.mysite.com/index.php?page=somepage.php&sometext=somevalue
I tried searching for such .htaccess online, but couldn't find it.
Can you please help me?
I'm quite sure this is a duplicate, but I'm having a bit of an issue finding it/them [Edit: I found one, though possibly not the best example].
Anyway, this is a fairly standard problem resolved with fairly standard code:
RewriteRule ^(.*)$ index.php?get=$1 [L,QSA]
The RewriteRule captures the entire request as $1, and passes it to index.php as the page GET parameter.
The [QSA] flag on the end says to take any existing GET parameters (sometext=somevalue in your example), and add them as additional GET parameters on the new request. (The [L] flag just says that this should be the last rule executed.)
Note that this will also redirect requests for things like images or CSS files, so it's good to add the following lines directly before this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
These lines say "if the request is for a file or directory that actually exists, don't process the rule." That way, requests for real files will be served directly by Apache, rather than being handled (or more likely, mishandled) by your PHP script.
RewriteRule ^(.*).php?sometext=(.*)$ index.php?page=$1.php&sometext=$2 [QSA,L] #rewrite
RewriteRule ^(.*).php?sometext=(.*)$ http://www.mysite.com/index.php?page=$1.php&sometext=$2 [R=301,L] #redirect
i am working for a site,which is in php.....i want to rewrite url
e.g www.3idiots.co.in/stories.php?id=17
if i want to rewrite it as
www.3idiots.co.in/stories/17.html
can any one tell me the code for this to write in .htaccess file.?
I'm assuming you're using Apache with mod_rewrite. Something like
RewriteEngine On
RewriteRule ^/stories/([0-9]+)\.html /stories.php?id=$1
should do the trick. Of course you'll need to make sure that RewriteRule is allowed in that directory. See this wiki page for more information.
mod_rewrite can only rewrite/redirect requested URIs and not those that are in your HTML documents. So you should first make sure, that your PHP application is printing the correct URIs, so /stories/17.html instead of /stories.php?id=17.
After that, you can use the rule suggested by José Basilio:
RewriteRule ^stories/([0-9]+)\.html$ stories.php?id=$1
Though redirecting requests of /stories.php?id=17 externally to /stories/17.html and then internally back to /stories.php?id=17 is possible, it’s not good practice as that would result in twice as many requests. But here’s the rule for that:
RewriteCond %{THE_REQUEST} ^GET\ /stories\.php[?\s]
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([0-9]+)&*([^&].*)?$
RewriteRule ^stories\.php$ /stories/%3.html?%1%4 [L,R=301]