Pretty URLs with .htaccess
Thanks for the idea @denoise and @mogosselin. Also with @stslavik for pointing out some of the drawback of my code example.
Here's how I do it:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^user/([0-9]*)/([a-z]*)$ ./index.php?user=$1&action=$2
RewriteRule ^user/([a-z]*)$ ./index.php?user&action=$1
by using var_dump($_GET);
on the link localhost/user/1234/update
I got
array (size=2)
'user' => string '1234' (length=4)
'action' => string 'update' (length=3)
while localhost/user/add
array (size=2)
'user' => string '' (length=4)
'action' => string 'update' (length=3)
which is my goal. I will just only do other stuffs under the hood with PHP.
What should I do to make the pretty URLs using .htaccess for my specific scenario?
Alright, so after messing around and reading .htaccess tutorials for hours, I finally managed to understand my mistake. First of all, here is the video which helped me understand my mistake.
Here's my solution:
<IfModule mod_rewrite.c>
Options -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?$1 [QSA,L]
</IfModule>
First, I am checking if mod_rewrite is enabled. Then providing some options. Then turning on the RewriteEngine which is neccessary for enabling rewriting rules. Then giving the Rewrite Conditions for [If no directory] and [If not file] for whatever query is being supplied, for which I rewrite the rule basically telling it that check for all string that doesn't end with extension ".", simply direct them all to index.php?$1.
Basically anything that has mvcframe.local/something_here/some_here/... will become automatically mvcframe.local/index.php?something_here/some_here
For my setup, index.php is the frontloader so everything must go through this file.
Simple pretty urls with .htaccess
You need to use QSA - When the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, and replace it with the newly generated one. Using the [QSA] flag causes the query strings to be combined. :
RewriteEngine On
RewriteRule ^article/([\w-]+)(?:\.html|/)?$ index.php?article=$1 [NC,QSA,L]
RewriteRule ^category/([\w-]+)/page/([\w-]+)(?:\.html|/)?$ index.php?category=$1&page=$2 [NC,QSA,L]
How to work with pretty URLs - PHP
You can set$_GET
yourself. $_POST
is unaffected by the rewrite.
Try this if you like:
<?php
function parse_path() {
$path = array();
if (isset($_SERVER['REQUEST_URI'])) {
$path = explode('/', $_SERVER['REQUEST_URI']);
}
return $path;
}
$path_info = parse_path();
echo '<pre>'.print_r($path_info, true).'</pre>';
// SET UP $_GET HERE
$_GET['user'] = $path_info[0];
$_GET['id'] = $path_info[2];
switch($path_info[1]) {
case 'get': include 'get.php';
break;
default:
include '404.php';
}
But if you can still modify the code that looks for $_GET
you might want to consider not using $_GET
like this, and rather set up some sort of class that contains the values.
And you also might want to consider doing your url rewriting so as to map the original request to something that has get variables.
eg
//.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/(.+)/(.+)$ /api/v1/$2.php?user=$1&id=$3 [L]
</IfModule>
.htaccess Pretty URLs title in url
Your regex is only allowing letters. It should also allow hyphen, numbers, upper case letters and underscore. Try this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-z]+)/([^/]+)/?$ content.php?action=$1&title=$2 [NC,L,QSA]
.htaccess : Pretty URL with whatever number+names of parameters
If the .htaccess
file is located in the document root (ie. effectively at http://localhost/.htaccess
) then you would need to do something like the following using mod_rewrite:
RewriteEngine On
RewriteRule ^(blahblahblah/mywebsite)/(\w+)$ $1/index.php?param1=$2 [L]
RewriteRule ^(blahblahblah/mywebsite)/(\w+)/(\w+)$ $1/index.php?param1=$2¶m2=$3 [L]
RewriteRule ^(blahblahblah/mywebsite)/(\w+)/(\w+)/(\w+)$ $1/index.php?param1=$2¶m2=$3¶m3=$4 [L]
# etc.
Where $n
is a backreference to the corresponding captured group in the preceding RewriteRule
pattern (1st argument).
UDPATE: \w
is a shorthand character class that matches a-z
, A-Z
, 0-9
and _
(underscore).
A new directive is required for every number of parameters. You could combine them into a single (complex) directive but you would have lots of empty parameters when only a few parameters were passed (rather than not passing those parameters at all).
I'm assuming your URLs do not end in a trailing slash.
If, however, the .htaccess
file is located in the /blahblahblah/mywebsite
directory then then directives could be simplified a bit:
RewriteRule ^(\w+)$ index.php?param1=$1 [L]
RewriteRule ^(\w+)/(\w+)$ index.php?param1=$1¶m2=$2 [L]
RewriteRule ^(\w+)/([\w]+)/([\w]+)$ index.php?param1=$1¶m2=$2¶m3=$3 [L]
# etc.
Don't use URL parameters (alternative method)
An alternative approach is to not convert the path segments into URL parameters in .htaccess
and instead just pass everything to index.php
and let your PHP script split the URL into parameters. This allows for any number of parameters.
For example, your .htaccess
file then becomes rather more simple:
RewriteRule ^\w+(/\w+)*$ index.php [L]
(This assumes the .htaccess
file is located in /blahblahblah/mywebsite
directory, otherwise you need to add the necessary directory prefix as above.)
The RewriteRule
pattern simply validates the request URL is of the form /value1
or /value1/value2
or /value1/value2/value3
etc. And the request is rewritten to index.php
(the front-controller) to handle everything.
In index.php
you then examine $_SERVER['REQUEST_URI']
and parse the requested URL.
HTACCESS RewriteRules with pretty urls for SEO (without allowing access to physical file location)
1st solution: With your shown attempts/samples, please try following htaccess rules file. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Direct request to url for about.php where query string has language as en.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/pages/about.php [NC]
RewriteCond %{QUERY_STRING} ^lang=en [NC]
RewriteRule ^ en/about-us? [R=301,L]
RewriteRule ^(en)/about-us/?$ pages/about.php?lang=$1 [NC,L]
##Direct request to url for about.php where query string has language as fr.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/pages/about.php [NC]
RewriteCond %{QUERY_STRING} ^lang=fr
RewriteRule ^ fr/a-propos? [R=301,L]
RewriteRule ^(fr)/about-us/?$ pages/about.php?lang=$1 [NC,L]
##Existing rules by OP with additonal conditions added to them.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(fr|en)/(a-propos|about-us)/?$ pages/about.php?lang=$1&%{QUERY_STRING} [NC,L]
##Existing rules by OP with additonal conditions added to them.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(fr|en)/(a-propos|about-us)/?$ pages/about.php?lang=$1 [NC,QSA,L]
2nd solution: OR try following htaccess rules set with using THE_REQUEST
variable. Make sure either use above OR following rules only one at a time.
RewriteEngine ON
##Direct request to url for about.php where query string has language as en.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} \s/pages/about\.php\?lang=en\s [NC]
RewriteRule ^ en/about-us? [R=301,L]
RewriteRule ^(en)/about-us/?$ pages/about.php?lang=$1 [NC,L]
##Direct request to url for about.php where query string has language as fr.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} \s/pages/about\.php\?lang=fr\s [NC]
RewriteRule ^ fr/a-propos? [R=301,L]
RewriteRule ^(fr)/about-us/?$ pages/about.php?lang=$1 [NC,L]
##Existing rules by OP with addiotnal conditions added to them.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(fr|en)/(a-propos|about-us)$ pages/about.php?lang=$1&%{QUERY_STRING} [NC,L]
##Existing rules by OP with addiotnal conditions added to them.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(fr|en)/(a-propos|about-us)$ pages/about.php?lang=$1 [NC,QSA,L]
Related Topics
How to Create and Download a CSV File from PHP Script
How to Show Ajax Requests in Url
How to Find Out Where a Function Is Defined
Is PHP Compiled or Interpreted
Why Does PHP 5.2+ Disallow Abstract Static Class Methods
MySQL: Select Random Entry, But Weight Towards Certain Entries
Making Sure PHP Substr Finishes on a Word Not a Character
Execute PHP Scripts Within Node.Js Web Server
PHP List of Specific Files in a Directory
Pdo With Insert into Through Prepared Statements
PHP Threading Call to a PHP Function Asynchronously
: Operator (The 'Elvis Operator') in PHP
MySQL Datetime Fields and Daylight Savings Time - How to Reference the "Extra" Hour
PHP Date() Format When Inserting into Datetime in MySQL
Get Response from PHP File Using Ajax