The real content is at domain.com/view.php?id=image_id
I want to have it be accessible with domain.com/view/image_id
The following is currently there to get the .php file extensions out.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Appending the following to the htaccess doesn't work:
RewriteRule ^view/([A-Za-z0-9]+). /view.php?id=$1 [L, QSA]
Also, I am fine with having everything after view.php? (view.php?id=) get taken into the php file and from there I can separate everything out by slashes and implement their data.
I have looked at many solutions here on stackoverflow and elsewhere but either they do not apply to me or something is wrong with my server. Either way, I get an internal 500 server error. Thanks.
You need to place the view rule before the more general php extension rule:
RewriteEngine On
RewriteRule ^view/([A-Za-z0-9]+)$ /view.php?id=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Also, you don't want that space after the L,.
^view/([A-Za-z0-9]+).
^---single character wildcard
That . at the end there is matching/consuming one of your ID values, so if the url is
/view/foobarbaz
Your capture group will actually be foobarba, and the z gets chopped off, producing
/view.php?id=foobarba
Your 500 Internal Server Error is the result of a redirect loop.
This is because your rule will always be true, because you are redirecting back to the same page.
You need to exclude the resultant link by adding a rule with ^! before all the rest.
Related
This will be a niche question but I am having trouble rewriting my url.
I am trying to rewrite from /view.php?user=Alex0111 to view/Alex0111. I also have a second get variable of /view.php?user=Alex0111&id=5 which I want to be view/Alex0111/5
Here are the contents of my .htaccess file
DirectoryIndex Home.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^view/([0-9A-Za-z]+) view.php?user=$1 [NC,L] #doesn't work causes internal error
I've checked this line of code multiple times to the tutorial I am following but I am missing the mark on something.
Replace both of your rewrite rules with:
RewriteRule ^view/(.+)/(.+) view.php?user=$1&id=$2 [NC,END,QSA]
Your first rewrite rule will interfere because it will rewrite the path as Markus mentioned in comments.
The [END] flag will throw an error if you have an old Apache version. In that case, use the [L]
The [QSA] flag tells the server to add any additional query parameters that the user sent. eg: view/Alex01/5?param=value
Before anyone comments, I know there are a lot of posts created on this topic, but none of them seem to solve my problem, that is why I have started this thread.
So, I have a page in my website called project.php which is used in GET query like so: project.php?id=12 I want to have a .htaccess file that converts the given URL into localhost/MyWeb/project/id/12/. I've literally followed every single post regarding that topic but none of them seem to work.
Also, along with that, I want all my .php and .html files to be shown just with their names, i.e localhost/MyWeb/index.php/ becomes localhost/MyWeb/index/ and localhost/MyWeb/sub1/sub2.php becomes localhost/MyWeb/sub1/sub2/.
EDIT:
The reason why I did not add my work in first place was because I didn't think it would be any helpful. But here it is:
RewriteEngine On
RewriteRule ^([0-9]+)$ project.php?id=$1
RewriteRule ^([0-9]+)/$ project.php?page=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Firstly, you are operating out of a sub-directory (MyWeb), which means you need to set a RewriteBase. Also, you need to ensure that your .htaccess file is placed inside that sub-directory, and not in the localhost document root.
So, below RewriteEngine on, insert the folloeing line:
RewriteBase /MyWeb/
Next, you stated that you want to convert project.php?id={id} to project/id/{id}, but your code omits the /id/ segment. I also noticed that you have two rules, and that the second one contradicts your question, so I am only going to show you the change you need to make for the first rule, until such time as you clarify what the second rule is for.
To make the project URI work, change the very first rule to:
RewriteRule ^project/id/([0-9]+)/?$ project.php?id=$1 [QSA,L]
This will match the URI you want, with an optional trailing slash. I've also added the QSA flag which appends any extra query string parameters to the rewitten URI, as well as the L flag which stops processing if the rule is matched.
Next, to omit the .php or .html from your URIs, change the last three lines to the following:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]
When you make a request to localhost/MyWeb/index, Apache will check to see if localhost/MyWeb/index.php or localhost/MyWeb/index.html exist, and will then serve whichever one it finds first.
If you have both the PHP and HTML files, then the PHP one will be served, and not the HTML one. If you prefer to serve HTML files, then swap the two blocks around.
Unfortunately, I don't know of a good way to force a trailing slash for these, specifically because of the condition that checks for their existence. In other words, it won't work if you request sub2/, with the trailins slash because it would need to check if sub2/.php exists, which it does not.
Update: For added benefit, place these two blocks just below the new RewriteBase you set earlier to redirect the old URIs to the new ones whilst allowing the rewrites to the new URIs to still work:
RewriteCond %{THE_REQUEST} \/project\.php\?id=([0-9]+) [NC]
RewriteRule ^ project/id/%1/ [R=302,L,QSD]
RewriteCond %{THE_REQUEST} \/MyWeb/(.+)\.(php|html)
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ %1 [R=302,L]
For reference, here's the complete file: http://hastebin.com/gacapesoqe.rb
I am trying to convert this:
site/read.php?id=6
to
site/read/6
I have tried a couple of solutions found on SO, with the last one being (to output: site/read/id/6):
RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]
When I try the second link, it will hang, and apache crashes (LOL).
Not sure if it has a problem with the rest of the .htaccess file, so here is the full code:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]
I could achieve (with rows 1-4) that no php extensions are showing up, so the address bar currently reads site/read?id=6
Can you please point me out where have I gone wrong?
You can put this code in your htaccess (which has to be in root folder)
Options -MultiViews
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/read\.php\?id=([0-9]+)\s [NC]
RewriteRule . /read/%1? [R=301,L]
RewriteRule ^read/([0-9]+)$ /read.php?id=$1 [L]
I would do dthis in PHP , it is very hard to debug what Apache is getting , it may be that it goes into indefinite loop, did you find anything in apache log files ?
But save yourself a trouble and do it in PHP, if you are using a Framework it is easy to inlcude one PHP that checks for this and redirects to new page if it detects .php in url.
I'm working on a website that has been built sloppily.
The website is filled with regular links that are translated into the corresponding .php pages by the .htaccess page.
This is it:
RewriteEngine on
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
First of all, I would love some help regarding whether or not this page has everything it should. I've never messed with it before.
Secondly and my main issue, if, for example, I would write the address www.thewebsite.com/foobar.html, it would be translated into www.thewebsite.com/cat.php?cat=foobar by the .htaccess page, and it would give a database error (and reveal information about the database).
I've put a check into cat.php which checks if the category exists, but I can't redirect the user to the 404 error page. There's a page called 404.shtml in the website, but redirecting the user to it causes the .htaccess to just change it again to cat.php?cat=404.
Is the way they used the .htaccess page normal? Should I change this system?
And how are users sent to error pages? From what I understood the server should be doing it on its own?
I would love some clarification... There is some much about this subject I don't understand.
Update:
This is my new .htaccess page
RewriteEngine on
RewriteRule ^error.php?err=(.*)$ Error$1.html
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
Because the redirecting is in the code and the user cannot see it, I allowed myself to write the link in a non-clean way. I tried turning it into a clean URL but the following does not do anything:
RewriteRule ^error.php?err=(.*)$ Error$1.html
Can someone please help me understand why? I thought since error.php is a real page, I should put it before the conditional but it didn't work. BTW, I saw in an article about .htaccess that the page should start with Options +FollowSymLinks. It seems to me that everyone sort of has their own way of writing it. Is there a guide or something like that, which I can be sure is authentic and covers all the bases there is about .htaccess?
Thank you so much!!
Using rewrite rules to work around links to .html pages that don't exist is unusual in my experience, but it's really just a different take on "pretty" URLs, e.g. www.thewebsite.com/foobar/ gets routed to cat.php?cat=foobar on the backend.
Your 404 issue is different. You need to be able to display error pages.
One option here is to rewrite requests as long as they don't request an existing file. This is very common for serving up static content like images, CSS files, and the like. To do this, you can use the -d and -f options to RewriteCond, which apply when requesting a directory and file respectively:
RewriteEngine On
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
Now, requests to 404.shtml should go through, because you're requesting an existing file on the filesystem.
Note that the RewriteConds only apply to the single RewriteRule that immediately follows. For additional RewriteRules, also include additional RewriteConds.
Your regex is wrong anywhere. Literal dot needs to be escaped using otherwise it will match any character. Also it is better to use L and QSA flags to end each rule properly.
RewriteEngine on
RewriteBase /
RewriteRule ^koral/([^/]+)/?$ page.php?name=$1 [L,QSA]
RewriteRule ^([^.]+)\.html/([^/]+)/([^/]+)/([^/]*)/?$ cat.php?cat=$1&page=$2&order=$3&dir=$4 [L,QSA]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
RewriteRule ^([^/]+)/([^.]+)\.html$ product.php?cat=$1&product=$2 [L,QSA]
I am implementing a caching system for dynamically generated images. The script is called via /img/type/param1/param2.png, where multiple types are possible and the number of parameters are variable. The script generates the image and dumps it to disk.
I would like .htaccess rules, which when requesting the image generation script:
checks to see if a cached file exists
if so, mod_rewrite to the cached file
if not, don't do anything so that the script runs
What I have so far is a slightly modified logic:
mod_rewrite to where the cached file would be
check to see if the file exists
if not, mod_rewrite the request back again
If there's a better way to do this, I'd love to hear it. In any case, the relevant part of my .htaccess file:
RewriteRule ^img/(type1|type2)/(.*)$ /images/cache/$1/$2
RewriteCond /^(.*)$ !-f
RewriteRule images/cache/(.*) /img/$1
This doesn't seem to work quite right. To debug it, I inserted the following after the first RewriteRule (the target page just dumps its input):
RewriteRule ^(.*)$ /htaccess.php?url=$1 [END]
As a result, I get:
Array
(
[url] => /images/cache/a/l/300.png/a/l/300.png
)
I don't understand why $2 contains l/300.png/a/l/300.png instead of just l/300.png.
If I change first RewriteRule to include an [L], I get the expected result. However, I experience the exact same "double-matching" issue on the second RewriteRule which reverts the request back into the non-cache version. However, adding [L] to this second RewriteRule:
RewriteRule ^img/(type1|type2)/(.*)$ /images/cache/$1/$2 [L]
RewriteCond /^(.*)$ !-f
RewriteRule images/cache/(.*) /img/$1 [L]
yields an Internal Server Error.
What am I doing wrong, and how do I fix this issue?
The first logic that you have is what you want to be doing, that bypasses the possible looping issues. You just need to extract the relevant bits from the %{REQUEST_URI} then backreference them using % references. So for example:
RewriteCond %{REQUEST_URI} ^/img/(.*)$
RewriteCond %{DOCUMENT_ROOT}/images/cache/%1 -f
RewriteRule ^img/(.*)$ /images/cache/$1 [L]
or using the regex patterns that you had:
RewriteCond %{REQUEST_URI} ^/img/(type1|type2)/(.*)$
RewriteCond %{DOCUMENT_ROOT}/images/cache/%1/%2 -f
RewriteRule ^img/(.*)$ /images/cache/$1 [L]