Session


Sessions - 图1

Overview

Sessions are used in PHP to persist data between requests. This enables developers to build better applications and increase the user experience. A very common usage of sessions is to keep whether a user is logged in or not. Phalcon\Session\Manager is an object oriented approach to handle sessions using Phalcon. There are several reasons to use this component instead of raw sessions or accessing the $_SESSION superglobal:

  • You can easily isolate session data across applications on the same domain
  • Intercept where session data is set/get in your application
  • Change the session adapter according to the application needs

Manager

Phalcon\Session\Manager is a component that allows you to manipulate sessions in your application. This manager accepts a an adapter which is the way the data will be communicated to a particular store.

PHP uses the term handler for the component that will be responsible for storing and retrieving the data. In Phalcon\Session\Manager we use the term adapter. So in order to set a handler in your session, for Phalcon\Session\Manager you need to call setAdapter(). The functionality is the same.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session->setAdapter($files);

First we need to create an adapter object. The object can be one of the adapters distributed with Phalcon (see below) but it can also be an object that implements SessionHandlerInterface. Once we instantiate the new Phalcon\Session\Manager object and pass the adapter in it. After that you can start working with the session.

Constructor

  1. public function __construct(array $options = [])

The constructor accepts an array of options that relate to the session. You can set a unique id for your session using uniqueId as a key and your chosen id string. This allows you to create more than one of these objects, each with its own unique id, if necessary. This parameter is optional, but it is advisable to set it always. Doing so will help you with potential session leaks.

Start

In order to work with the session, you need to start it. start() performs this task. Usually this call is made when the component is registered or at the very top of your application’s workflow. start() returns a boolean value indicating success or failure.

NOTE:

  • If the session has already started, the call will return true.
  • If any headers have been sent, it will return false
  • If the adapter is not set, it will throw an exception
  • It will return the result of session_start()
  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session->setAdapter($files);
  11. $session->start();

Destroy

Similarly, you can call destroy() to kill the session. Usually this happens when a user logs out.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. // ....
  14. $session->destroy();

Exists

To check if your session has started, you can use exists()

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. var_dump(
  11. $session->exists()
  12. );
  13. // `false`
  14. $session
  15. ->setAdapter($files)
  16. ->start();
  17. var_dump(
  18. $session->exists()
  19. );
  20. // `true`

Regenerate Id

Phalcon\Session\Manager supports regenerating the session id. This allows you to replace the current session id with a new one and keep the current session information intact. To achieve this you can call regenerateId(). The method also accepts a bool parameter, which if true will instruct the component to remove old session file.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. $session->regenerateId();

Get

You can use get() to retrieve the contents stored in the session for a particular element passed as a string parameter. The component also supports the magic getter so you can retrieve it as a property of the manager.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. echo $session->get('userId');
  14. echo $session->userId;

Has

You can use has() to check whether a particular element is stored in your session. The component also supports the magic __isset, allowing you to use PHP’s isset() method if you want.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. echo $session->has('userId');
  14. var_dump(
  15. isset($session->userId)
  16. );

Id

You can also set the session id. The session id is set in a HTTP cookie. You can set the name by calling setId(). getId() is used to retrieve the session id.

You need call this method before calling start() for the id to take effect

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->setId('phalcon-id')
  13. ->start();
  14. echo $session->getId(); // 'phalcon-id'

Name

Each session can have a name. The session name is set in a HTTP cookie. If this is not set, the session.name php.ini setting is used. You can set the name by calling setName(). getName() is used to retrieve the session name.

You need to call this method before calling start() for the name to take effect

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->setName('phalcon-app')
  13. ->start();
  14. echo $session->getName(); // 'phalcon-app'

Options

You can set options for the manager by using setOptions(). The method accepts an array and in it you can set the uniqueId for the session. To get the options you can call getOptions() which will return the array of options stored in the manager.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager('id-1');
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. $session->setOptions(
  14. [
  15. 'uniqueId' => 'id-2'
  16. ]
  17. );

