写入会话的意外值

时间:2014-03-28 14:19:56

标签: php session zend-framework post-redirect-get

更新:已解决 检查当前请求是否是一个帖子是不够的。表单仍然按创建顺序传递给帮助程序。如果传递给帮助者的第一个表单不是发布的表单,则没有足够的验证来防止使用其详细信息而不是预期的发布表单。

在帮助程序中添加了if附加条款......

if ($postId)

应该是

if ($postId === $formId)

非常直接真的......只花了我2天才找到答案。

---以下原帖---

我试图在ZF1中实现自己的PRG(Post / Redirect / Get)模式。

我使用扩展Zend_Form的自定义表单类来添加setUniqueFormId方法,该方法基本上是带有表单名称的隐藏元素。表单与2个变量($persistData$redirectUrl)一起传递给动作助手。 问题是,当我有多个表单时,第一个$persistData$redirectUrl值总是用于任何后续表单,即使这些表单已被更改。 使用从最后一次调用传递给助手的值。

有关为何会出现这种情况的任何想法?任何帮助非常感谢。

更新:我认为这是使用动作助手的问题。每次调用它并传递新值时,所有先前的值都会更改。我对行动助手经纪人的内部并不熟悉。任何人都可以提出任何建议或提出建议吗?

---控制器行动---

// Create 2 new forms 
$testForm1 = new Application_Form_Test;
$testForm2 = new Application_Form_Test;

// Call a custom function on each form tp create a hidden field called 
// "unique_form_id" to help identify the form that has posted the data
$testForm1->setUniqueFormId('test_form_1');
$testForm2->setUniqueFormId('test_form_2');

// Call "Post Redirect Get" Helper and pass a boolean variable for $persistData
$formData1 = $this->_helper->postRedirectGet($testForm1, true);
$formData2 = $this->_helper->postRedirectGet($testForm2, false);

---控制器动作助手---

public function direct($form, $persistData = false, $redirectUrl = null)
    {
    $formId = $form->getElement('unique_form_id')->getValue();

    $currentUrl = implode   (
                            '/',
                            array   (
                                    $this->getRequest()->getModuleName(),
                                    $this->getRequest()->getControllerName(),
                                    $this->getRequest()->getActionName()
                                    )
                            );

    $session = new Zend_Session_Namespace('prg');

    $redirectUrl = $redirectUrl ? $redirectUrl : $currentUrl;

    if ($this->getRequest()->isPost())
        {
        $postId = $this->getRequest()->getPost('unique_form_id');

        if ($postId)
            {
            $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');

            $postUrl = $currentUrl;

            $session->$postUrl->$postId = array (
                                                'url'       => (string) $redirectUrl,
                                                'id'        => (string) $postId,
                                                'post'      => (array) $this->getRequest()->getPost(),
                                                'persist'   => (bool) $persistData
                                                );

            Zend_Session::writeClose(true);

            $response = $redirector ->setCode(303)
                                    ->setExit(true)
                                    ->gotoUrl($redirectUrl);

            return  $response;
            }
            else    {
                    return false;
                    }
        }
        else    {
                $urlSessionData = $session->$currentUrl;

                // Results shown below
                Zend_Debug::dump($urlSessionData);

                if ($urlSessionData->$formId != null)
                    {
                    $formSessionData = $urlSessionData->$formId;
                    $formPersist = $formSessionData['persist'];
                    $formPostData = $formSessionData['post'];

                    if (!$formPersist)
                        {
                        unset($urlSessionData->$formId);
                        }

                    if(!empty($formPostData))
                        {
                        $form->isValid($formPostData);
                        }

                    return $formPostData;
                    }
                    else    {
                            return false;
                            }
                }
    }

---前端控制器插件---

function preDispatch()
    {
    $session = new Zend_Session_Namespace('prg');

    $currentUrl = implode   (
                            '/',
                            array   (
                                    $this->getRequest()->getModuleName(),
                                    $this->getRequest()->getControllerName(),
                                    $this->getRequest()->getActionName()
                                    )
                            );

    // Check if current url is in prg sesison
    // If not, we have moved to another URL or its our first visit to the $currentUrl
    if ($session->$currentUrl === null)
        {
        // Remove all prg sessions
        Zend_Session::namespaceUnset('prg');
        }           

    return;
    }

---转储结果---

object(stdClass)#54 (2) 
    {
    ["test_form_1"] => array(4)
        {
        ["url"] => string(21) "admin/timeclock/index"
        ["id"] => string(11) "test_form_1"
        ["post"] => array(4)
            {
            ["test_element"] => string(0) ""
            ["submit"] => string(5) "Submit"
            ["unique_form_id"] => string(11) "test_form_1"
            }
        ["persist"] => bool(false) <-- Expected to be 'true'
        }

    ["test_form_2"] => array(4)
        {
        ["url"] => string(21) "admin/timeclock/index"
        ["id"] => string(11) "test_form_2"
        ["post"] => array(4)
            {
            ["test_element"] => string(0) ""
            ["submit"] => string(5) "Submit"
            ["unique_form_id"] => string(11) "test_form_2"
            }
        ["persist"] => bool(false) <-- Expected to be 'false'
        }
    }

1 个答案:

答案 0 :(得分:1)

我(愚蠢地)没有检查表单提交后表单是否传递给帮助程序是否是已发布的表单。这意味着如果发布的表单不是发布的第一个表单,则与第一个表单一起传递的值是存储在会话中的值。

if ($postId)应该是if ($postId === $formId)

public function direct($form, $persistData = false, $redirectUrl = null)
    {
    $formId = $form->getElement('unique_form_id')->getValue();

    $currentUrl = implode   (
                            '/',
                             array   (
                                     $this->getRequest()->getModuleName(),
                                     $this->getRequest()->getControllerName(),
                                     $this->getRequest()->getActionName()
                                     )
                            );

$session = new Zend_Session_Namespace('prg');

$redirectUrl = $redirectUrl ? $redirectUrl : $currentUrl;

if ($this->getRequest()->isPost())
    {
    $postId = $this->getRequest()->getPost('unique_form_id');

    if ($postId === $formId)
        {
        $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');

        $postUrl = $currentUrl;

        $session->$postUrl->$postId = array (
                                            'url'       => (string) $redirectUrl,
                                            'id'        => (string) $postId,
                                            'post'      => (array) $this->getRequest()->getPost(),
                                            'persist'   => (bool) $persistData
                                            );

        Zend_Session::writeClose(true);

        $response = $redirector ->setCode(303)
                                ->setExit(true)
                                ->gotoUrl($redirectUrl);

        return  $response;
        }
        else    {
                return false;
                }
    }
    else    {
            $urlSessionData = $session->$currentUrl;

            // Results shown below
            Zend_Debug::dump($urlSessionData);

            if ($urlSessionData->$formId != null)
                {
                $formSessionData = $urlSessionData->$formId;
                $formPersist = $formSessionData['persist'];
                $formPostData = $formSessionData['post'];

                if (!$formPersist)
                    {
                    unset($urlSessionData->$formId);
                    }

                if(!empty($formPostData))
                    {
                    $form->isValid($formPostData);
                    }

                return $formPostData;
                }
                else    {
                        return false;
                        }
            }
}