会话¶
概览¶
在 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对象并传入适配器后,您就可以开始处理会话。
构造函数¶
构造函数接受与会话相关的选项数组。您可以使用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';
}
}