I've been searching all over the web and haven't yet found any solution to this issue. I'm hoping you could shed some light on the situation.
I have my index file set up like this:
<header></header>
<div id="main">
<?php
if(isset($_GET["p"])) $p = $_GET["p"];
else $p = "home";
if(file_exists("pages/{$p}.php")) include("pages/{$p}.php");
?>
</div>
which makes me load my pages with a ?p=contact href.
Say I would like to display a users profile. I'd then create a subfolder in my "pages" folder, making the relative path pages/users/profile.php, thus the href ?p=users/profile&uid=5. But that leaves an ugly URL (as well as SEO rating).
How would I rewrite that URL to look like /users/profile/5?
EDIT:
I've tried the following, resulting in HTTP 500:
RewriteRule ^([^/]*)/([^/]*)$ /?p=$1&uid=$2 [L]
EDIT: My .htaccess file, located directly inside root folder: http://pastie.org/2268239
Line 338 is where I want to achieve this (currently just a comment).
Simplest answer for both your situations would be to add this in your .htaccess file
RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php?$1 [L]
This will redirect all traffic on your domain to your index.php file.
You could then determine what to do in your script using the uri in $_SERVER["REQUEST_URI"]
I achieved the desired effect by adding these three lines:
RewriteRule ^([a-zA-Z]+)$ index.php?p=$1 [L]
RewriteRule ^([a-zA-Z]+)/([a-zA-Z]+)$ index.php?p=$1/$2 [L]
RewriteRule ^([a-zA-Z]+)/([0-9]+)$ index.php?p=$1&uid=$2 [L]
This allows me to access /contact, /users/index and /users/profile/5.
I'm not a php guy, but I tried this with my rewrite.
RewriteRule ^/(.+)/([^/]+)$ /index.php?p=$1&uid=$2 [L]
In this case, for the p parameter, you're looking for all chars up to the last slash, so the first part of this takes anything, otherwise it's going to stop at the first slash (users instead of users/profile).
Then it looks for a slash and keep (not-slash). The (.+) will be greedy, so it will go up to the last slash before the end.
Then it occurred to me the last part doesn't need to avoid slashes. Since the first part is greedy, the explicit / slash is going to BE the last slash. So it's even simpler:
RewriteRule ^/(.+)/(.+)$ /index.php?p=$1&uid=$2 [L]
I like the .+ to require something, at least when first figuring these out. If later you know they can be optional, you can do .*, but usually that ends up being a different page or a different rule.
These rules do expect all urls to be in this format, which is what you're asking. But maybe it's a little too grabby, so it could exclude urls that really have a .htm or .php or whatever.
RewriteRule ^/(.+)/([^.]+)$ /index.php?p=$1&uid=$2 [L]
This looks for anything up to the last slash, then anything without a dot in it. If it has a dot, this won't apply. So if it's a "regular" url, this will leave it alone. This might help with the 404 problem, in case the 404 page is getting caught by this.
Related
I'm trying to write clean url's for my website. I'm a rookie at this so forgive me. My .htaccess file currently looks like this:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-]+)$ something.php?query=$1
RewriteRule ^([a-zA-Z0-9-]+)/$ something.php?query=$1
The first rule seems to work. For example website.com/good-looking-query-string does in fact rewrite to website.com/something.php?query=ugly+looking+query+string
The second rule is where I'm having a problem. I can't get that trailing slash to work. For example website.com/good-looking-query-string/ appears to pull up the page but without any CSS rules applied. I noticed all the links end up appended to the query string also. For example the link back to index.php ends up like website.com/good-looking-query-string/index.php
I need to get that trailing slash to work. What in the world am I doing wrong?
You can combine two line in one line:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-]+)/?$ something.php?query=$1
In this case / will be optional
Your issue is client side, you are using relative paths but you need to be using Root-relative paths. A URL of:
website.com/good-looking-query-string
loads from the root. A url of:
website.com/good-looking-query-string/
loads from the good-looking-query-string directory.
So instead of href="style.css" you should have "href="/style.css"and the index issue should behref="/index.php"instead ofhref="index.php"`.
As noted in the earlier comment your regex could be simplified by adding a ? on the trailing slash to make it option. That is not your issue though, just simplifies the rules.
RewriteRule ^([a-zA-Z0-9-]+)/?$ something.php?query=$1
I have the following URL:
http://example.com/pages/page.php?company_name=Name
What I want to achieve is to have a URL like this:
http://example.com/pages/Name
I have tried different rules but they don't work:
RewriteRule ^pages/([A-Za-z0-9-]+)/?$ /pages/page.php?company_name=$1 [NC] or
RewriteRule ^pages/([^/]*)\.php$ /pages/page.php?company_name=$1 [L]
It doesn't work. It gives me a "not found" page. How can I properly use mod_rewrite?
Try this out:
RewriteRule ^pages/([0-9a-zA-Z\-_]*)(/|)$ /pages/page.php?company_name=$1 [QSA,L]
This will care or not care if the url has a trailing slash:
http://example.com/pages/Name
http://example.com/pages/Name/
And will also include any extra agrs (QSA) if the page calls for it:
http://example.com/pages/Name/?more=stuff
That should work, if your apache has mod_rewrite and the php exists where you have shown.
UPDATE
If you have a different url that needs a different php, for example 'bluepages':
http://example.com/bluepages/Name
Then this would work for that:
RewriteRule ^bluepages/([0-9a-zA-Z\-_]*)(/|)$ /bluepages/somescript.php?some_var=$1 [QSA,L]
If you have multiple like this you wish to control, you can make multiple RewriteRules in your htaccess for each one. However if you just want to wildcard it, then this would do a blind catchall (and cause lots of error reports in your apache logs):
RewriteRule ^([0-9a-zA-Z]*)/([0-9a-zA-Z\-_]*)(/|)$ /$1/page.php?some_var=$2 [QSA,L]
You will either need to be specific, or just change everything. There are so many ways one can go with it, and it really depends on your intent.
I know there are tons of questions already but looks like i'm missing a step.
I recently added a login/signup form to my website. Users can then fill out a quick bio on their profile.
The issue that i'm facing is that right now, the profile page URL looks like that:
"www.example.com/profile.php"
How can I edit the .htaccess file so that it looks like:
"www.example.com/neil/
(neil being the username)
I've tried to add this to my .htaccess file but it didn't work.
RewriteEngine On
RewriteRule ^/(.*)/$ http://www.example.com/?name=$1 [L]
fiy, i'm working on localhost.
Just to be clear: my htaccess file should have no extension right (should't end with .txt) ?
Thanks
I suggest the following:
RewriteRule ^(.+)/$ profile.php?name=$1 [L]
The rule (.+)/ matches a string of one or more characters that ends with a slash, but returns the string without the end slash.
Changes this: http://www.example.com/neil/
To this: http://www.example.com/profile.php?name=neil
Changes this: http://www.example.com/ne/il/
To this: http://www.example.com/profile.php?name=ne/il
EDIT:
As suggested by sgroves:
Since names will probably not contain slashes, you can only match strings that don't contain slashes like this:
RewriteRule ^([^/]+)/$ profile.php?name=$1 [L]
I am pretty new to using the RewriteRule, so I am likely missing something obvious, but I have a PHP script that takes URL variables like this:
{baseurl}properties.php?prop=Property-Name
I would like to create RewriteRules so that anyone who types in this script name/variable combo would have their URL rewritten to:
{baseurl}/properties/Property-Name
As well as ensuring that anyone who types in the flat-link url, actually calls the script with the right variable name and value.
I have been referring to this link and I have found related threads:
Mod_rewrite flat links
Mod_rewrite trouble: Want to direct from ?= to a flat link, nothing seems to work
But, I am obviously doing something wrong, as I cannot get this URL to work the way I want. I am currently using the following code, which appears to do nothing (aside from rewriting the URL to include the www, and redirect requests for index.php to the site root):
RewriteEngine ON
RewriteCond %{HTTP_HOST} ^baseurl.com$ [NC]
RewriteRule ^(.*)$ http://www.baseurl.com/$1 [R=301,L]
RewriteRule ^index.php / [R=301,L]
RewriteRule ^properties/([0-9A-Za-z]+)/$ /properties.php?prop=$1
The issue is clearly with the last RewriteRule, assuming nothing above is affecting it. Again, I am likely doing something ridiculous. Can someone please explain what I am doing wrong?
Thanks for your help.
At a quick glance, it appears that you forgot to include the dash in your regular expression and you included trailing slash. Use this instead:
RewriteRule ^properties/([0-9A-Za-z-]+)$ /properties.php?prop=$1
If you look at your rule ^properties/([0-9A-Za-z]+)/$ you see that it needs to end with a forward slash. You can either remove that or make it optional like ^properties/([0-9A-Za-z]+)/?$.
Not sure how you'll take this question but...
Whenever I try to make my URLs look pretty I always end up messing around for too long and it's simply not worth the trouble. But the end effect is good if it were a simple task.
So what I want to do is create a method which in the end would achive something like...
index.php?do=user&username=MyUsername //This becomes...
/user/MyUsername //...that
index.php?do=page&pagename=customPage //And this becomes...
/page/customPage //...that
index.php?do=lots&where=happens&this=here //This also becomes...
/lots/happens/here //...that
index.php?do=this&and=that&that=this&and=some&more=too //And yes...
/this/that/this/some/more //This becomes this
So then I just make a nice .htacess file that I'll never have to look at again. Everything will be better in the world because we have pretty URLs and my head didn't hurt in the making.
You can use a different approach of throwing the url in a single parameter, and parse it in your application.
So the apache rewrite rule would look like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
which will convert your urls as follows:
/user/MyUsername => index.php?q=/user/MyUsername
/page/customPage => index.php?q=/page/customPage
...
In your app, you then have a $_GET['q'] variable, which you can split by '/', and have your arguments in order. In PHP it would be something like:
$args = explode('/', $_GET['q']);
$args will be an array with 'user', 'MyUserName', etc.
This way you will not have to touch your .htaccess again, just your app logic.
For /user/MyUsername ==> index.php?do=user&username=MyUsername and /page/customPage ==>
index.php?do=page&pagename=customPage, you can use:
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)$ index.php?do=$1&$1name=$2 [L]
But I don't think you can write a catch-all rule for /lots/happens/here and /this/that/this/some/more because you need to tell mod_rewrite how to translate the two urls.
Remember, mod_rewrite has to translate /lots/happens/here into index.php?do=lots&where=happens&this=here and not the other way around.
The best approach would be to delegate your application to generate the “pretty URLs” as well as parse and interpret them and to use mod_rewrite only to rewrite the requests to your application with a rule like this one:
RewriteRule %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
This rule will rewrite all requests that can not be mapped directly to an existing file to the index.php. The originally requested URL (more exact: the URL path plus query) is then available at $_SERVER['REQUEST_URI'].