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

时间:2008-09-15 15:21:28

标签: php cakephp action cakephp-1.2

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

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

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

中禁用了两个调用
$questionnaire = $this->Questionnaire->read(null, $questionnaire_id);
$question = $this->Questionnaire->Question->read(null, $question_id);

......然后它也不会发生。

为什么?

请参阅下面的代码,Controller是“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']));
    }

}

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

此致 斯图

9 个答案:

答案 0 :(得分:10)

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

图像,样式表和javascript包含也会发生这种情况。

要计数检查$ id是否为int,请检查以确保$ id作为数据库中的主键存在,然后再继续执行任何功能。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

有同样的问题,用一定的动作随机运行2-3次。我追查了两个原因:

  • Firefox插件Yslow设置为从其首选项自动加载,导致页面在使用F5时重新加载(不是从浏览器的地址栏加载页面并按Enter键时)。

  • 我在$ html-&gt; link()的选项中有一个错误的css样式声明;在某些情况下,它最终将作为background-image:url('');,这也导致重新运行。将链接的样式设置为background-image:none;当没有可用的图像时,为我修复了一些东西。

希望这会有所帮助。我知道这是一个相当古老的帖子,但是当它在搜索这个问题时谷歌出现相当高的时候,我认为它仍然可以通过发布来帮助其他人。

祝你好运

Jeroen den Haan

答案 4 :(得分:1)

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

两个可能的原因

  • 路线错误(请检查路线配置)
  • 有问题的AppController。我在AppController中添加了很多东西,尤其是对于beforeFilter()和beforeRender(),所以你可能也想检查一下。

还有一件事,你在会话中设置Questioneer.id在哪里?也许这就是问题?

答案 5 :(得分:1)

是的,当网页中的链接断开时会发生这种情况。每个浏览器都以不同方式处理它(Firefox称之为2x)。我测试过,CakePHP v1.3和v2.2.1没有区别。要找出罪魁祸首是谁,请将此行添加到代码中,然后在www文件夹中打开第二个生成的文件:

file_put_contents("log-" . date("Hms") . ".txt", $this->params['pass'] ); // CakePHP v1.3 
file_put_contents("log-" . date("Hms") . ".txt", $this->request['pass'] ); //CakePHP v2.2.1
PS:首先我责备jQuery。但最终在第3部分脚本中忘记了AJAX加载的图像。

答案 6 :(得分:0)

我在chrome中遇到了同样的问题,我禁用了我的'HTML Validator'添加。这是两次加载页面

答案 7 :(得分:0)

我遇到了类似的问题,问题似乎与端点上的大小写不敏感有关。  

即:
http://server/Questionnaires/loadAvertisement -vs-
http://server/questionnaires/loadavertisement

当调用正确的端点时,该方法会运行一次 - 其中较低的端口运行两次。这个问题偶尔发生在一个控制器上,但不会发生在另一个控制器上(基本上是相同的逻辑,没有其他组件等)。我无法确认,但相信浏览器的错误 - 不是CakePHP本身。

我的解决方法是确保每个端点链接都是正确的。为了更进一步,我在Route的配置中添加了常见的case-variants:

应用程序/配置/ routes.php文件

<?php
// other routes..
$instructions = ['controller'=>'Questionnaires','action'=>'loadAvertisement'];
Router::connect('/questionnaires/loadavertisement', $instructions);
Router::connect('/QUESTIONNARIES/LOADADVERTISEMENT', $instructions);
// ..etc

答案 8 :(得分:0)

如果您错过<something>,例如视图,蛋糕会触发错误的<something>错误,它会尝试呈现其Error View。因此,AppController将被调用两次。如果您解决了遗漏的问题,则会调用AppController一次。