SitePoint Sponsor

User Tag List

Results 1 to 6 of 6

Hybrid View

  1. #1
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Rewrite rule for invalid query

    For a rewrite that seems to work, I want to be sure itís really correct, lest there be some possible error Iím unaware of.

    I'm using this:
    Code:
    RewriteRule ^(\d+)$ index.php?a=$1
    RewriteRule ^([\D+]|[\D|\d]+)$ index.php [L]
    to do this
    Code:
    slideshow/12      =>     slideshow/index.php$a=12
    The first rule handles numbers (with the index.php handling out-of-range numbers), and for thoroughness I want any invalid queries such as
    Code:
    slideshow/hgyt
    slideshow/23ab
    slideshow/23&
    to go index.php with no query string.

    Iím hoping the second ruleís condition says: ďany non-numeric or any mix of numeric and non-numericĒ. It seems to work.

    Is it fully correct?

    Thank you.

  2. #2
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,278
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    First let's analyze what you have so far.

    1. The plus sign needs to go outside the character class.

    Before
    [\D+]

    After
    [\D]+

    In fact, in this specific situation, you don't need a character class at all.

    After
    \D+

    2. When inside a character class, the "|" character does not mean "or". It's simply treated as the literal "|" character.

    Before
    [\D|\d]+

    After
    [\D\d]+

    3. Matching all non-digit characters, as well as all digit characters, effectively means you're matching on *any* character.

    Before
    [\D\d]+

    After
    .+

    4. That the second part of your ORed pattern will match anything makes the first part redundant.

    Before
    (\D+|.+)

    After
    (.+)

    And that's what your pattern boils down to.

    What you could have done is simply this:

    RewriteRule \D index.php

    Note the lack of any "^" start or "$" end anchors. This way, it doesn't matter where in the string the non-digit character matches. You're simply detecting whether a non-digit character exists.

    Note also that the path "index.php" contains non-digit characters, so you'll also be rewriting "index.php" to "index.php". It's not the worst thing in the world, but if you want to avoid it, you can create a rewrite condition.

    # Use the next rewrite rule only if the URL isn't already pointing to a real file
    RewriteCond ${REQUEST_FILENAME} !-f

    RewriteRule \D index.php


    With all that out of the way, let's examine some of your attempts at validation.

    The first rule handles numbers (with the index.php handling out-of-range numbers), and for thoroughness I want any invalid queries to go index.php with no query string.
    The problem with using rewrite rules to identify and correct for invalid URLs is that there's nothing stopping me from bypassing your pretty URLs and typing the real URL in my address bar instead.

    slideshow/index.php?a=hgyt

    Which means your PHP must be able to handle invalid queries. And if your PHP is already capable of handling invalid queries, then there's no point in using rewrite rules to apply an extra and ineffective layer of validation. I would get rid of both your rewrite rules and simply do this:

    RewriteCond ${REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?a=$1 [QSA]
    "First make it work. Then make it better."

  3. #3
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    First let's analyze what you have so far. ...

    I would get rid of both your rewrite rules and simply do this:

    RewriteCond ${REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?a=$1 [QSA]

    Thank you. This works perfectly. I've added an is_numeric() filter to the index file.

    The detailed explanation is much appreciated -- good learning for a beginner wanting thorough understanding.

  4. #4
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    First let's analyze what you have so far ...

    RewriteCond ${REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?a=$1 [QSA]

    Puzzling result now:

    This works perfectly in my local server (Mac Apache) but not in my remote server (Linux Litespeed).

  5. #5
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,278
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Andante View Post
    Puzzling result now:

    This works perfectly in my local server (Mac Apache) but not in my remote server (Linux Litespeed).
    I had a typo.

    RewriteCond ${REQUEST_FILENAME} !-f

    should be

    RewriteCond %{REQUEST_FILENAME} !-f
    "First make it work. Then make it better."

  6. #6
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ... should be

    RewriteCond %{REQUEST_FILENAME} !-f

    Thank you. Now it works perfectly.

    (I wonder why ${REQUEST_FILENAME} does work in my local Apache...?)

    Your help is much appreciated.


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
  •