简体   繁体   English

在Zend Framework PHP中的页面之间持久存储数据时,使用会话变量与请求参数

[英]Using session variables versus Request parameters when persisting data between pages in Zend Framework PHP

I'm trying to better understand what the best method would be to persist data between requests in this scenario (using Zend Framework): 我试图更好地了解在这种情况下(使用Zend Framework)在请求之间保留数据的最佳方法是:

Say I have an Events controller and the default (index) view displays any existing Announcements (if there are any), and a link to Add a new Announcement (Both Event and Announcement are arbitrary objects). 假设我有一个“事件”控制器,并且默认(索引)视图显示任何现有的公告(如果有的话),以及指向“添加新公告”的链接(“事件”和“公告”都是任意对象)。 I'm trying to retrieve the eventId so I can associate the new Announcement with it when saving it to the database. 我正在尝试检索eventId,以便将新的Announcement与之关联时将其保存到数据库中。 Compositionally, an Event consists of 0 to many Announcements. 从结构上讲,一个事件包含0到许多公告。 From my limited understanding of the Zend Framework, I see two main options. 从对Zend框架的有限了解中,我看到了两个主要选择。

Option one: Make the URL something like '/event/addAnnouncement/eventId/5', which makes retrieving the eventId easy via route/path parameters. 选项一:使URL类似于“ / event / addAnnouncement / eventId / 5”,这使得通过route / path参数轻松检索eventId。

Option two: In the indexAction of the controller, save the eventId to a session variable, which can then be retrieved in the addAnnouncementAction of the Event controller. 选项二:在控制器的indexAction中,将eventId保存到一个会话变量中,然后可以在Event控制器的addAnnouncementAction中检索该变量。 This way the Add Announcement link would simply be '/event/addAnnouncement/'. 这样,“添加公告”链接将只是“ / event / addAnnouncement /”。

Can anyone shed some light on which of these two ways is better, or if there is another way I'm not aware of? 谁能阐明这两种方法中的哪一种更好,或者还有我不知道的另一种方法?

As always, any help is much appreciated. 与往常一样,我们非常感谢您的帮助。 Thanks. 谢谢。

The question to ask yourself is, how long do you need to persist the data? 要问自己的问题是,您需要将数据保留多长时间?
If you only need to save the data to pass it to the next action you can use POST or GET , the GET would pass through the url and the POST would not( typically ). 如果只需要保存数据以将其传递到下一个操作,则可以使用POSTGET ,而GET将通过url,而POST则不会( 通常 )。

The example you presented would suggest that you need to persist the data just long enough to validate, filter and process the data. 您提供的示例将建议您将数据保留足够长的时间,以验证,过滤和处理数据。 So you would likely be very satisfied passing the few pieces of data around as parameters( POST or GET ). 因此,您可能会非常满意地将一些数据作为参数传递( POSTGET )。 This would provide the temporary persistence you need and also provide the added benefit of the data expiring as soon as a request was made that did not pass the variables. 这将提供您所需的临时持久性,并且还提供在未传递变量的请求后数据过期的额外好处。

A quick example (assume your form passes data with the POST method): 一个简单的示例(假设您的表单使用POST方法传递数据):

   if ($this->getRequest()->isPost()) {
        if ($form->isValid($this->getRequest()->getPost()){
            $data = $form->getValues();//filtered values from form
            $model = new Appliction_Model_DbTable_MyTable();
            $model->save($data);
            //but you need to pass the users name from the form to another action
            //there are many tools in ZF to do this with, this is just one example
            return $this->getHelper('Redirector')->gotoSimple(
                                                   'action' => 'newaction', 
                                                    array('name' => $data['name'])//passed data
                                                   ); 
        }

}

if you need to persist data for a longer period of time then the $_SESSION may come in handy. 如果您需要将数据保留更长的时间,则$ _SESSION可能会派上用场。 In ZF you will typically use Zend_Session_Namespace() to manipulate session data. 在ZF中,通常将使用Zend_Session_Namespace()处理会话数据。
It's easy to use Zend_Session_Namespace , here is an example of how I often use it. 使用Zend_Session_Namespace很容易,这是我经常使用它的示例。

class IndexController extends Zend_Controller_Action {
protected $_session;

public function init() {
    //assign the session to the property and give the namespace a name.
    $this->_session = new Zend_Session_Namespace('User');
}
public function indexAction() {
    //using the previous example
    $form = new Application_Form_MyForm();

     if ($this->getRequest()->isPost()) {
        if ($form->isValid($this->getRequest()->getPost()){
            $data = $form->getValues();//filtered values from form
            //this time we'll add the data to the session
            $this->_session->userName = $data['user'];//assign a string to the session
            //we can also assign all of the form data to one session variable as an array or object
            $this->_session->formData = $data;
            return $this->getHelper('Redirector')->gotoSimple('action'=>'next');
        }
    }
    $this->view->form = $form;
}
public function nextAction() {
   //retrieve session variables and assign them to the view for demonstration
   $this->view->userData = $this->_session->formData;//an array of values from previous actions form
   $this->view->userName = $this->_session->userName;//a string value
    }
  }
}

any data you need to persist in your application can sent to any action, controller or module. 您需要在应用程序中保留的任何数据都可以发送到任何操作,控制器或模块。 Just remember that if you resubmit that form the information saved to those particular session variables will be over written. 请记住,如果您重新提交该表单,则保存到这些特定会话变量的信息将被覆盖。

There is one more option in ZF that kind of falls between passing parameters around and storing data in sessions, Zend_Registry . ZF中还有一个选项,介于传递参数和在会话中存储数据之间, Zend_Registry It's use is very similar to Zend_Session_Namespace and is often used to save configuration data in the bootstrap (but can store almost anything you need to store) and is also used by a number of internal Zend classes most notably the flashmessenger action helper . 它的用法与Zend_Session_Namespace非常相似,通常用于将配置数据保存在引导程序中(但可以存储几乎所有您需要存储的内容),并且也由许多内部Zend类使用,最著名的是flashmessenger操作助手

 //Bootstrap.php
 protected function _initRegistry() {

        //make application.ini configuration available in registry
        $config = new Zend_Config($this->getOptions());
        //set data in registry
        Zend_Registry::set('config', $config);
    }
 protected function _initView() {
        //Initialize view
        $view = new Zend_View();
        //get data from registry
        $view->doctype(Zend_Registry::get('config')->resources->view->doctype);
        //...truncated...
        //Return it, so that it can be stored by the bootstrap
        return $view;
    }

I hope this helps. 我希望这有帮助。 Pleas check out these links if you have more questions: 如果您还有其他问题,请检查以下链接:

The ZF Request Object ZF请求对象
Zend_Session_Namespace Zend_Session_Namespace
Zend_Registry Zend_Registry

Option 1 is better, although in your example this is not a POST (but it could be done with a POST). 选项1更好,尽管在您的示例中这不是POST(但可以通过POST完成)。

The problems with option 2 are: 选项2的问题是:

  • If a user had multiple windows or tabs open at the same time, relating to different events, how would you track which event ID should be used? 如果用户同时打开与不同事件有关的多个窗口或选项卡,您将如何跟踪应使用哪个事件ID?
  • If a user bookmarked the add event page and came back later, the session var may not be set 如果用户为添加事件页面添加了书签并稍后返回,则可能无法设置会话变量

Option 2 is also a little more complicated to implement, and adds a reliance on sessions. 选项2的实现也有些复杂,并且增加了对会话的依赖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM