I'm trying to build an htaccess file that displays an index file on a blank URI, or a numeric slug (pages), such as: example.com or example.com/12 (the later appending ?page=$1)
However when accessing any non-numeric slug, it should go to a different page. For some reason, I can't get it to ever hit the index file (even when blank or numeric). What am I missing?
Here's what I have:
Options All
RewriteEngine On
RewriteRule ^([0-9]*)/?$ index.php?page=$1 [L]
RewriteRule ^([^/]+)/?$ another_page.php?slug=$1 [L]
Shouldn't a blank URI or numeric URI hit the first rule, with the Last flag, and load index.php? Every request I make is hitting another_page.php
Thanks!
Ah ha, I figured it out shortly after posting this question.
I did require the RewriteCond lines above the final, but the original files had to exist too. I setup this htaccess file before creating the index.php file (I was looking for a 404).
This is what worked:
Options All
RewriteEngine On
RewriteRule ^([0-9]*)/?$ index.php?page=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ another_page.php?slug=$1 [L]
Thanks guys!
Related
I am currently coding my own website in PHP and MySQL on WampServer (local). I've already rewrited some of my URLs successfully. But I'm having problems with one of them.
I want to display on a page all my articles listed in a category using the GET method. For the moment, I have the following URL : http://localhost/actuco/cat.php?id=xpS3cc&slug=amerique-du-nord and I would like to use and display this URL as http://localhost/actuco/c-xpS3cc-amerique-du-nord/ (which does contains exactly the same GET parameters than the original URL).
I have tried to do this with the following line in my .htaccess file
RewriteRule ^c-([^/]*)-([^/]*)/$ cat.php?id=$1&slug=$2
When I write the second URL in my browser, it shows me a blank page with no code lines at all. My first URL works perfectly.
I'm really lost and I really don't know how to fix it.
Here is the whole .htaccess file used on my website (all other URL rewritings in this file do work).
Options +FollowSymlinks
RewriteEngine On
RewriteBase /actuco/
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_URI} /+[^\.]+$
#RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ article.php?lng=$1&yr=$2&mo=$3&dy=$4&slug=$5&total_slug=$6
#RewriteRule ^([^/]*)-([^/]*)-([^/]*)$ waluty.php?cur=$1&amt=$2&lang=$3
RewriteRule ^([^/]*)/([^/]*)$ url.php?mode=$1&u=$2
RewriteRule ^c-([^/]*)-([^/]*)/$ cat.php?id=$1&slug=$2
RewriteRule ^bio$ o.php [L]
Thanks in advance for your help !
just pest this code in your .htaccess file
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php?/$1 [L,QSA]
hopefully, it will work.
Solved ! Just forgotten to add slash before $ in this line
Before :
RewriteRule ^([^/]*)/([^/]*)$ url.php?mode=$1&u=$2
After :
RewriteRule ^([^/]*)/([^/]*)/$ url.php?mode=$1&u=$2
Now it works, but I still have a problem with multiple hyphens in slug described here : Multiple hyphen handling in .htaccess (URL rewriting)
I'm working on an MVC project and I have the following .htaccess file:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?path=$1 [L]
RewriteRule !^(public/|index\.php) [NC,F]
It works OK. I only want the public/ folder and the index.php file to be accessible to the public. All other paths should be inserted into the path GET parameter. For example, mysite.com/controller/method should point to mysite.com/index.php?path=controller/method.
Now, there is a problem. When visiting the URL directly (without including index.php, it is adding [NC,F] to the GET path parameter. It's like visiting mysite.com is pointing to mysite.com/index.php?path=[NC,F].
Why is this happening and how do I fix it?
EDIT
I moved index.php into the public/ folder. Here is my .htaccess file now:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule ^(/)?$ public/index.php [L]
RewriteRule !^(public/) [NC,F]
It seems to work OK. Are there any other improvements I could make on this?
You don't have a redirect location on the last rule, so it's taking the flags as the redirect location. Just a dash will be fine since it's a forbidden response. Change the last line to:
RewriteRule !^(public/|index\.php$) - [NC,F]
Also adding the dollar sign after index.php just to be clear.
Edit:
I would suggest updating your new rule set to the following (actually I suggest a complete re-think below, but this is an update on what you have):
RewriteEngine On
RewriteRule ^$ public/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule !^(public/) - [NC,F]
The (/)? wasn't needed in your homepage rule, as the opening forward slash is not included in .htaccess matches anyway.
I moved your rule for the homepage to the top or it will never be used due to being matched by the previous rule (so the path param is not there when empty, which is presumably what you intended).
I stopped anything in /public/ from being passed to your index.php script, since the way you had it, anything in public that didn't exist would have been passed to your index script, which does not seem to be what you intend.
I added RewriteCond %{REQUEST_URI} !=/public/index.php so the rule couldn't be executed on itself and create a loop if rule processing is run through more than once, which it can be, but then took it back out because the above match on /public/ covers that anyway.
A Re-Think
All that said, I don't think it really makes sense to check if files don't exist and then just send forbidden responses to the ones that do, yet send everything else to your index script. Why not just send everything to your index script? That seems to be what you want really. I would suggest you simplify to this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
Dropping the homepage rule since no need to worry about an empty path parameter being passed to your index script. Changing the logic to be "Leave anything in /public/ alone. For anything else, pass it through to the index.php script." so files tests not needed since the script handles it all, and no forbidden response needed because there is nothing left to match, it's all covered by the rules. You can always return forbidden to anything you don't want to process in your script, which you would have needed to do anyway for existing file URLs in your previous setup.
One Last Re-Think
And finally, if I might suggest, it would be cleaner to have your index.php file in the root of the website, so you can make /public/ work with its own index file later if you like, so finally I would move it back to the root and change the rules to this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule ^(.*)$ index.php?path=$1 [L]
And if you like all that, an up-vote to go with already accepting the answer would be much appreciated. :)
Adding RewriteRule ^(/)?$ public/index.php [L] seems to have resolved the issue. I'm not sure if this is the best approach, but here is my .htaccess file now:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule ^(/)?$ public/index.php [L]
RewriteRule !^(public/) [NC,F]
I moved index.php into the public folder to make things clearer.
I have removed file extensions on .php for my webserver. I just wanted to make it look nicer. This works excellent.
I have the following pages:
sitename.com/portfolio
sitename.com/portfolio/resume/file.html
The htaccess has rules so that when they visit the second link its just converting it to portfolio.php?resume&file=$1. That works awesome.
Okay heres the issue. Because i remove the extensions, if a user were to typ the domain as sitename.com/ portfolio/ with a traing slash, they will get an internal server error. Likewise, if they just type sitename.com/portfolio/r they also get an error since it doesnt exist. I know one way around this is to add an option in htacess for every page but that seems like a bad way of doing it.
Anyways here the current htacess file I am using:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteRule ^portfolio/resumes/([^/]+).html$ /portfolio.php?resume&file=$1 [L,QSA]
RewriteRule ^portfolio/resumes$ /portfolio.php?resumes [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ /$1.php [L]
ErrorDocument 404 /404.php
If i visit the site on a page that doesnt exist like sitename.com/1 or sitename.com/1.php then I get my 404 page, but if 1.php DID exist then i would see it and IF it did exist, and I typed sitename.com/1/ or sitename.com/1/somethingelse then instead of a 404 (which I expect) then it gives me an internal server error. Is there any way around this? an error in my syntax? Thanks
This is because when you request an uri with a trailing slash eg : /uri/ , your rule rewrites it to /uri/.php instead of /uri.phpwhich is an unknown/unsupported destination. You need to accept the trailing slash as an optional char. Change your rule to :
RewriteRule ^(.*?)/?$ /$1.php [L]
I'm in the process of overhauling one of my projects, a web based booking system, but I'm having a bit of an issue with my htaccess file. The old system was pretty standard, with .php scripts in the route of the website, I had a rule hiding my extensions, and I resultantly had a URL like /viewinvoce?ID=1. I've been trying to find out how to rewrite this URL so it looks a lot neater - in the format /viewinvoice/1, and I'm getting there, but I have a slight problem...
The URL /test works - it adds a trailing slash making the URL /test/, and the value 'test' is passed to the webpage.
The URL /test/ works as above, a trailing slash isn't added since it already exists, and 'test' is passed to the webpage.
The URL /test/1 also works, 'test' and '1' are both passed to the web page,
but when a slash is type after 1 (/test/1/) the page throws a 404.
My .htaccess file
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)$ /index.php?PID=$1&ID=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])/(.*[^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]
My simple PHP script..
<?php
echo $_GET['PID'];
echo '<br>';
echo $_GET['ID'];
Ideally, I'd like the .htaccess file to add a second trailing slash to the second variable passed, but I'm a bit confused at this point, and ideally a second pair of eyes would be useful!
Try these rules:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !/$ %{REQUEST_URI}/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?PID=$1&ID=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ index.php?PID=$1 [L,QSA]
Make sure to test it after clearing your browser cache.
We have added a paging system inside our layout. When we go to /page/clan, the page about our clan gets displayed. (as its located in pages/clan.php).
To get /page, we used a htaccess script, which rewrites index.php?page=pagename into the /page/pagename I mentioned.
This is our current htaccess code for converting these urls:
RewriteEngine On
RewriteRule ^page/([^/]*)$ index.php?page=$1 [L]
However, We'd like to remove the /page part, so it's possible to just use /clan instead of /page/clan to open the clan page.
How can this be done and with what code?
Thanks!
Try :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/?$ index.php?page=$1 [L,NC]
Rewrite condions make sure you don't rewrite any existing files or directories on the server.
[NC] flag makes the pattern case insensitive, so in you case example.com/fOo would also work.