2015-05-01 7 views
1

Я получаю странное поведение, которое я не могу полностью объяснить. Рассмотрим этот контроллер код:Yii 1.1 сеанс иногда не сохраняет значение

public function actionCreate() 
{ 
    $order = new Order(); 

    $this->performAjaxValidation($order, null, 'order-form'); 

    if (isset($_POST['Order'])) { 
     $order->attributes = $_POST['Order']; 
     if ($order->save()) { 
      Yii::app()->session['order_id'] = $order->id; 
      $this->redirect('confirm'); 
     } 
    } 
    $this->render('create', array('order' => $order)); 
} 

public function actionConfirm() 
{ 
    $order_id = Yii::app()->session['order_id']; 
    if(!$order_id) { 
     throw new CHttpException(404, 'Order not found'); 
    } 
    $order = $this->loadModel($order_id); 
    $this->render('confirm', array('order' => $order)); 
} 

Итак, сначала я создаю заказ, а затем, если создание прошло успешно, есть перенаправление на страницу подтверждения. Идентификатор заказа сохраняется в сеансе, чтобы клиент мог видеть заказ, который они создали. Почему я не могу сделать перенаправление на страницу подтверждения ($ order_id)? Потому что 1. Заказ содержит данные, предоставленные пользователем, и он не может быть общедоступным, только пользователь создал этот заказ, который может просмотреть его на странице подтверждения, и 2. Там нет аутентификации, пользователям не требуется входить в систему.

Странно то, что большую часть времени он отлично работает, но иногда (1 раз из 5 минут) идентификатор заказа не сохраняется в сеансе. Если сеанс свежий, тогда он будет показывать 404. Если это не так, и вы создадите несколько заказов, он будет равномерно отображать предыдущие данные заказа (следующий порядок сохраняется в порядке).

Я бы предположил, что что-то не так с самим компонентом сеанса (я использую CDbHttpSession). Но все остальное (связанные с сессией) отлично работает на сайте (backend auth никогда не сбой, всегда появляются флеш-сообщения).

Любые идеи, где я должен смотреть?

+0

Попробуйте использовать 'Yii :: app() -> user-> setState ('order_id', $ order-> id);' вместо массива 'Yii :: app() -> session'. Информация [здесь] (http://www.yiiframework.com/doc/api/1.1/CBaseUserIdentity#setState-detail). –

+0

Хорошо, что также сохраняет информацию в сеансе, поэтому я не вижу разницы в этом случае. Но я все-таки пробовал, с тем же результатом. – Andrey

+0

Ну, 'Yii :: app() -> user-> setState' гарантирует, что вызывается' Yii :: app() -> user-> init(); ', который открывает сеанс. 'Yii :: app() -> session' не делает. –

ответ

1

Хорошо, теперь кажется очевидным. Причиной было классическое состояние сеанса: сеанс автоматического запуска, performAjaxValidation читает сеанс до того, как будет установлен order_id, а затем сохранит сеанс без order_id после того, как order_id установлен, но до вызова actionConfirm. Собственные сессии PHP блокируются, поэтому эта ситуация не будет, но сеансы db не будут.

Смежные вопросы