Pretty Urls With .Htaccess

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



Leave a reply



Submit