SitePoint Sponsor

User Tag List

Results 1 to 20 of 20
  1. #1
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Exclamation Give me a URL Rewriting Rule Please :)

    Hello,
    I know I will make you mad at asking this question. But I have so much faith in people here helping me out that I will ask anyways.

    I have URLs like

    http://www.mysite.com/category.php?c...tname=Finance&
    page=1&orderby=name&order=asc (categories page)

    I want it to be something like
    www.mysite.com/category/13/Finance/1/name/asc

    All of the other URLs are also like this. Can you gurus please help me out.

    1. Please give me rule for this.
    2. Also tell me will the alternate urls with .php file names also work or will have to rewrite all my site links from now on.
    3. In PHP, how can i target the variables values like 13, Finance, 1, name, asc.
    4. Also, does the order of these variables matter in the URL.


    I browsed the site forum.modrewrite.com but it was so tricky and i have a deadline to beat. (Yeah, I know. In the end it all fall backs to that )

    I know there must be tons of difficulties and questions coming, but please, I am here and I need you guys' help.

    Thanks a LOT.

    Khuram
    Last edited by khuramyz; Nov 8, 2007 at 03:59.

  2. #2
    SitePoint Zealot Dachande663's Avatar
    Join Date
    Feb 2005
    Location
    Birmingham, UK
    Posts
    151
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Put this in a .htaccess document
    Code:
    RewriteEngine on
    RewriteRule ^category/([0-9]+)/([a-zA-Z0-9]+)/([0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ category.php?cat=$1&catname=$2&page=$3&orderby=$4&order=$5
    1) That's your rule
    2) The original location (category.php) will still work as usual
    3) Use GET e.g. $_GET['order'] for order
    4) Yes, if one is missing or in the wrong order e.g. /asc/name it won't work
    5) As always, make sure you sanitise these input values (mysql_real_escape_string etc)
    Web Developer & Geek: hybridlogic.co.uk ~ lukelanchester.com

  3. #3
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is cool.
    I have a similar pages for the store.php and deals.php with similar query string attributes. Cant we generalize this rule to say something like with introducing variables like $1, $2 ?

    Thanks in advance.

  4. #4
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  5. #5
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'd suggest you simply have a rule that catches everything (.*) and do all url parsing in php. This is much easier.

  6. #6
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok that would be cool stereofrog.
    can you tell me tutorial about this approach, i will give it a try.

    Although I must say that I dont have a central MVC for my site. I have header footer pages which are included and the site keeps running. so that may hinder this approach. dont you say ?

  7. #7
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not aware of any tutorials on this, but it's actually quite simple. Make a .htaccess like this
    Code:
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .* index.php?path=$0 [QSA]
    This will redirect everything like "site.com/foo/bar/baz" to "site.com/index.php?path=foo/bar/baz". In the "index.php" analyze the "path" parameter and act accordingly.

  8. #8
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmmm that would mean a considerable change to the heirarchy of my site. I would like to go with the solution of Dachande663.
    Can you help me device a solution for a generic rewrite rule.

  9. #9
    SitePoint Zealot Dachande663's Avatar
    Join Date
    Feb 2005
    Location
    Birmingham, UK
    Posts
    151
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @stereofrog: by doing it in mod_rewrite it can handle the work a bit faster and provides another layer of security.

    @khuramyz: If the store and deals pages expect the same arguments as cat then you can simply copy the rule like so:
    Code:
    RewriteRule ^category/([0-9]+)/([a-zA-Z0-9]+)/([0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ category.php?cat=$1&catname=$2&page=$3&orderby=$4&order=$5
    RewriteRule ^store/([0-9]+)/([a-zA-Z0-9]+)/([0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ store.php?cat=$1&catname=$2&page=$3&orderby=$4&order=$5
    RewriteRule ^deals/([0-9]+)/([a-zA-Z0-9]+)/([0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ deals.php?cat=$1&catname=$2&page=$3&orderby=$4&order=$5
    If they don't just change each rule to suit and it will work. For the contact, about etc pages you can either create an actually directory with an index page or use something like this:
    Code:
    RewriteRule ^contact-us/?$ static/contact-us.php
    RewriteRule ^about/?$ static/about.php
    and then put all of those pages in a directory called static. Hope this helps.
    Web Developer & Geek: hybridlogic.co.uk ~ lukelanchester.com

  10. #10
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    And then you get a complicated mess like that above Dachande.
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  11. #11
    SitePoint Zealot Dachande663's Avatar
    Join Date
    Feb 2005
    Location
    Birmingham, UK
    Posts
    151
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Personally I'd rather have a few lines in a htaccess file than a list of regular expressions and then relevant actions in PHP trying to decide what goes where. But for things like 'about' I normally just have a directory. And for situations like order by etc I either use get strings or key pairs actually in the URI to stop the order been as important. (And finally I use a PHP based rewriting system in one of my projects and I can tell you mod_rewrite is by far the easiest solution).
    Web Developer & Geek: hybridlogic.co.uk ~ lukelanchester.com

  12. #12
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Very simply, match everything that you don't want to be passed straight through by the HTTP server, parse the REQUEST_URI or PATH_INFO - e.g., explode("/",$_SERVER['REQUEST_URI']) - and write a tree of nested switches to handle every possible URI, defaulting to a 404 error page for anything you don't want to process.

    Here, we ignore all script, stylesheet, image, and other media files, and process everything else in index.php:

    Code:
    RewriteEngine On
    RewriteRule !\.(asx|avi|css|flv|gif|htm|html|ico|jpg|js|mov|mpeg|mpg|php|png|rm|rv|swf|wmv)$ index.php

  13. #13
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    I'd suggest you simply have a rule that catches everything (.*) and do all url parsing in php. This is much easier.
    Don't validate user input, that's so much easier
    Saul

  14. #14
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by php_daemon View Post
    Don't validate user input, that's so much easier
    None of this eliminates the need for validating user input. You still have to ensure correct datatypes, argument is within bounds, etc., and provide a suitable fallback for malformed requests.

  15. #15
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I didn't say it does. But using catch all is almost as bad as not validating the input.
    Saul

  16. #16
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by php_daemon View Post
    I didn't say it does. But using catch all is almost as bad as not validating the input.
    True. Don't catch everything. The Web server can dish up JavaScript and images more efficiently without any PHP processing unless you have a specific reason to catch them, e.g., to prevent code peeking, hotlinking, etc.

  17. #17
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Correct, that's why there's RewriteCond %{REQUEST_FILENAME} !-f above. As for security, I don't see how it depends on having more or less rewrite rules in htaccess. Of course, the php file should always validate its input, no matter if it comes from rewriting or somewhere else.

  18. #18
    SitePoint Addict khuramyz's Avatar
    Join Date
    Oct 2005
    Location
    Manchester, UK
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi I would like to add something to this thread.

    I wanted to say that cant we have a simple rewrite rule which could go like

    http://www.mysite.com/category/name=...name/order=asc

    and now we could parse it like,

    the string between first pair of "/" will be the page name
    and next strings would be key-value pairs from QS.

    I have done the technique where index.php catches everything and then we include stuff though the php and believe its a nightmare. I had about 100 cases and that bloody file kept getting longer and longer. Offcourse I had to write cases for that as I was doing some processing and data updation on each page load. But believe me, I dont wanna get into that again.

    That is why I submitted to you people last night.

    regards

  19. #19
    SitePoint Zealot Dachande663's Avatar
    Join Date
    Feb 2005
    Location
    Birmingham, UK
    Posts
    151
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    RewriteRule ^category/(.+)/?$ category.php?qs=$1
    PHP Code:
    $qs_arr explode('/',$_GET['qs']);
    foreach (
    $qs_arr as $qs_pair) {
    $qs_vals explode('=',$qs_pair);
    $query_strings[$qs_vals[0]]=$qs_values[1];
    }
    print_r($query_strings); 
    Off the top of my head, it would require more validation i.e. making sure values are set, sanitising them, but it's a starting point.
    Web Developer & Geek: hybridlogic.co.uk ~ lukelanchester.com

  20. #20
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by khuramyz View Post
    I have done the technique where index.php catches everything and then we include stuff though the php and believe its a nightmare. I had about 100 cases and that bloody file kept getting longer and longer.
    You're right that it can become an unmanageable nightmare if you handle everything in index.php. It's helpful to design your URL namespace in advance and break it up into separate files. That way you don't end up with a confusing mess of nested switches.

    index.php:

    PHP Code:
    $args explode("/",$_SERVER['REQUEST_URI']); // it's actually a little more complicated to get a clean array, but this is illustrative

    switch($args[0]) {
    case 
    "forum":
     include(
    'forum.php');
     break;
    case 
    "blog":
     include(
    'blog.php');
     break;

    ...

    default:
     
    header('HTTP/1.1 404 Not Found');
     echo 
    "The requested object wasn't found here.";
     exit();

    forum.php:

    PHP Code:
    $forum = new Forum();

    switch(
    $args[1]) {
    case 
    "view_topic":
     
    $topicId $args[2];
     
    forum->viewTopic($topicId); // this method should validate $topicId
     
    break;

    ...

    default:
     
    $forum->topicList();
     break;



Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •