跳转到内容

会话


概览

在 PHP 中,会话用于在请求之间持久化数据。这使开发人员能够构建更好的应用程序并提升用户体验。会话的常见用途之一是保持用户是否已登录的状态。Phalcon\Session\Manager是一种通过 Phalcon 处理会话的对象导向方法。与原始会话或访问$_SESSION超全局:

  • 您可以轻松地在同一域名下的不同应用之间隔离会话数据
  • 拦截您的应用程序中设置/获取会话数据的位置
  • 根据应用程序的需求更改会话适配器

管理器

Phalcon\Session\Manager是一个允许您在应用程序中操作会话的组件。这个管理器接受一个适配器,该适配器定义了数据如何与特定存储进行通信。

注意

PHP 使用术语handler来表示负责存储和检索数据的组件。在Phalcon\Session\Manager我们使用术语adapter。因此,为了在您的会话中设置处理程序对于Phalcon\Session\Manager您需要调用setAdapter()。其功能是相同的。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session->setAdapter($files);

首先,我们需要创建一个适配器对象。该对象可以是 Phalcon 分发的适配器之一(请参见下方),也可以是一个实现了SessionHandlerInterface的对象。一旦我们实例化新的Phalcon\Session\Manager对象并传入适配器后,您就可以开始处理会话。

构造函数

public function __construct(array $options = [])
构造函数接受与会话相关的选项数组。您可以使用uniqueId作为键和您选择的 ID 字符串来为您的会话设置唯一 ID。这使您可以在必要时创建多个具有各自唯一 ID 的此类对象。尽管此参数是可选的,但建议始终设置它。这样做有助于避免潜在的会话泄漏。

启动

为了处理会话,您需要启动它。start()执行此任务。通常,当组件注册或在应用程序的工作流程顶部时会调用此方法。start()返回一个布尔值,指示成功或失败。

注意

  • 如果会话已经启动,调用将返回true.
  • 如果任何头部已被发送,则返回false
  • 如果未设置适配器,将会抛出异常
  • 它将返回session_start()
<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session->setAdapter($files);

$session->start();

销毁

的结果destroy()来销毁会话。通常,这发生在用户注销时。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session
    ->setAdapter($files)
    ->start();

// ....

$session->destroy();

是否存在

要检查您的会话是否已启动,可以使用exists()

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

var_dump(
    $session->exists()
);
// `false`

$session
    ->setAdapter($files)
    ->start();

var_dump(
    $session->exists()
);
// `true`

重新生成ID

Phalcon\Session\Manager支持重新生成会话 ID。这允许您用一个新的 ID 替换当前会话 ID,同时保留当前会话信息不变。为此,您可以调用regenerateId()。该方法还接受一个bool参数,如果true将指示组件删除旧的会话文件。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

$session->regenerateId();

获取

你可以使用get()以字符串参数的形式传递特定元素以检索存储在会话中的内容。该组件还支持魔术 getter,因此您可以将其作为管理器的属性检索。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

echo $session->get('userId');
echo $session->userId;

是否存在

你可以使用has()检查特定元素是否存储在您的会话中。该组件还支持魔术__isset,允许您使用 PHP 的isset()方法,如果您想要的话。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

echo $session->has('userId');
var_dump(
    isset($session->userId)
);

ID

您还可以设置会话 ID。会话 ID 设置在一个 HTTP Cookie 中。您可以通过调用setId(). getId()用于检索会话 ID。

注意

您需要在此前调用此方法start()才能使 ID 生效

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session
    ->setAdapter($files)
    ->setId('phalcon-id')
    ->start();

echo $session->getId(); // 'phalcon-id'

名称

每个会话可以有一个名称。会话名称设置在一个 HTTP Cookie 中。如果不设置,将使用session.name php.ini设置。您可以通过调用setName(). getName()用于检索会话名称。

注意

您需要在此前调用此方法start()才能使名称生效

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session
    ->setAdapter($files)
    ->setName('phalcon-app')
    ->start();

echo $session->getName(); // 'phalcon-app'

选项

