Page 1 of 1

regex for query string in mvc

Posted: Thu Aug 26, 2010 11:32 am
by impeto
Hey guys,

I have an MVC framework and I would like to get the name of the module, controller and function from the query string; something like:

Code: Select all

http://mysite.com/index.php?module=shop&controller=cart&function=add&prod=12345
can anyone come up with a regex that would only extract the module, controller and function and nothing else? I have tried for the past 1/2 and i just gave up.

Thanks!

Re: regex for query string in mvc

Posted: Thu Aug 26, 2010 11:53 am
by AbraCadaver
If PHP, no need for a regex: viewtopic.php?f=1&t=120404

Also, depending on how you're using it, why not just use the $_GET vars?

Re: regex for query string in mvc

Posted: Thu Aug 26, 2010 12:56 pm
by impeto
That's how I'm doing it right now (using the $_GET vars). First I look at the $_SERVER['REQUEST_URI'] to check for uri segments in the form of "module/controller/function" and if I can't find anything in there, I look at the $_GET array. The problem that I have is that my framework allows user input filtering before the uri class is instantiated. I guess I can move that after the uri class. I was also thinking that using regex like that would be more elegant -- as far as coding :)

Thanks for your reply.

Re: regex for query string in mvc

Posted: Sat Aug 28, 2010 10:14 am
by ridgerunner
This problem gives me an excuse to try out a new technique I just learned from Steve Levithan's excellent blog:
Capturing Multiple, Optional HTML Attribute Values.

The problem is that the three values you want to extract from the URI query string may appear in any order and may be mixed in with any number of other parameter=values. How does one extract them with a regular expression? Well, that blog post provides a slick way to do this. Here is a script I whipped up which extracts the three parameters you need. Note however, that if a parameter is missing from the query string, the $matches variable will hold one of two values for that entry: 1.) an empty string if the missing parameter comes before another one which is not missing, or 2.) the $matches array element will simply not exist if the missing parameter has no matching parameters following it. Your script needs to handle both scenerios. Running the following script demonstrates how all this works.

Code: Select all

<?php // File: test.php
// Here is the regex in verbose commented format.
$re = '/# Regex to match three specific prop=values in URI query string.
\?                           # Start of query string is a literal "?"
(?>                          # Atomic group prohibits backtracking.
  &?+module=([^&#\s]*+)      # $1: Module value.
| &?+controller=([^&#\s]*+)  # $2: Controller value.
| &?+function=([^&#\s]*+)    # $3: Function value.
| &?+[^=&#\s]*+=[^&#\s]*+    # Match and discard any other "prop=value".
)*+                          # Loop through all "prop=value" in query.
(?:\#|$)                     # End of query is EOS or start of fragment.
/ix';
// Some example data to test different orders and missing values
$data = array(
// Test parameters occuring in different orders.
    "http://mysite.com/index.php?module=shop&controller=cart&function=add&prod=12345", // 1
    "http://mysite.com/index.php?controller=cart&function=add&prod=12345&module=shop", // 2
    "http://mysite.com/index.php?function=add&prod=12345&module=shop&controller=cart", // 3
    "http://mysite.com/index.php?prod=12345&module=shop&controller=cart&function=add", // 4
// Test ending the query with a fragment rather than end of string.
    "http://mysite.com/index.php?prod=12345&module=shop&controller=cart&function=add#fragment", // 5
// Test what happens when there are missing expected parameters.
    "http://mysite.com/index.php?controller=cart&function=add&prod=12345", // 6
    "http://mysite.com/index.php?module=shop&function=add&prod=12345", // 7
    "http://mysite.com/index.php?module=shop&controller=cart&prod=12345", // 8
    "http://mysite.com/index.php?module=shop", // 9
    "http://mysite.com/index.php?&prod=12345", // 10
);
// Ok lets do this...
for ($i = 0; $i < count($data); ++$i) {
    if (preg_match($re, $data[$i],  $matches)) {
        printf("\nMatch number %d:\n", $i + 1);
        if (!isset($matches[1])) $matches[1] = '(not in query string)';
        if (!isset($matches[2])) $matches[2] = '(not in query string)';
        if (!isset($matches[3])) $matches[3] = '(not in query string)';
        printf("\tmodule     = %s\n", $matches[1]);
        printf("\tcontroller = %s\n", $matches[2]);
        printf("\tfunction   = %s\n", $matches[3]);
    }
}
?>
In case you are unable to run this from the command line, here is the output from the script:

Code: Select all

O:\TEST_PHP>php test.php

Match number 1:
        module     = shop
        controller = cart
        function   = add

Match number 2:
        module     = shop
        controller = cart
        function   = add

Match number 3:
        module     = shop
        controller = cart
        function   = add

Match number 4:
        module     = shop
        controller = cart
        function   = add

Match number 5:
        module     = shop
        controller = cart
        function   = add

Match number 6:
        module     =
        controller = cart
        function   = add

Match number 7:
        module     = shop
        controller =
        function   = add

Match number 8:
        module     = shop
        controller = cart
        function   = (not in query string)

Match number 9:
        module     = shop
        controller = (not in query string)
        function   = (not in query string)

Match number 10:
        module     = (not in query string)
        controller = (not in query string)
        function   = (not in query string)

O:\TEST_PHP>
Hope this helps!
:)

Re: regex for query string in mvc

Posted: Sun Aug 29, 2010 2:35 pm
by impeto
That is exactly what I'm looking for! Thank you sooooo much! Right now I am getting those values from the $_GET array, but my framework has an option to change the contents of that array via custom filters or even to empty the array if the site admin wants to. This is a lot better because it gets the values from the URI.

Again, Thank you!