In the above example, after setOptions() is called with a new uniqueId, data will be stored using id-2 now and anything stored before that will not be accessible until you change the key back to id-1.

Set

You can use set() to store contents in your session. The method accepts a string as the name of the element and the value to be stored.. The component also supports the magic setter so you can set it as a property of the manager.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. $session->set('userId', 12345);
  14. $session->userId = 12345;

Remove

To remove a stored element in the session, you need to call remove() with the name of the element. The component also supports the magic __unset so you can use PHP’s unset() method if you want.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();
  13. $session->remove('userId');
  14. unset($session->userId);

Adapters

Libmemcached

Phalcon\Session\Adapter\Libmemcached uses the Phalcon\Storage\Adapter\Libmemcached internally to store data in Memcached. In order to use this adapter you need the settings for Memcached and a Phalcon\Storage\AdapterFactory object in order for the adapter to be created internally.

The available options for Redis are:

  • client - client settings
  • servers - array of server data
    • host - the host
    • port - the port
    • weight - the weight for the server
  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Storage\AdapterFactory;
  4. use Phalcon\Session\Adapter\Libmemcached;
  5. $options = [
  6. 'client' => [],
  7. 'servers' => [
  8. [
  9. 'host' => '127.0.0.1',
  10. 'port' => 11211,
  11. 'weight' => 0,
  12. ],
  13. ],
  14. ];
  15. $session = new Manager();
  16. $factory = new AdapterFactory();
  17. $redis = new Libmemcached($factory, $options);
  18. $session
  19. ->setAdapter($redis)
  20. ->start();

Noop

Phalcon\Session\Adapter\Noop is an “empty” or null adapter. It can be used for testing, a joke for your colleages or any other purpose that no session needs to be invoked.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Noop;
  4. $session = new Manager();
  5. $session
  6. ->setAdapter(new Noop())
  7. ->start();

Redis

Phalcon\Session\Adapter\Redis uses the Phalcon\Storage\Adapter\Redis internally to store data in Redis. In order to use this adapter you need the settings for Redis and a Phalcon\Storage\AdapterFactory object in order for the adapter to be created internally.

The available options for Redis are:

  • host - the host
  • port - the port
  • index - the index
  • persistent - whether to persist connections or not
  • auth - authentication parameters
  • socket - socket connection
  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Storage\AdapterFactory;
  4. use Phalcon\Session\Adapter\Redis;
  5. $options = [
  6. 'host' => '127.0.0.1',
  7. 'port' => 6379,
  8. 'index' => '1',
  9. ];
  10. $session = new Manager();
  11. $factory = new AdapterFactory();
  12. $redis = new Redis($factory, $options);
  13. $session
  14. ->setAdapter($redis)
  15. ->start();

Stream

This adapter is the most common one, storing the session files on the file system. You need to create a Phalcon\Session\Adapter\Stream adapter with the savePath defined in the options. The path needs to be writeable by the web server, otherwise your sessions will not work.

  1. <?php
  2. use Phalcon\Session\Manager;
  3. use Phalcon\Session\Adapter\Stream;
  4. $session = new Manager();
  5. $files = new Stream(
  6. [
  7. 'savePath' => '/tmp',
  8. ]
  9. );
  10. $session
  11. ->setAdapter($files)
  12. ->start();

Custom

The adapters implement PHP’s SessionHandlerInterface. As a result you can create any adapter you need by extending this interface. You can also use any adapter that implements this interface and set the adapter to Phalcon\Session\Manager. There are more adapters available for this components in the Phalcon Incubator.

  1. <?php
  2. namespace MyApp\Session\Adapter;
  3. use SessionHandlerInterface;
  4. class Custom extends SessionHandlerInterface
  5. {
  6. /**
  7. * Close
  8. */
  9. public function close() -> bool;
  10. /**
  11. * Destroy
  12. */
  13. public function destroy($sessionId) -> bool;
  14. /**
  15. * Garbage Collector
  16. */
  17. public function gc($maxlifetime) -> bool;
  18. /**
  19. * Read
  20. */
  21. public function read($sessionId) -> string;
  22. /**
  23. * Open
  24. */
  25. public function open($savePath, $sessionName) -> bool;
  26. /**
  27. * Write
  28. */
  29. public function write($sessionId, $data) -> bool;
  30. }