您可以通过使用setOptions()来为管理器设置选项。该方法接受一个数组,在其中您可以设置会话的uniqueId。要获取选项,可以调用getOptions(),它将返回存储在管理器中的选项数组。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager('id-1');
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);
$session
    ->setAdapter($files)
    ->start();

$session->setOptions(
    [
        'uniqueId' => 'id-2'
    ]   
);

在上面的例子中,setOptions()被调用了一个新的uniqueId,数据将使用id-2存储,并且在此之前的任何存储的内容都不可访问,直到您将键改回id-1.

设置

你可以使用set()以在您的会话中存储内容。该方法接受一个string作为元素名称和要存储的值。该组件还支持魔术 setter,因此您可以将其作为管理器的属性设置。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

$session->set('userId', 12345);
$session->userId = 12345;

移除

要删除会话中存储的元素,您需要调用remove()并传递元素名称。该组件还支持魔术__unset,因此您可以使用 PHP 的unset()方法,如果您想要的话。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

$session->remove('userId');
unset($session->userId);

适配器

Libmemcached

Phalcon\Session\Adapter\Libmemcached使用Phalcon\Storage\Adapter\Libmemcached内部存储 Memcached 数据。为了使用此适配器,您需要 Memcached 设置和一个Phalcon\Storage\AdapterFactory对象以内部创建适配器。

Memcached 的可用选项为:

名称 描述
client 客户端设置
servers 服务器数据数组

The servers选项是一个包含以下选项的数组:

名称 描述
host 主机
port 端口
weight 服务器的权重
<?php

use Phalcon\Session\Adapter\Libmemcached;
use Phalcon\Session\Manager;
use Phalcon\Storage\AdapterFactory;
use Phalcon\Storage\SerializerFactory;

$options = [
    'client'  => [],
    'servers' => [
        [
            'host'   => '127.0.0.1',
            'port'   => 11211,
            'weight' => 0,
        ],
    ],
];

$session           = new Manager();
$serializerFactory = new SerializerFactory();
$factory           = new AdapterFactory($serializerFactory);
$libmemcached      = new Libmemcached($factory, $options);

$session
    ->setAdapter($libmemcached)
    ->start();

无操作

Phalcon\Session\Adapter\Noop是一个“空”或者null适配器。它可以用于测试、同事之间的玩笑,或任何不需要调用会话的目的。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Noop;

$session = new Manager();
$session
    ->setAdapter(new Noop())
    ->start();

Redis

Phalcon\Session\Adapter\Redis使用Phalcon\Storage\Adapter\Redis内部存储 Redis 数据。为了使用此适配器,您需要 Redis 设置和一个Phalcon\Storage\AdapterFactory对象以内部创建适配器。

Redis 的可用选项为:

名称 描述
host 主机
port 端口
index 索引
persistent 是否持久化连接
auth 认证参数
socket 套接字连接
<?php

use Phalcon\Session\Adapter\Redis;
use Phalcon\Session\Manager;
use Phalcon\Storage\AdapterFactory;
use Phalcon\Storage\SerializerFactory;

$options = [
    'host'  => '127.0.0.1',
    'port'  => 6379,
    'index' => '1',
];

$session           = new Manager();
$serializerFactory = new SerializerFactory();
$factory           = new AdapterFactory($serializerFactory);
$redis             = new Redis($factory, $options);

$session
    ->setAdapter($redis)
    ->start();

这个适配器是最常见的一种,将会话文件存储在文件系统中。你需要创建一个Phalcon\Session\Adapter\Stream适配器,并使用savePath在选项中定义的路径。该路径需要对Web服务器可写,否则你的会话将无法正常工作。

<?php

use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$session = new Manager();
$files = new Stream(
    [
        'savePath' => '/tmp',
    ]
);

$session
    ->setAdapter($files)
    ->start();

自定义

这些适配器实现了PHP的SessionHandlerInterface。因此,你可以通过扩展此接口来创建任何你需要的适配器。你还可以使用实现此接口的任何适配器,并将其设置为Phalcon\Session\Manager。在[Phalcon Incubator][incubator]中还有更多适用于此组件的适配器可用。

