I set a session in a class from libraries. Then I tried to get the value of this session in another class from libraries. The value is empty.
I took a look in CodeIgniter Library to find out what the problem could be and at the some similar topics from StackOverflow but I don't see anything wrong from my end. maybe I am missing something. Please help.
// IN THIS CLASS I SET THE SESSION 'fr_phone'
class Form_submit_fr {
var $CI;
protected $fr_id;
protected $fr_data = array();
public function __construct() {
$this->CI =& get_instance();
if (strpos($this->CI->uri->segment(1),'frid') !== false){
$this->fr_id = (int)str_replace('frid','',$this->CI->uri->segment(1));
$this->fr_data = $this->get_fr_data();
// add the phone to session
if (isset($this->fr_data->city_toll) && $this->fr_data->city_toll != '') {
$fr_phone = $this->fr_data->city_toll;
} else {
$fr_phone = $this->fr_data->city_phone;
}
// here the session is set
$this->CI->session->set_userdata('fr_phone', $fr_phone);
//the result is correct
echo $this->CI->session->userdata('fr_phone') . ' - fr_phone<br>';
}
}
....
}
// IN THIS CLASS I NEED TO GET THIS SESSION 'fr_phone'
class P_details {
protected $page_link;
protected $fr_data;
var $CI;
public function __construct(){
$this->CI =& get_instance();
if ($this->CI->uri->segment(2) == false && $this->CI->uri->segment(3) == false) {
$this->page_link = $this->uri->segment(1)."/";
} else if ($this->CI->uri->segment(1) != false && $this->CI->uri->segment(2) != false && $this->CI->uri->segment(3) == false) {
$this->page_link = $this->CI->uri->segment(1)."/".$this->CI->uri->segment(2)."/";
} else if ($this->CI->uri->segment(1) != false && $this->CI->uri->segment(2) != false && $this->CI->uri->segment(3) != false) {
$this->page_link = $this->CI->uri->segment(1)."/".$this->CI->uri->segment(2)."/";
$this->fr_data = $this->get_fr_data($this->CI->uri->segment(3));
}
$this->CI->load->model('getDetails_model');
}
public function get_p_id($type = '') {
$details_array = $this->CI->getDetails_model->all_details($this->page_link);
if (empty($details_array)) {
return FALSE;
}
else {
$data['fr_phone'] = '';
$data['detail'] = $details_array;
// get phone from session
// here the session is empty
echo $this->CI->session->userdata('fr_phone') . ' - fr_phone<br>';
if ($this->CI->session->userdata('fr_phone')) {
$data['fr_phone'] = $this->CI->session->userdata('fr_phone');
}
if ($this->fr_data != '') {
$data['fr_detail'] = $this->fr_data;
}
return $data;
}
}
...
}
this is my config file:
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;
this is my autoload file:
$autoload['libraries'] = array('database','session');
I have made the suggested changes in config file for $config['sess_save_path']. thanks a lot. I could see the files in the writable folder and the entries in database when I checked this way as well:
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 43200;
$config['sess_save_path'] = APPPATH.'writable';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
Also I used database for session:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 43200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
In both cases the session works if I define a session in Controller in constructor or index function. I can get session in View files and in other Classes but if I set a session under a condition for a specific link then this session is always empty when I want to get it in a class from libraries folder or in view files:
//in controller
if (strpos($this->uri->segment(1),'frid') !== false){
...
$fr_phone = '111-222-3333';
$this->session->set_userdata('fr_phone', $fr_phone);
echo $this->session->userdata('fr_phone') // works
}
When I call this session in a Class from libraries folder, the session is empty: above example for class P_details. And there is no way to get a session that is set in a Class from libraries folder and to get it in Another Class from libraries folder. It is very strange and I cannot get it. Also I tried to get session in a different controller and no success.
i had similar issue with one project. After long try i fix the issue the following way
1) in config.php
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'writable absolute path';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
and created the folder named "writable absolute path" in the root
Hopes this will help
It is very strange but I removed the session from autoload:
$autoload['libraries'] = array('database');
I added session_start(); in controllers and I set the session in a common way:
$_SESSION['fr_phone'] = $fr_phone;
Then I was able to get this value in any files. Is this a bug?
I tried without session_start() by adding $this->load->library('session'); and it did not work.
Can anyone find an answer to this issue?
I am using CodeIgniter 3.0.2
Related
I am working in codeigniter, i have some config variables in config.php file of codeigniter, but for welcome controller i want to changes its config variable, i am not able to get controller name in config file of codeigniter, i am using this function $controller = $this->router->fetch_class();, but it is not working can anyone please help me how can we get it ? I have below config variables, but i want to only enable it if controller name is not a welcome
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 900; //7200; 900
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 0; //
$config['sess_time_to_update'] = $config['sess_expiration'];
When my maintenance mode is on.
I would like to be able to still view the home page when maintenance mode is on.
But only if the member session role_id = 1
Currently does not let me view the home page at all even though my session role_id == 1 keeps redirecting to maintenance page
Question: How can I make sure can view home page if maintenance mode is active but if session role id == '1'
public function maintenance_mode() {
$maintenance_mode = $this->is_maintenance();
if ($maintenance_mode) {
if ($this->session->userdata('role_id') == '1') {
return true;
} else {
$route = $this->uri->segment(1) .'/'. $this->uri->segment(2);
$ignore = array('common/maintenance');
if (!in_array($route, $ignore)) {
redirect(base_url('common/maintenance'));
}
}
}
}
public function is_maintenance() {
$query = $this->db->where('item', 'maintenance_mode')->get('settings')->row('value');
return $query;
}
Solution
The code in my question was fine. I found the issue. it was creating the sessions twice one for www.example.co.nz and one for example.co.nz
I need to add cookie domain
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '.example.co.nz';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_sessions';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = APPPATH . 'cache/sessions/';
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = TRUE;
I am trying to use one session data for all of my subdomains.
I have created a subdomain in cpanel like this : *.mydomain.in
and my *.mydomain.in uses the same path as my mydomain.in example:
mydomain.in uses path on my server: /public_html/mydomain.in
*.mydomain.in uses path on my server: /public_html/mydomain.in
Now the problem is every time I visit the site it's creating a different session. For example:
I visit mydomain.in .... it creates a session.
I visit example.mydomain.in .... it creates a different session
I again visit mydomain.in ... it creates a different session.
my codeigniter config file:
$config['encryption_key'] = 'MY-SECRET-KEY-HERE';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 0;
$config['sess_expire_on_close'] = TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['cookie_prefix'] = "";
$config['cookie_domain'] = ".mydomain.in";
$config['cookie_path'] = "/";
$config['cookie_secure'] = FALSE;
Any help or suggestion would be a great help. Thanks in advance.
Here's how I solved the issue.
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 0;
$config['sess_expire_on_close'] = TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = FALSE;
$config['sess_time_to_update'] = 300000000;
$config['cookie_prefix'] = "etc_anything_";
$config['cookie_domain'] = ".mydomain.in";
$config['cookie_path'] = "/";
$config['cookie_secure'] = FALSE;
Mohamed Sufian's answer is largely correct, but note that as per the Session Docs, the cookie_prefix setting is ignored by the session driver. If you want to have an instance specific cookie name you will need to edit the sess_cookie_name configuration option.
For example:
$config['sess_cookie_name'] = 'my_prefix_ci_session';
$config['cookie_prefix'] = "my_prefix_"; // Only relevant for non-session cookies
$config['cookie_domain'] = ".example.com";
$config['cookie_path'] = "/";
I’m using PDO driver to access MySQL database. Everything is working OK on that part. My database.php looks like this:
$active_group = 'default';
$active_record = FALSE;
$db['default']['hostname'] = 'mysql:host=127.0.0.1:3386';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'mydatabase';
$db['default']['dbdriver'] = 'pdo';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
I don’t use Active Record..
The problem occurred when I auto-loaded session library and set it to use database. I created table in my database, and on first visit to site, a record gets inserted into session table. No problem there.
An error occurs on subsequent visits to the site. I’m getting following:
Fatal error: Call to undefined method CI_DB_pdo_driver::where() in P:\Git\TengWebsite\system\libraries\Session.php on line 201
set $active_record = TRUE;
$active_group = 'default';
$active_record = TRUE;
Note: that some CodeIgniter classes such as Sessions require Active Records be enabled to access certain functionality.
its clearly stated here CodeIgniter Doc
I am using Codeigniter 2.0.1 and Postgresql 8.1. My code uses transactions within try-catch blocks.
On a simple insert at times I get a "Fatal Error"
Fatal Error: Call to a member function row() on a non-object in
<...path...>/system/database/drivers/postgre/postgre_driver.php on
line 357
My Database Config is:
$db['default']['hostname'] = "localhost";
$db['default']['username'] = "***";
$db['default']['password'] = "***";
$db['default']['database'] = "***";
$db['default']['dbdriver'] = 'postgre';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = FALSE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
The lne of my Model code that is causing the error is "$id = $this->db->insert_id();".
I say so because the line that causes the error is within insert_id() method and it is being used only once in the model.
A code snapshot of the model is given below.
try {
// CODE TO FILL UP $data ARRAY
$this->DBquery("BEGIN");
$this->DBinsert('<TABLE NAME>', $data);
$id = $this->db->insert_id();
// SOME MORE CODE
}
catch(Exception $e) {
$this->DBquery("ROLLBACK");
//echo $e->getMessage();
return 0;
}
$this->DBquery("COMMIT");
return $id;
$this->DBquery and $this->DBinsert are custom methods made by me on a base model class which extends the CI_Model class. These methods function full well.
Below is the insert_id method in postgre_driver.php and line 357 is "$row = $query->row();"
function insert_id()
{
$v = $this->_version();
$v = $v['server'];
$table = func_num_args() > 0 ? func_get_arg(0) : NULL;
$column = func_num_args() > 1 ? func_get_arg(1) : NULL;
if ($table == NULL && $v >= '8.1')
{
$sql='SELECT LASTVAL() as ins_id';
}
elseif ($table != NULL && $column != NULL && $v >= '8.0')
{
$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
$query = $this->query($sql);
$row = $query->row();
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
}
elseif ($table != NULL)
{
// seq_name passed in table parameter
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
}
else
{
return pg_last_oid($this->result_id);
}
$query = $this->query($sql);
$row = $query->row(); // LINE 357
return $row->ins_id;
}
Its so more confusing because the problem is not always. It happens sometimes but with a good enough frequency to hamper work. The system is being used by about 8-10 users and so I guess concurrency should not be an issue.
Also, I am using pconnect and number of connections is unlimited.
This sounds like maybe some of your insert statements are failing. If something errors out inside of a transaction like this, it can invalidate the transaction. If you look in the log file, you may find entries like "current transaction is aborted, commands ignored until end of transaction." (What's happening is the $query variable in the insert_id function doesn't receive a valid query result value, so calling functions on it fails at that point)
The best way to handle this is probably to modify your custom DBinsert function to return a value indicating the success or failure of the insert operation. (You should just be able to return the value of whatever insert command you're running internally)
Then, you can do something like this:
$insert_ret_val = $this->DBinsert('<TABLE NAME>', $data);
if($insert_ret_val){
//insert success!
$id = $this->db->insert_id();
}else{
//handle failed insert here, rollback, whatever
}