Url Rewriting With PHP

URL rewriting with PHP

You can essentially do this 2 ways:

The .htaccess route with mod_rewrite

Add a file called .htaccess in your root folder, and add something like this:

RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1

This will tell Apache to enable mod_rewrite for this folder, and if it gets asked a URL matching the regular expression it rewrites it internally to what you want, without the end user seeing it. Easy, but inflexible, so if you need more power:

The PHP route

Put the following in your .htaccess instead: (note the leading slash)

FallbackResource /index.php

This will tell it to run your index.php for all files it cannot normally find in your site. In there you can then for example:

$path = ltrim($_SERVER['REQUEST_URI'], '/');    // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
if(empty($elements[0])) { // No path elements means home
ShowHomepage();
} else switch(array_shift($elements)) // Pop off first item and switch
{
case 'Some-text-goes-here':
ShowPicture($elements); // passes rest of parameters to internal function
break;
case 'more':
...
default:
header('HTTP/1.1 404 Not Found');
Show404Error();
}

This is how big sites and CMS-systems do it, because it allows far more flexibility in parsing URLs, config and database dependent URLs etc. For sporadic usage the hardcoded rewrite rules in .htaccess will do fine though.

URL rewriting in PHP

http://localhost/april/video?category=Programming-Language&cat_id=2

This can be transformed into:
http://localhost/Programming-Language/2

(notice that I shifted cat_id to the end, since I suspected it to be a page number.)

This is accomplished by placing the following in your .htaccess:

RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)$ /april/video?category=$1&cat_id=$2 [L]

Obviously you can then pick up the variables via $_GET request ($_GET['category'])

How to do URL re-writing in PHP?

A Beginner's Guide to mod_rewrite.

Typically this will be nothing more than enabling the mod_rewrite module (you likely already have it enabled with your host), and then adding a .htaccess file into your web-directory. Once you've done that, you are only a few lines away from being done. The tutorial linked above will take care of you.

Just for fun, here's a Kohana .htaccess file for rewriting:

# Turn on URL rewriting
RewriteEngine On

# Installation directory
RewriteBase /rootDir/

# Protect application and system files from being viewed
RewriteRule ^(application|modules|system) - [F,L]

# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Rewrite all other URLs to index.php/
RewriteRule .* index.php/$0 [PT,L]

What this will do is take all requests and channel them through the index.php file. So if you visited www.examplesite.com/subjects/php, you may actually be visiting www.examplesite.com/index.php?a=subjects&b=php.

If you find these URLs attractive, I would encourage you to go one step further and check out the MVC Framework (Model, View, Controller). It essentially allows you to treat your website like a group of functions:

www.mysite.com/jokes

public function jokes ($page = 1) {
# Show Joke Page (Defaults to page 1)
}

Or, www.mysite.com/jokes/2

public function jokes ($page = 1) {
# Show Page 2 of Jokes (Page 2 because of our different URL)
}

Notice how the first forward slash calls a function, and all that follow fill up the parameters of that function. It's really very nice, and make web-development much more fun!

.htaccess rewrite url if starts with numbers and add the complete part (incl. text) as parameter for another URL

Rewrite rules are really quite simple once you understand their structure:

  • On the left is a regular expression which determines which URLs from the browser the rule should match
  • Inside that regular expression, you can "capture" parts of the URL with parentheses ()
  • Next, is the URL you want to serve instead; it can include parts that you captured, using numbered placeholders $1, $2, etc. It's entirely up to you where you put these, and Apache won't guess
  • Finally, there are flags which act as options; in your example, you're using "NC" for "Not Case-sensitive", and "L" for "Last rule, stop here if this matches"

In your example, the pattern you are matching is ^[0-9]+[A-Za-z0-9-]+/?$, which is "from start of URL, 1 or more digits, one or more letters/digits/hyphens, 0 or 1 trailing slash, end of URL".

The only part you're capturing is ([A-Za-z0-9-]+), the "one or more letters/digits/hyphens" part; so that is being put into $1. So the rest of the URL is being "discarded" simply because you haven't told Apache you want to put it anywhere.

If you want to capture other parts, just move the parentheses, or add more. For instance, if you write ^([0-9]+)([A-Za-z0-9-]+)/?$ then $1 will contain the "one or more digits" part, and $2 will contain the "one or more letters/digits/hyphens" part.

Rewrite URL as user friendly names in php web app

Either your question is unclear or you have not (yet) really thought this through... If you want to rewrite pretty URLs into an internal request that refers to some specific object inside your data model, then you do need that object's ID inside the URL. Simply because the http servers rewriting logic cannot somehow guess that (typically numeric) ID somehow.

So I assume you want to finally use URLs along this scheme:

  • https://www.example.com/subjects/science/123

    => /subjects.php?subject=science&subject_id=123
  • https://www.example.com/topics/light-energy/234

    => /topics.php?topic=light-energy&topic_id=234
  • https://www.example.com/quizzes/check-your-grammar-skills/345

    => /quizzes.php?quizz=check-your-grammar-skills&id=345

For that situation you'd need a rewriting set like this:

RewriteEngine on
RewriteRule ^/?subjects/(\w+)/(\d+)$ /subjects.php?subject=$1&subjectid=$2 [END]
RewriteRule ^/?topics/(\w+)/(\d+)$ /topics.php?topic=$1&topic_id=$2 [END]
RewriteRule ^/?quizzes/(\w+)/(\d+)$ /quizzes.php?quizz=$1&id=$2 [END]

I personally would not use different names for the ID comlumn, but that is a question of personal choice and of how you internally match, I guess.

The above rule set will work in the http servers host configuration and likewise inside some dynamic configuration file (".htaccess" style file). you obviously need to have the http servers rewriting module loaded and activated. In case you decide to use a dynamic configuration rule also need to make sure that it's interpretation is enabled (see the AllowOverride directive in the documentation) and that the file is located in the http hosts DOCUMENT_ROOT and readable by the server process.

In case you get a http status 500 back for requests to those URLs ("internal server error"), then chances are that you operate a very old version of the apache http server. In that case try using the [L] flag instead of the [END] flag.


And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

PHP When rewrite pages url then the $_get not working

In the code you posted there is no $_GET['cat_id'] variable, unless there is a cat_id URL parameter on the URL being requested (which you've not stated).

If the .htaccess file and index.php script are located at http://example.com/~admin/ (where ~admin is an Apache per-user web directory) then a request of the form http://example.com/~admin/category/men-items (as in your example) would result in the $params['category'] array index holding the value men-items (from the named captured group in the matching regex). If that is what you are referring to? But there is no "cat_id" here.


UPDATE:

I just want now i have two links now on my website 1: /~admin/category.php?cat_id=2 and 2: /~admin/category/men-items. it will create content duplicate issue in feature i want just one link like 2: /~admin/category/men-items so need to redirect 1 link to 2

To canonicalise the URL for SEO you can do something like the following at the top of your .htaccess file:

RewriteCond %{QUERY_STRING} ^cat_id=2$
RewriteRule ^category\.php$ /~admin/category/men-items [R=301,L]

If the old URL category.php still exists as a physical file then you'll need to ensure that MultiViews is disabled in order to avoid conflicts with mod_rewrite. For example, at the very top of your .htaccess file:

Options -MultiViews


Related Topics



Leave a reply



Submit