模型视图控制器 - PHP 中使用 MVC 的 Post-Redirect-Get (PRG) 的最佳实践


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

MVC 的 PRG 模式有什么最佳实践吗?
在本教程中:

http://www.theserverside.com/news/1365146/Redirect-After-Post建议的解决方案需要 4 个操作:
Create_Item (POST) => "重置"表单并重定向到Display_Item
Display_Item (GET) => 显示表单(如果存在,则包含临时数据和错误)
Store_Item (POST) => 尝试将数据保存到数据库,如果错误,保存错误并重定向到Display_Item,如果成功,则重定向到Display_Stored
Display_Stored (GET) => 显示创建的项目或成功消息 tec。

现在,我认为使用 POST 进行第一个操作是一个问题,因为我们不能用链接开始表单。在Create_Item中使用 GET 似乎是更好的选择。
而且,我们可以对 3 个操作执行相同的操作(对 Create_Item 和Display_Item使用相同的操作,但使用额外的标志来重置表单,例如:

http://www.example.com/controller/Create_Item/?reset=1
而且我们也可以只用 2 个动作来做同样的事情,因为我们可以在 Create_Item 中使用 if 来检查请求是 GET 还是 POST(因此我们将Display_Item与 Store_Item 相结合)。

而且我们也可以只用 1 个动作做同样的事情,因为我们可以有一个额外的标志(在 URL 查询或会话中)来显示结果而不是表单:
GET http://www.example.com/controller/Create_Item/?reset=1 => 显示一个新表单并重定向到下一个 URL
GET http://www.example.com/controller/Create_Item/=> 显示一个包含临时数据和错误的表单(如果存在
)POST http://www.example.com/controller/Create_Item/=> 将错误保存在临时中,或将数据保存在数据库中(并为成功设置会话标志)并重定向到上面的 URL 或下一个 URL
获取 http://www.example.com/controller/Create_Item/=> 如果 $_SESSION['成功'] 显示结果

就个人而言,我喜欢有 4 个动作的想法,但我与其他选项相比没有任何真正的优势。但是如果没有真正的标准,我选择我的设计并不安全。
有人知道每个设计的缺点(如果有的话)吗?

例如,我看到 4 个动作更干净,但如果我们想更改临时数据的保存方式,我们需要在 4 个地方更改它。

谢谢!

模式是GET一个空白表单,修改表单的内容,然后将其POST到服务器,然后服务器将重定向发送到另一个页面,这是一个GET,也许是一个页面说Form submitted successfully.。(获取>)>重定向后>获取

第一个动作并不是真的POST.这是填写表格并提交的最终结果。该指南更多的是关于该POST之后该怎么做,就好像您不进行重定向一样,那么用户就会留在一个页面上Form submitted successfully,说明他们可以在哪里按 F5 并执行另一个POST。但是,通过该重定向,它们通过安全GET出现在该结果页面上,这不会导致双重帖子。

至于实现,你应该在服务器端有自己的操作。这与MVC/RESTful实现一致。

  • GET/url?action=new -> 调用 new_form() 方法来呈现新表单
  • POST/url?action=
  • create -> 调用 create_form() 方法保存并重定向到/url?action=show&id=1234
  • GET/url?action=show&id=1234 -> 调用 show_form() 方法来显示结果
  • POST/url?action=save&id=1234 -> 调用 save_form() 方法来保存和重定向

如果您想让第二个动作调用save,您可以在此处使用 3 个操作。大多数 REST/CRUD 约定都使用 4,但选择权在您手中。好处与首先采用 REST/MVC 路线相同。

另请参阅以下资源:

  • RESTful Web Services
  • 这涵盖了 RESTful 控制器的典型约定。它涵盖了rails,但如果你想走REST路线,它仍然适用于PHP。