We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

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;
  }
}