We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

On-Demand session and session name

Currently i am trying a varnish+phalconphp setup and the best option would be to get rid of the session for non-authenticated users.

For this i will need to start the session only if:

  • the user has the cookie with the session name set (eg; $_COOKIE['sname']
  • the user is on the Auth Controller

What is the most appropriate way to do this?

So far i've seen that it's best to go with extending the \Phalcon\Session\Adapter .

Thanks.



2.6k
Accepted
answer
edited Mar '14

I managed to do it like this (see the "startOnDemand" and "set"):

<?php 
/**
 * Configure the session, but to start only if needed
 */
$di->set('session', function() {

  $memcache = new \Zero\Session\Adapter\Memcache(array(
      'host'          => '127.0.0.1',     // mandatory
      'post'          => 11211,           // optional (standard: 11211)
      'lifetime'      => 8600,            // optional (standard: 8600)
      'prefix'        => 'zero',         // optional (standard: [empty_string]), means memcache key is zero_31231jkfsdfdsfds3
      'persistent'    => false            // optional (standard: false)
    ));
  $memcache->startOnDemand();
  return $memcache;
}, true);

<?php
/**
 * Project Zero
 * User: Marian Craciun
 * Date: 1/14/14 8:10 AM
 */

namespace Zero\Session\Adapter;
use Zero\Context\Zero;

/**
 * Memcache session adapter for Phalcon framework
 *
 * @category    Phalcon
 * @package     Phalcon_Session_Adapter_Memcache
 */
class Memcache extends \Phalcon\Session\Adapter implements \Phalcon\Session\AdapterInterface
{
  /**
   * Default option for memcache port
   *
   * @var integer
   */
  const DEFAULT_OPTION_PORT = 11211;

  /**
   * Default option for session lifetime
   *
   * @var integer
   */
  const DEFAULT_OPTION_LIFETIME = 8600;

  /**
   * Default option for persistent session
   *
   * @var boolean
   */
  const DEFAULT_OPTION_PERSISTENT = false;

  /**
   * Default option for prefix of sessionId's
   *
   * @var string
   */
  const DEFAULT_OPTION_PREFIX = '';

  /**
   * Contains the memcache instance
   *
   * @var \Phalcon\Cache\Backend\Memcache
   */
  protected $memcacheInstance = null;

  /**
   * Class constructor.
   *
   * @param  null|array                $options
   * @throws \Phalcon\Session\Exception
   */
  public function __construct($options = null)
  {
    if (is_array($options)) {
      if (!isset($options["host"])) {
        throw new \Phalcon\Session\Exception("No session host given in options");
      }

      if (!isset($options["port"])) {
        $options["port"] = self::DEFAULT_OPTION_PORT;
      }

      if (!isset($options["lifetime"])) {
        $options["lifetime"] = self::DEFAULT_OPTION_LIFETIME;
      }

      if (!isset($options["persistent"])) {
        $options["persistent"] = self::DEFAULT_OPTION_PERSISTENT;
      }

      if (!isset($options["prefix"])) {
        $options["prefix"] = self::DEFAULT_OPTION_PREFIX;
      }
    } else {
      throw new \Phalcon\Session\Exception("No configuration given");
    }

    parent::__construct($options);
  }

  public function startOnDemand(){
    if(Zero::cookies()->has(session_name())) {
      $this->start();
    }
  }

  public function set($index, $value){
    if($this->_started === false) {
      $this->start();
    }
    return parent::set($index, $value);
  }

  /**
   * {@inheritdoc}
   *
   * @return boolean
   */
  public function open()
  {

    return true;
  }

  /**
   * {@inheritdoc}
   *
   * @return boolean
   */
  public function close()
  {
    return true;
  }

  /**
   * {@inheritdoc}
   *
   * @param  string $sessionId
   * @return mixed
   */
  public function read($sessionId)
  {
    return $this->getMemcacheInstance()->get(
      $this->getSessionId($sessionId),
      $this->getOption('lifetime')
    );
  }

  /**
   * {@inheritdoc}
   *
   * @param string $sessionId
   * @param string $data
   */
  public function write($sessionId, $data)
  {
    $this->getMemcacheInstance()->save(
      $this->getSessionId($sessionId),
      $data,
      $this->getOption('lifetime')
    );
  }

  /**
   * {@inheritdoc}
   *
   * @return boolean
   */
  public function destroy()
  {
    return $this->getMemcacheInstance()->delete($this->getSessionId($this->getId()));
  }

  /**
   * {@inheritdoc}
   */
  public function gc()
  {
  }

  /**
   * {@inheritdoc}
   *
   * @param  string $key
   * @return mixed
   */
  public function getOption($key)
  {
    if (isset($this->_options[$key])) {
      return $this->_options[$key];
    }

    return null;
  }

  /**
   * Returns the memcache instance.
   *
   * @return \Phalcon\Cache\Backend\Memcache
   */
  protected function getMemcacheInstance()
  {

    if ($this->memcacheInstance === null) {
      $this->memcacheInstance = new \Phalcon\Cache\Backend\Memcache(
        new \Phalcon\Cache\Frontend\Data(array("lifetime" => $this->getOption("lifetime"))),
        array(
          'host'       => $this->getOption('host'),
          'port'       => $this->getOption('port'),
          'persistent' => $this->getOption('persistent')
        )
      );
    }

    return $this->memcacheInstance;
  }

  /**
   * Returns the sessionId with prefix
   *
   * @param  string $sessionId
   * @return string
   */
  protected function getSessionId($sessionId)
  {
    return (strlen($this->getOption('prefix')) > 0)
      ? $this->getOption('prefix') . '_' . $sessionId
      : $sessionId;
  }
}