Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for Post-Redirect-Get (PRG) with MVC in PHP

Is there any best practice for PRG pattern with MVC?
In this tutorial:
http://www.theserverside.com/news/1365146/Redirect-After-Post
the proposed solution requires 4 actions:
Create_Item (POST) => "resets" the form and redirects to Display_Item
Display_Item (GET) => shows the form (with temp data and errors if exists)
Store_Item (POST) => try to save data to DB, if errors, save errors and redirect to Display_Item, if success redirect to Display_Stored
Display_Stored (GET) => shows the item created or a success message, tec.

Now, I think that to have the first action with POST is a problem, because we can't start the form with a link. Using GET in Create_Item seems a better option.
And also, we can do the same with 3 actions (using the same action for Create_Item and Display_Item, but with an extra flag for reseting the form, for example:
http://www.example.com/controller/Create_Item/?reset=1

And also we can do the same with just 2 actions, because we can use an if inside Create_Item for checking if the request is GET or POST (so we are combining Display_Item with Store_Item).

And also we can do the same with just 1 action, because we can have an extra flag (in the URL query or in a session) for showing the results instead of the form:
GET http://www.example.com/controller/Create_Item/?reset=1 => shows a new form and redirects to the next URL
GET http://www.example.com/controller/Create_Item/ => shows a form with temp data and errors if exists
POST http://www.example.com/controller/Create_Item/ => save errors in temp, or data in DB (and set a session flag for success) and redirects to above URL or next URL
GET http://www.example.com/controller/Create_Item/ => if $_SESSION['success'] show results

Personally I like the idea of having 4 actions, but I don't have any real advantage over the others options. But I don't feel secure choosing my design without a real criteria.
Does somebody know the PROS and CONS of each design (if any)?

For example, I see the 4 actions cleaner, but if we want to change how the temp data is saved, we need to change it in 4 places.

Thanks!

like image 578
Enrique Avatar asked May 08 '11 22:05

Enrique


1 Answers

The pattern is to GET a blank form, modify the contents of the form, then POST that to the server, which then sends a redirect to another page which is a GET, perhaps to a page saying Form submitted successfully.. (Get->)Post->Redirect->Get

The first action is not really POST. That's the end result of completing a form and submitting it. The guide is more about what to do after that POST, as if you do not do a redirect, then the user is left on a page saying Form submitted successfully where they could just hit F5 and do another POST. With that redirect however, they're on that results page via a safe GET which will not result in a double post.

As for the implementation, you should have each be its own action on the server side. This is inline with the MVC / RESTful implementation.

  • GET /url?action=new -> Call new_form() method to render a new form
  • POST /url?action=create -> Call create_form() method to save and redirect to /url?action=show&id=1234
  • GET /url?action=show&id=1234 -> Call show_form() method to display the result
  • POST /url?action=save&id=1234 -> Call save_form() method to save and redirect

You could use 3 actions here instead if you wanted to have the 2nd action call save. Most REST/CRUD conventions use the 4, but the choice is yours. The benefits are the same as going the REST/MVC route in the first place.

See these resources as well:

  • RESTful web services
  • This covers typical conventions for RESTful controllers. It covers rails, but still applies to PHP as well if you're wanting to go the REST route.
like image 182
Bryan Drewery Avatar answered Nov 20 '22 07:11

Bryan Drewery