views:

750

answers:

7

Hello,

I have built a system that conforms to the mvc pattern in PHP. The controllers and actions are part of the urls in my application. So I have:

www.example.com/controller/action/

So now I am looking for a way to pass on variables. For forms I just use the post method, but sometimes I would just like to link to a different page and then pass on some variables.

I would like some suggestions on how to do this. I know the Zend Framework has the variables as key/value pairs after the action in the controller using the "/" character as a separator, like this:

www.example.com/controller/action/var1/value1/var2/value2

Is this the best way? This is actually the only way I know it's done. I am looking for an easy but yet good way to implement it.

Any suggestions are welcome.

+1  A: 

You have the option of passing on variables through either a GET or a POST.

GET will append variables to the URL, either in pretty format

 /controller/action/var1/value1/var2/value2

or the traditional way

 /controller/action/?var1=value1&var2=value2

In the former case, you will still need to write an Apache rewrite rule to extract the variables from the URL and route to the controller/action with the right set of variables as part of your $_REQUEST.

If you're using POST, you can add hidden values to each form as a way to pass along variables.

For variables that you wouldn't like to be public knowledge, you can use Sessions to store them server-side.

Pras
+1  A: 

You can also do GET queries like so:

www.site.com/controller/action?var1=value1&var2=value2

These will show up in the $_GET superglobal.

Richard Pistole
+2  A: 

var1/value1/var2/value2 is really not the best approach and it abuses the MVC controller/action/id structure. Either you need to rethink your design, use POST or query params. Most likely you could redo the design, for example if you have

/search/type/movie/format/divx/year/2000

You could redo that as

/movie/divx?year=2000

So your movie controller would search for divx format movies and then maybe use a helper or filter or client-side script to show only movies that match year == 2000.

aleemb
I wouldn't exactly call controller/action/id restful.
troelskn
That should have read MVC. fixed.
aleemb
+3  A: 

Frameworks like CodeIgniter let you pass the variables into the controller without disclosing the variable name -

/controller/action/foo/bar/

would get processed as:

function action( $id, $value){
  echo $id; // outputs 'foo'
  echo $value; // outputs 'bar'
}

http://codeigniter.com/user_guide/general/controllers.html

I like this as it gives you control of how many parameters your controller will accept, and if it is important that certain variables are never used, you can do logic or redirect appropriately.

postpostmodern
+1  A: 

Depending on your project, you might also try setting and reading values using PHP sessions. These values don't have to be passed from script to script as GET or POST values. One down-side (or up side) is that the variables cannot simply be passed as part of the URL (or bookmarked).

Joel Dare
+1  A: 

I'd avoid the key/value Zend style approach you mentioned before. The problem is it becomes trivial to create two different URLs

http://www.example.com/controller/action/var1/value1/var2/value2 
http://www.example.com/controller/action/var2/value2/var1/value1

that point to the same resource. While this works, part of the success of MVC style frameworks for web applications is they make it easier to provide a clean URL structure, and to associate a single URL on your site with every resource. The var1/value1/var2/value2 approach offers little advantage over key/value query strings.

The approach I'd take here is to eschew keys, and just just use values

http://www.example.com/example/list/value1/value2/value3

which will be passed into the action method as an array

class example extends Controller{ 
 public function list($args){
  //$args[0] = 'value1';
  //$args[1] = 'value2';  
  //$args[2] = 'value3';    
 }
}

By doing it this way, you're leaving it up to the end users of your system to decide how they want to handle $GET style variables, while encouraging a design that leads to cleaner, more stable, single resource URLs.

Alan Storm
+1  A: 

What I like to use in my CakePHP projects are "named params". Basically, my URLs look like this:

http://example.com/controller/action/param1:value1/param2:value2

You can see some more examples in the Cake's manual. I don't know if your framework supports this (or Zend), but if bakers did it, it can be done. :-)

dr Hannibal Lecter