CakePHP:动作运行两次,没有充分的理由

时间:2020-03-05 18:53:42  来源:igfitidea点击:

我的蛋糕(cake_1.2.0.7296-rc2)有一个奇怪的问题。
在某些情况下,即使仅发出一个请求,我的start()操作也会运行两次。

触发因素似乎是:
加载一个像这样的对象:$ this-> Questionnaire-> read(null,$ questionnaire_id);
访问$ this-data

如果我禁用了start()操作对loadAvertisement()的调用,则不会发生这种情况。
如果我禁用了loadAdvertisement()中的两个调用:

$questionnaire = $this->Questionnaire->read(null, $questionnaire_id);
$question = $this->Questionnaire->Question->read(null, $question_id);

...那么也不会发生。

为什么?

参见下面的代码,控制器为" questionnaires_controller"。

function checkValidQuestionnaire($id)
{
    $this->layout = 'questionnaire_frontend_layout';

    if (!$id)
    {
        $id = $this->Session->read('Questionnaire.id');        
    }

    if ($id) 
    {
        $this->data = $this->Questionnaire->read(null, $id);

        //echo "from ".$questionnaire['Questionnaire']['validFrom']." ".date("y.m.d");
        //echo " - to ".$questionnaire['Questionnaire']['validTo']." ".date("y.m.d");

        if ($this->data['Questionnaire']['isPublished'] != 1 
            //|| $this->data['Questionnaire']['validTo'] < date("y.m.d")
            //|| $this->data['Questionnaire']['validTo'] < date("y.m.d")
            )
        {
            $id = 0;
            $this->flash(__('Ungültiges Quiz. Weiter zum Archiv...', true), array('action'=>'archive'));
        }
    }
    else
    {
        $this->flash(__('Invalid Questionnaire', true), array('action'=>'intro'));
    }

    return $id;
}

function start($id = null) {
    $this->log("start");

    $id = $this->checkValidQuestionnaire($id);

    //$questionnaire = $this->Questionnaire->read(null, $id);
    $this->set('questionnaire', $this->data);

    // reset flow-controlling session vars
    $this->Session->write('Questionnaire',array('id' => $id));
    $this->Session->write('Questionnaire'.$id.'currQuestion', null);
    $this->Session->write('Questionnaire'.$id.'lastAnsweredQuestion', null);
    $this->Session->write('Questionnaire'.$id.'correctAnswersNum', null);

    $this->loadAdvertisement($id, 0);

    $this->Session->write('Questionnaire'.$id.'previewMode', $this->params['named']['preview_mode']);

    if (!$this->Session->read('Questionnaire'.$id.'previewMode'))
    {
        $questionnaire['Questionnaire']['participiantStartCount']++;
        $this->Questionnaire->save($questionnaire);
    }        

}

function loadAdvertisement($questionnaire_id, $question_id)
{

    //$questionnaire = array();
    $questionnaire = $this->Questionnaire->read(null, $questionnaire_id);

    //$question = array();
    $question = $this->Questionnaire->Question->read(null, $question_id);

    if (isset($question['Question']['advertisement_id']) && $question['Question']['advertisement_id'] > 0)
    {
        $this->set('advertisement', $this->Questionnaire->Question->Advertisement->read(null, $question['Question']['advertisement_id']));
    }
    else if (isset($questionnaire['Questionnaire']['advertisement_id']) && $questionnaire['Questionnaire']['advertisement_id'] > 0)
    {
        $this->set('advertisement', $this->Questionnaire->Question->Advertisement->read(null, $questionnaire['Questionnaire']['advertisement_id']));
    }

}

我真的不明白这一点...它不认为是这种方式。
任何帮助将不胜感激! :)

问候,
斯图

解决方案

回答

我们可能想尝试使用debug_print_backtrace()函数找出其来源。 (http://nl.php.net/manual/en/function.debug-print-backtrace.php

回答

检查布局中是否存在不存在的链接,例如,指向favicon.ico的链接配置错误将导致控制器动作再次被触发。确保favicon.ico指向Webroot而不是本地目录,否则将为/controller/action/favicon.ico而不是/favicon.ico生成请求,从而触发操作。

图片,样式表和javascript包含也可能发生这种情况。

为了反检查$ id是一个int,然后在继续进行任何功能之前检查以确保$ id作为数据库的主键存在。

回答

遇到相同的问题,并且某些操作随机运行2-3次。我找到了两个原因:

  • Firefox添加组件Yslow被设置为从其首选项自动加载,从而导致在使用F5时重新加载页面(而不是从浏览器的地址栏中加载页面并按Enter)。
  • 我在$ html-> link()的选项中有错误的CSS样式声明;在某些情况下,它将最终变成background-image:url('');,这也导致重新运行。设置链接到背景图像的样式:无;当没有可用的图像时,对我来说是固定的。

希望这可以帮助。我知道这是一篇很旧的文章,但是由于在搜索此问题时在Google中的排名很高,因此我认为它仍然可以帮助其他人。

祝你好运

耶罗恩·登·哈恩(Jeroen den Haan)

回答

上周我遇到了这样的问题。

两种可能的原因

  • 路由错误(请检查路由配置)
  • AppController错误。我将很多东西添加到AppController中,尤其是添加到beforeFilter()和beforeRender()上,因此我们可能也想检查一下。

还有一件事,我们在会话中的哪里设置Questioneer.id?也许那是问题所在?

回答

对我来说,这是一个JS问题。

使用jQuery的wrap函数来在包装的内容中重新执行JS!