<?php

namespace MyApp\Session\Adapter;

use SessionHandlerInterface;

class Custom extends SessionHandlerInterface
{
    public function close() -> bool;

    public function destroy($sessionId) -> bool;

    public function gc(int $maxlifetime) -> bool;

    public function read($sessionId) -> string;

    public function open($savePath, $sessionName) -> bool;

    public function write($sessionId, $data) -> bool;
}

异常

在Session组件中抛出的任何异常都将为Phalcon\Session\Exception类型。如果任何会话操作未能正确完成,则会抛出此异常。你可以使用这些异常来选择性地捕获仅从此组件抛出的异常。

<?php

use Phalcon\Session\Exception;
use Phalcon\Session\Manager;
use Phalcon\Mvc\Controller;

/**
 * @property Manager $session
 */
class IndexController extends Controller
{
    public function index()
    {
        try {
            $this->session->set('key', 'value');
        } catch (Exception $ex) {
            echo $ex->getMessage();
        }
    }
}

Bag

Phalcon\Session\Bag是一个帮助将会话数据分离到不同组中的组件namespaces。这样你可以为应用程序创建会话变量的组。在Bag中设置数据会自动将它们存储在会话中:

<?php

use Phalcon\Di\Di;
use Phalcon\Session\Bag as SessionBag;
use Phalcon\Session\Manager as SessionManager;
use Phalcon\Session\Adapter\Stream as SessionAdapter;

$container = new Di();
$adapter = new SessionAdapter();
$session = new SessionManager();
$session->setAdapter($adapter);
$user      = new SessionBag($session, 'user');

$user->setDI($container);

$user->name     = 'Dark Helmet';
$user->password = 12345;

依赖注入

如果您使用Phalcon\Di\FactoryDefault容器中可以注册你的会话管理器。以下是服务注册以及访问它的示例:

<?php

use Phalcon\Di\Di;
use Phalcon\Session\Manager;
use Phalcon\Session\Adapter\Stream;

$container = new Di();

$container->set(
    'session',
    function () {
        $session = new Manager();
        $files = new Stream(
            [
                'savePath' => '/tmp',
            ]
        );

        $session
            ->setAdapter($files)
            ->start();

        return $session;
    }
);

注册管理器后,你可以从控制器、视图或任何其他继承自Phalcon\Di\Injectable的组件中访问你的会话,如下所示:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Session\Manager;

/**
 * @property Manager $session
 */
class InvoicesController extends Controller
{
    public function indexAction()
    {
        // Set a session variable
        $this->session->set('user-name', 'Dark Helmet');
    }
}

持久化数据

你还可以注入Phalcon\Session\Bag组件。这样做可以帮助你在每个类中隔离变量而不污染会话。该组件会自动使用persistent属性名称进行注册。在$this->persist中设置的任何内容仅在每个类本身中可用,而如果在会话管理器中设置了数据,则在整个应用程序中都可用。

在控制器中:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Session\Bag;
use Phalcon\Session\Manager;

/**
 * @property Bag     $persistent
 * @property Manager $session
 */
class InvoicesController extends Controller
{
    public function indexAction()
    {
        // Set a session variable
        $this->persistent->name = 'Dark Helmet';
        $this->session->name    = 'Princess Vespa';
    }

    public function echoAction()
    {
        // Set a session variable
        echo $this->persistent->name; // 'Dark Helmet';
        echo $this->session->name;    // 'Princess Vespa';
    }
}

在组件中:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Session\Bag;
use Phalcon\Session\Manager;

/**
 * @property Bag     $persistent
 * @property Manager $session
 */
class InvoicesController extends Controller
{
    public function indexAction()
    {
        // Set a session variable
        $this->persistent->name = 'President Skroob';
    }

    public function echoAction()
    {
        // Set a session variable
        echo $this->persistent->name; // 'President Skroob';
        echo $this->session->name;    // 'Princess Vespa';
    }
}
无噪 Logo
无噪文档
25 年 6 月翻译
文档源↗