So basically I want users to be able to go to my website with a URL of something like /45678, instead of having to use /?p=45678, so really I just want to remove the variable name. I've tried using mod_rewrite, but it seems that is only for removing the name when the page is visited.
Here is the current code:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^p=([0-9]+=$
RewriteRule ^/$ /%1 [R]
Simply change all of your links to /45678 rather than ?p=45678. Or did I misunderstand you completely? Because what I got from your post is that it works properly, unless you manually access the ?p=45678 where as it stays as ?p=45678.
EDIT:
This is what I am using for http://www.madphp.org/dev/, give it a go, works like a charm for me (it also removes the index.php part). To access your now cleaner URL you would simply explode the $_SERVER['PATH_INFO'] variable to get all of the required parameters within your PHP script.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Have you set up mod_rewrite correctly? If so, you can use variables like simple $_GET variables, in this case you must access $_GET['p'] in PHP.
I did this without using .htaccess, but it does query a database. I wrote this a while ago so it uses PEAR DB, adjust to your database/connection method. I'll just copy my code and let you figure out what changes you need.
$db=connect_db();
$name=substr($_SERVER['PHP_SELF'], 20);
$name=strtolower($name);
$id=$db->getone("select id from user where login='{$name}'");
header("Location: /dragonart/profile?user=" . $id);
If you store your information in a database this may be a nice alternative. The downside is that the the URL is not rewritten and the user is ultimately sent to a page with ending in a $_GET variable.
edit:
Just realized that using my method a simpler method can be used for the answer. Since my solution was used to find the id of a user using their username and then send someone to their profile (which requires the id) a better solution would be something like:
$var=substr($_SERVER['PHP_SELF'], $length);
header("Location: /path/to/page?p=".$var);
where $length is the usual length of the URL without the variable at the end.
Related
I know there's a million similar questions on stuff like this, but clearly there's much I don't understand because I haven't been able to derive answers or a solution to my (as I understand it) fairly simple question.
Basically, I'm trying to get an old site back up, but want a more professional look to it this time round, which includes cleaning up the URLs. A typical page is as follows (hosted locally at the moment, but will be assigned a domain in next few days):
192.168.0.200/album-reviews.php?albid=22
Using the following code, I have been able to achieve the above example page loading via manually typing 192.168.0.200/album-reviews/22 into the browser:
RewriteRule ^album-reviews/([0-9a-zA-Z]+) album-reviews.php?albid=$1 [NC,L]
However, what I want as well is for when the link is clicked on my site, it directs the user to /album-reviews/22 instead of album-reviews.php?albid=22. The only way to get the clean URL at the moment is to manually type it into the bar, links from my site do not get the clean URL, the code I have been playing around with (and have been unable to get working) based on sources I've found is this:
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([0-9a-zA-Z]+)
RewriteRule ^ /album-reviews/%1? [L,R]
So if anyone could shed some light on how I get all this working as desired, I'd be grateful, I hope my question has been articulated appropriately.
On a side note, If i wanted to include the post title in the URL too like this:
192.168.0.200/album-reviews.php?albid=22&ptitle=my first post
how would alter any code to make it like this:
192.168.0.200/album-reviews/22/my first post
Thank you.
You can use:
Options -MultiViews
RewriteEngine on
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([^\s&]+)&ptitle=([^\s&]+)
RewriteRule ^ album-reviews/%1/%2? [L,R=301]
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([^\s&]+)
RewriteRule ^ album-reviews/%1? [L,R=301]
RewriteRule ^album-reviews/([^/]+)/?$ album-reviews.php?albid=$1 [NC,L]
RewriteRule ^album-reviews/([^/]+)/([^/]+)/?$ album-reviews.php?albid=$1&ptitle=$2 [NC,L]
If you want to show the contents of http://yoursite.com/album-reviews.php?albid=22 at the url http://yoursite.com/album-reviews/22, you need these codes:
Your htaccess needs this lines:
RewriteEngine On
Options -Indexes
RewriteRule ^album-reviews/(.*)$ album-reviews.php?pretty=$1 [L,QSA]
And your PHP these:
$pretty = $_GET['pretty'];
$parameters = explode('/',$pretty);
$albid = $parameters[0];
Your user won't be redirected, your website will show directly the page at the pretty url.
Now, what happened? That you instructed htaccess to send everything after album-reviews as a GET parameter called "pretty". Then in your PHP you cut it for every / that appeared in it, and that way you formed the array $parameters. So you can even get more parameters, for every /, they are all in the array $parameters:
$second_parameter = $parameters[1];
$third_parameter = $parameters[2];
$fourth_parameter = $parameters[3];
How can I do to change the name of the url of my site which is: www.example.com/user/panel.php to www.example.com/username/panel.php where the "username" is unique for each user , And for each login would be the name of the user from database, as it is in jsfiddle.net, could they help me?
Personally I would not use .htaccess for this ( specifically )
that said most the time people do it this way
RewriteEngine On
RewriteRule ^users/([-a-zA-Z0-9_]+)/?$ index.php?user=$1 [L]
So if you had a url like
www.yoursite.com/users/someguy
Then it would pass it to apache ( and php ) as
www.yoursite.com/index.php?user=someguy
Then in PHP you could access it just using $_GET[user].
Now ignoring security concerns I may have ( you shouldn't rely on user input to tell who they are, they can lie about it) for this I would use what I call the URI method ( not URL ) a URI is an imaginary path. This is also the method employed by many MVC systems. So for this I will start with the URI
www.yoursite.com/index.php/users/someguy
Notice where the index.php is ( in the middle ). Then you do a .htaccess like this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f #if not a real file
RewriteCond %{REQUEST_FILENAME} !-d #if not a real folder
RewriteRule ^(.*)$ index.php/$1 [L] #hide the index.php
So what this does is allow you to remove the index.php giving you a url like this
www.yoursite.com/users/someguy
Which is what we want, and looks basically the same as the first case.
Then you cam use the $_SERVER['QUERY_STRING'] supper global which will give you everything past index.php
/users/someguy
And you can split that up, route it somewhere, do whatever you need to with it. Like this
$uri = array_filter( explode('/', $_SERVER['QUERY_STRING'] ) );
//$uri = [ 'users', 'someguy' ];
Now the reason I like this more, is it's more flexible and it lets you use the query string the ?var part of the url for other stuff. ( like bookmarkable search forms ) ie. it feels less hacky because your not breaking the query parameters of a GET Request. Conversely, with the first method, if your .htaccess is sloppy you could make it were the query part of the URL is unusable on your site, and that just feels wrong to me.
It also easier to maintain, because it requires no further setup for additional pretty urls
For example:
Say you want prettyfy your product. Using the first method you would have to go back to the .htaccess add at least 1 more rule in:
RewriteEngine On
RewriteRule ^users/([-a-zA-Z0-9_]+)/?$ index.php?user=$1 [L]
RewriteRule ^products/(0-9_]+)/?$ index.php?product=$1 [L]
Possibly even more complex levels if you have product categories
RewriteRule ^produts/([-a-zA-Z0-9_]+)/(0-9_]+)/?$ index.php?category=$1&product_id=$2 [L]
After a wile you would wind up with dozens of rules in there, some of which may not be immediately clear as to what they do. Then you realize you spelled products as produts and have to start renaming things. It's just a mess later on.
Now using the second method you don't need to do any additional steps, besides routing it in your index page. You just put the url in
www.yoursite.com/products/123
And pull that stuff from the $_SERVER array with no further messing with rewrite rules.
Here is a previous answer I did that outlines how to build a basic router.
Oop php front controller issue
Make sense.
I'have this rewrite condition that redirect all the request of non-existing files to the app.php in parent directory.
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^(.*)$ %2../app.php [L]
In the last line (rewriterule) the value of $1 is the path relative to the dir where .htacces is, in order to make it portable ( found here: http://linlog.skepticats.com/entries/2014/08/Using_RewriteBase_without_knowing_it.php ).
That is : calling http://localhost/myapp/public/test123/r.txt I will get test123/r.txt in $1 variable (considering that .htaccess is in public/).
I would like to pass the value of $1 to the app.php, a common solution would be to append it as a query string:
RewriteRule ^(.*)$ %2../app.php?__path=$1 [L]
In this way I have __path as a GET variable (PHP: $_REQUEST["__path"]) , but how it works with other kind of requests like POST (query string should not be there) ?
A more clean solution would be to put $1 in a HTTP custom header but, how can I set a custom header, say MYAPP_PATH to $1 value through .htacess ?
To start with your comment:
I've noticed that the trick ?__path=$1 overrides all the querystring that I pass in the original URL.
You forgot to set the QSA flag.
Second to the core question:
In this way I have __path as a GET variable (PHP: $_REQUEST["__path"]) , but how it works with other kind of requests like POST (query string should not be there) ?
This just works fine. GET-parameters are just popularly called that, they're actually query string parameters and can be passed with any HTTP verb, from GET and POST to PUT and DELETE. So if you POST to a URL with query string parameters you can still read them from $_GET just fine.
Final point, as the above solves all your issues: please do not use $_REQUEST. It's really REALLY bad practice, and may lead to obscure security and stability issues. Just use $_POST, $_GET et al instead.
My site used to generate URLs like this:
/data.php?s=1432862823&type=basic
I have modified the program so the new URLs generated are:
/d.php?s=1432862823&t=basic
Since some people have bookmarked the old URLs I want to write a Rewrite rule that will get them to the new url.
I've not this so far:
RewriteEngine on
RewriteRule "^/data\.php$" "/d.php"
but I can't figure out how to account for the variables.
Try this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^s=([^&]+)&type=([^&]+) [NC]
RewriteRule ^data.php$ /d.php?s=%1&t=%2 [NC,R,L]
This will externally redirect a request for :
/data.php?s=foo&type=bar
to
/d.php?s=foo&t=bar
Edit: I do apologise, I only noticed now that you have changed the type parameter to t. As such, this solution will not fit your needs, unless for a URI where the query string parameters do not change. I'm leaving this answer here so that others may learn from it - you'll be surprised how many people don't know that the query string is automatically transferred to the new destination. Starkeen's answer, therefore, is the correct answer.
You could follow Starkeen's solution, which specifically checks for the query string and explicitly adds it to d.php. Alternatively, for simplicity, you could just use this:
RewriteEngine on
RewriteRule ^data.php$ /d.php [R=302,L]
The query string will automatically be transferred from data.php to d.php, and you will be redirected accordingly.
To make the redirect permanent and cached by browsers and search engines, change 302 to 301.
I'm having e commerce website in php. And now moving to fancy urls, url rewriting.
for that i've variable length of parameters with optional variables too.
for example,
http://example.com/product.php?page=e&id=23&color=blue&size=xxl&width=200&height=100
Here, the parameters are optional That means, some variables may or may not participage in the url except id.
here, page=e is fixed and it is not dynamic. ( the reason behind is i've other rewritten rules like ^categories, ^toys etc..
and re-written url should be one of these,
http://example.com/e/23/color-blue/size-xxl/
http://example.com/e/26/color-black/width-500/height-900/
http://example.com/e/56/type-shirt/color-white/height-345/size-xl/
i've tried below with no luck,
RewriteRule ^e/([^/.]+)/?$ product.php?page=e&url=$1 [L,NC,QSA]
i'm getting all $_GET values like this,
http://example.com/product.php?page=e&id=23&color=blue&size=xxl&width=200&height=100
but i'm trying to achieve like this,
http://example.com/e/23/color-blue/size-xxl/width-200/height-100
how can i pass the queries with slashes and not &'s.
that main idea behind above last url is to process the whole fancy url into simple one in php,
and then use those variables in the page script. is there any better solution than this ??
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
RewriteRule ^(e)/([0-9]+)/([^-]+)-([^/]*)(/.*)?$ product.php$5?page=$1&id=$2&$3=$4 [L,QSA]
RewriteRule ^(product\.php)/([^-]+)-([^/]*)(/.*)?$ $1$4?$2=$3 [L,QSA]