5

I'm setting multiple session variables in a PHP script that is external to Joomla.

The variables are set consecutively using the following code.

//Access Joomla
define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(__FILE__));
define( 'DS', DIRECTORY_SEPARATOR );
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
$app = JFactory::getApplication('site');
$app->initialise();

//Store values in Joomla Session
$session = JFactory::getSession();
$session->set('firstvalue', $firstvalue);
$session->set('secondvalue', $secondvalue);   
$session->set('thirdvalue', $thirdvalue);
$session->set('fourthvalue', $fourthvalue); 

In another script I then get the session variables

$session = JFactory::getSession();
$firstvalue = $session->get('firstvalue');
//etc etc

The problem I'm seeing is that the value for firstvalue occasionally goes missing. I'm not sure if this happens to the other variables yet. From what I've read, it's possible that Joomla is not locking the session. What I think that means is that Joomla tries to set firstvalue, but before it gets saved it is overwritten by another variable. Does this sound right?

If my understanding of the situation is right, I've come up with a few solutions. If you have some better ones I'd love to hear them :)

I could

  • store the variables in an array and set them in one go.
  • create different namespaces for each of the variables.

In summary,

I'd like to know if setting Joomla session variables consecutively in a script external to Joomla could cause some values to be lost. If that is unlikely, I'd appreciate suggestions as to what could be causing the data loss and suggestions on how to solve the problem.

  • 2
    when you do $session->set('firstvalue', $firstvalue), the firstvalue only will be saved in the end of the joomla cycle. If your external script is trying to access the variable before that, you have a problem – csbenjamin Jul 8 '14 at 13:09
  • @csbenjamin Thanks for the comment. I'm assuming that the other variables will also be set at the end of the cycle. Is that right? By Joomla cycle do you mean something like this ->docs.joomla.org/Application_execution_order Is there a way to determine when the Joomla cycle has finished? – TryHarder Jul 9 '14 at 13:36
2

I have had issues with this when the database is used as the session handler. From what I can gather, the session data isn't written to the database until the script has terminated. This means that if the second script starts running before the first finishes it would load the session data without the new values since it hasn't been written to the database yet.

I have had some luck with just switching the session handler to file instead of database and had this actually lock the file so that the second script wouldn't run until the first had finished and saved its value. This is probably because there isn't as good of a way to lock the individual table row as there is a file.

  • Thanks David. I've changed my code since posting this question, but I'm confident your answer would solve the problem. Instead of Joomla sessions, I'm using server side caching (think memcache or redis). I've found that it's much faster than trying to read and set via Joomla session. Again this is probably because I was using the database as the session handler. – TryHarder Aug 20 '14 at 6:38
1

OK, the problem is that we got to use the same session.

In order to do that. We had to call $session->getId() to get current seeeion_id then send it to the client side, when we create the session and save the data.

Then the client side should pass back the session_id when they want to retrieve back the session data, and we pass the seeeion_id as a one of the parameters of JFactory::getSession().

The JFactory::getSession() can take an array as its parameter. To specify the session_id we use id as the name. so the codes are

$options = array(
    "id" => $input_msg->session_id
);
$session = JFactory::getSession($options);
$firstvalue = $session->get('firstvalue');

where the $input_msg->session_id is the session_id you retrieve back from user's input.

Another important issue is that if we want to destroy() the session, right after we retrieve back the session by $session = JFactory::getSession($options). We got to activate the session by calling $session->start(), then calling $session->destroy() can be success, otherwise we'll got a fail message.

By the way, you can find your sessions on #__session table one record per session.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.