Exceptions

Any exceptions thrown in the Session component will be of type Phalcon\Session\Exception. It is thrown any session operation is not completed correctly. You can use these exceptions to selectively catch exceptions thrown only from this component.

  1. <?php
  2. use Phalcon\Session\Exception;
  3. use Phalcon\Session\Manager;
  4. use Phalcon\Mvc\Controller;
  5. /**
  6. * @property Manager $session
  7. */
  8. class IndexController extends Controller
  9. {
  10. public function index()
  11. {
  12. try {
  13. $this->session->set('key', 'value');
  14. } catch (Exception $ex) {
  15. echo $ex->getMessage();
  16. }
  17. }
  18. }

Bag

Phalcon\Session\Bag is a component that helps separating session data into namespaces. This way you can create groups of session variables for your application. Setting data in the bag stores them automatically in the session:

  1. <?php
  2. use Phalcon\Di;
  3. use Phalcon\Session\Bag as SessionBag;
  4. $container = new Di();
  5. $user = new SessionBag('user');
  6. $user->setDI($container);
  7. $user->name = 'Dark Helmet';
  8. $user->password = 12345;

Dependency Injection

If you use the Phalcon\Di\FactoryDefault container you can register your session manager. An example of the registration of the service as well as accessing it is below:

  1. <?php
  2. use Phalcon\Di;
  3. use Phalcon\Session\Manager;
  4. use Phalcon\Session\Adapter\Stream;
  5. $container = new Di();
  6. $container->set(
  7. 'session',
  8. function () {
  9. $session = new Manager();
  10. $files = new Stream(
  11. [
  12. 'savePath' => '/tmp',
  13. ]
  14. );
  15. $session
  16. ->setAdapter($files)
  17. ->start();
  18. return $session;
  19. }
  20. );

After registering the manager you can access your session from controllers, views or any other components that extend Phalcon\Di\Injectable as follows:

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. use Phalcon\Session\Manager;
  4. /**
  5. * @property Manager $session
  6. */
  7. class InvoicesController extends Controller
  8. {
  9. public function indexAction()
  10. {
  11. // Set a session variable
  12. $this->session->set('user-name', 'Dark Helmet');
  13. }
  14. }

Persistent Data

You can also inject the Phalcon\Session\Bag component. Doing so will help you isolate variables for every class without polluting the session. The component is registered automatically using the persistent property name. Anything set in $this->persist will only be available in each class itself, whereas if data is set in the session manager will be available throughout the application.

In a controller:

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. use Phalcon\Session\Bag;
  4. use Phalcon\Session\Manager;
  5. /**
  6. * @property Bag $persistent
  7. * @property Manager $session
  8. */
  9. class InvoicesController extends Controller
  10. {
  11. public function indexAction()
  12. {
  13. // Set a session variable
  14. $this->persistent->name = 'Dark Helmet';
  15. $this->session->name = 'Princess Vespa';
  16. }
  17. public function echoAction()
  18. {
  19. // Set a session variable
  20. echo $this->persistent->name; // 'Dark Helmet';
  21. echo $this->session->name; // 'Princess Vespa';
  22. }
  23. }

In a component:

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. use Phalcon\Session\Bag;
  4. use Phalcon\Session\Manager;
  5. /**
  6. * @property Bag $persistent
  7. * @property Manager $session
  8. */
  9. class InvoicesController extends Controller
  10. {
  11. public function indexAction()
  12. {
  13. // Set a session variable
  14. $this->persistent->name = 'President Skroob';
  15. }
  16. public function echoAction()
  17. {
  18. // Set a session variable
  19. echo $this->persistent->name; // 'President Skroob';
  20. echo $this->session->name; // 'Princess Vespa';
  21. }
  22. }