#php #session #cakephp
#php #сеанс #cakephp
Вопрос:
Я новичок в Cakephp, и у меня большая проблема с сессиями…
Что именно происходит
Я начинаю инициализировать сеанс с помощью ajax, вызывая php-файл (контроллер)
это URL из ajax-> url: http ://domain.com/things/view/0
Я попробовал также без ajax, вызвав этот URL: http ://domain.com/things/view/1
В обоих случаях сеанс инициализируется. Ниже приведен контроллер, который я использую для инициализации сеанса
class ThingsController extends AppController {
var $name = 'Things';
var $components = array('Session');
var $helpers = array('Html', 'Javascript', 'Ajax');
var $uses = null;
function index() {
// preload dynamic data
$this->set('data1', 'content will update here');
$this->set('data2', 'here too');
$this->render('neat');
}
function view($id, $idd) {
if ($idd == 0) {
$this->Session->write('language', 'ro');
} else {
$this->Session->write('language', 'en');
}
if (is_numeric($id)) {
if ($id == 0) {
$this->Session->write('language', 'ro');
} else {
$this->Session->write('language', 'en');
}
}
$this->render('neat');
} //view()
} //ThingsController
Как вы можете видеть if SESSION['language'] == 0 is ro else is en
Используемое правило рутирования является:
Router::connect('/things/:id/*', array('controller' => 'things', 'action' => 'view',
'things'), array('pass' => 'id'));
Но работает и без этого правила 🙂
Теперь на странице о работе сеанса: http: //domain.com/despre-noi
Я использовал этот рутер:
Router::connect('/despre-noi/*', array('controller' => 'about', 'action' => 'display', 'about'));
И этот контроллер
function display() {
if (isset($_SESSION["language"])) {
$language = $_SESSION["language"];
$this->Session->write('language', $_SESSION["language"]);
} else {
$this->Session->write('language', 'ro');
$language = "ro";
}
include('views/pages/'.$language.'.ctp');
$this->layout = 'default';
$this->About->id = 1;
$this->set('post1', $this - > About - > read());
}
Но на странице партнеров: http: //domain.com/parteneri
Где я использовал этот рутер:
Router::connect('/parteneri/*', array('controller' => 'partner', 'action' => 'display', 'partner'));
и следующий контроллер:
function display() {
if (isset($_SESSION["language"])) {
$language = $_SESSION["language"];
$this->Session->write('language', $_SESSION["language"]);
} else {
$this->Session->write('language', 'ro');
$language = "ro";
}
include('views/pages/'.$language.'.ctp');
$this->layout = 'default';
$this->set('posts', $this - > Partner - > find('all'));
}
это не работает..
Эти две страницы очень похожи, с той разницей, что на странице партнера, которую я использовал $this->set('posts', $this->Partner->find('all'));
, а затем в view с помощью foreach()
я перечисляю элементы, а на странице about я читаю строку
$this->About->id = 1;
$this->set('post1', $this->About->read());
Может быть, это проблема … две функции read () vs find () .. или это просто совпадение?
Заранее спасибо
Ответ №1:
Сначала убедитесь, что у вас есть:
Configure::write('Session.save', 'php');
в вашем app/config/core.php
файле. Глава о сеансах в книге по CakePHP приводится несколько хороших примеров того, как настраивать и использовать компонент сеанса.
Кроме того, если вы собираетесь использовать сеансы (т. е. Session
компонент), вам лучше поместить:
var $components = array('Session');
В вашем AppController
. Таким образом, этот компонент будет доступен каждому контроллеру.
Во-вторых, если вы используете класс Session CakePHP для записи данных сеанса, то вам не следует обращаться к этим данным напрямую (т. Е. путем вызова $_SESSION['language']
). Это плохая практика, поскольку, если вы когда-нибудь решите использовать 'database'
в качестве хранилища сеансов или если CakePHP решит, что данные сеанса должны быть зашифрованы, тогда ваш код сломается, и вы понятия не будете, почему.
Короче говоря, пожалуйста, используйте $this->Session->read('language')
в своем коде (а также, взгляните на вышеупомянутую главу о сеансах, она также дает некоторую хорошую информацию.
Кроме того, поскольку вы хотите достичь интернационализации, после исправления ваших контроллеров в соответствии с вставками в моих комментариях вам обязательно нужно взглянуть на простой способ локализации, прочитав раздел интернационализации CakePHP. Есть способ упростить работу и отделить логику представления от содержимого презентации в ваших представлениях — но это материал для другого вопроса 😉
Комментарии:
1. Спасибо за ответ. В core.php У меня есть Configure::write(‘Session.save’, ‘my_session’); и я создаю файл my_sessions и помещаю в него все, как в примере с книгами. Вначале я сохраняю это на php, как вы сказали, это не так. В любом случае, я также попытался вызвать, как вы мне посоветовали, и все еще ничего… Сеансы действуют так, как будто я нахожусь в другом домене, и, конечно, он ничего об этом не знает.. У меня также есть этот linex в core.php : Configure::write(‘Безопасность. уровень’, ‘низкий’); Configure::write(‘Session.checkAgent’, false);
2. Я думал, проблема в маршрутизаторе, и я меняю следующий маршрутизатор Router:: connect(‘/parteneri /*’, array(‘controller’ => ‘partner’, ‘action’ => ‘display’, ‘партнер’)); чтобы загрузить страницу about, для этого я меняю маршрутизатор на Router :: connect(‘/ parteneri / *’, array(‘controller’ => ‘about’, ‘action’ => ‘display’, ‘about’)); и это работает нормально, загружает страницу about с корректно инициализированным сеансом. Итак, единственная проблема должна быть в контроллере партнера (оба контроллера — partner и about — находятся в теле вопроса) … но в чем ошибка
3. Я также хочу упомянуть, что это сеанс вывода в about controller: print_r($ _SESSION); он выводит массив ( [Config] => Array ( [UserAgent] => bacc67458f6a4db196762e81c0d9c341 [time] => 1303984020 [timeout] => 10 ) [language] => ru ), но если я выводю его в контроллере-партнере, он выводит Array ( ). Таким образом, он забывает все об этом сеансе…: ( Это все, что я могу сказать о своей проблеме. Спасибо
4. небольшой вопрос, просто чтобы убедиться: есть ли у вас var
$components = array('Session');
в вашемPartnerController
классе?5. Я обновил ответ, указав, как всегда использовать
Session
компонент (объявляя использование вAppController
)