CakePHP: Action runs twice, for no good reason

2019-03-16 17:37发布

I have a strange problem with my cake (cake_1.2.0.7296-rc2). My start()-action runs twice, under certain circumstances, even though only one request is made.

The triggers seem to be : - loading an object like: $this->Questionnaire->read(null, $questionnaire_id); - accessing $this-data

If I disable the call to loadAvertisement() from the start()-action, this does not happen. If I disable the two calls inside loadAdvertisement():

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

... then it doesn't happen either.

Why?

See my code below, the Controller is "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']));
    }

}

I really don't understand this... it don't think it's meant to be this way. Any help would be greatly appreciated! :)

Regards, Stu

9条回答
趁早两清
2楼-- · 2019-03-16 17:54

For me it was a JS issue.

Take care of wrap function with jQuery that re-execute JS in wrapped content!

查看更多
The star\"
3楼-- · 2019-03-16 17:55

Check your layout for non-existent links, for example a misconfigured link to favicon.ico will cause the controller action to be triggered for a second time. Make sure favicon.ico points towards the webroot rather than the local directory, or else requests will be generated for /controller/action/favicon.ico rather than /favicon.ico - and thus trigger your action.

This can also happen with images, stylesheets and javascript includes.

To counter check the $id is an int, then check to ensure $id exists as a primary key in the database before progressing on to any functionality.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-03-16 17:58

I had a problem like this last week.

Two possible reasons

  • Faulty routes (DO check your routes configuration)
  • Faulty AppController. I add loads of stuff into AppController, especially to beforeFilter() and beforeRender() so you might want to check those out also.

One more thing, are where are you setting the Questioneer.id in your Session? Perhaps that's the problem?

查看更多
时光不老,我们不散
5楼-- · 2019-03-16 17:59

Yes, it occurs when there is a broken link in the web page. Each browser deals with it variously (Firefox calls it 2x). I tested it, there is no difference in CakePHP v1.3 and v2.2.1. To find out who the culprit is, add this line to the code, and then open the second generated file in you www folder:

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: First I blame jQuery for it. But in the end it was forgotten image for AJAX loading in 3rd part script.

查看更多
戒情不戒烟
6楼-- · 2019-03-16 18:00

I had the same problem in chrome, I disabled my 'HTML Validator' add on. Which was loading the page twice

查看更多
Explosion°爆炸
7楼-- · 2019-03-16 18:00

If you miss <something>, for example a View, Cake will trigger a missing <something> error and it will try to render its Error View. Therefore, AppController will be called twice. If you resolve the missing issue, AppController is called once.

查看更多
登录 后发表回答