【问题标题】:Unexpected value written to session写入会话的意外值
【发布时间】:2016-10-19 14:35:50
【问题描述】:

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

在 helper 中添加了 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'
        }
    }

【问题讨论】:

  • 你的方案是什么?验证form1和form2验证和显示?只是验证form1并显示?只是验证form2并显示?其他的?
  • 您能否尝试将问题缩小到更少量的代码?您发布的代码量可能有问题,我们无法执行它来测试。
  • 我理解为什么这总是错误的,但不是你有 2 种形式。你打电话给2?一个接一个?
  • 您应该通过发布您的解决方案作为答案来解决您的问题,而不是通过编辑原始问题。这样你就可以接受你的答案,结束问题。
  • @ConspicuousCompiler 谢谢,我没有意识到这是一个选项。我自己已经回答了这个问题。如果没有更好的答案,我会在 2 天内接受。

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


【解决方案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;
                        }
            }
}

【讨论】:

    猜你喜欢
    • 2015-09-24
    • 2011-08-13
    • 1970-01-01
    • 2016-02-03
    • 2016-06-17
    • 1970-01-01
    • 2013-12-16
    • 2013-11-20
    • 2016-07-20
    相关资源
    最近更新 更多