-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathsession-set-save-handler.xml
370 lines (359 loc) · 14.3 KB
/
session-set-save-handler.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 184f3f7bd45643cb80f828d0bb001991ec3a5fad Maintainer: yuanyuqiang Status: ready -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="function.session-set-save-handler" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>session_set_save_handler</refname>
<refpurpose>设置用户自定义会话存储函数</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>bool</type><methodname>session_set_save_handler</methodname>
<methodparam><type>callable</type><parameter>open</parameter></methodparam>
<methodparam><type>callable</type><parameter>close</parameter></methodparam>
<methodparam><type>callable</type><parameter>read</parameter></methodparam>
<methodparam><type>callable</type><parameter>write</parameter></methodparam>
<methodparam><type>callable</type><parameter>destroy</parameter></methodparam>
<methodparam><type>callable</type><parameter>gc</parameter></methodparam>
<methodparam choice="opt"><type>callable</type><parameter>create_sid</parameter></methodparam>
<methodparam choice="opt"><type>callable</type><parameter>validate_sid</parameter></methodparam>
<methodparam choice="opt"><type>callable</type><parameter>update_timestamp</parameter></methodparam>
</methodsynopsis>
<para>
可以使用下面的方式来注册自定义会话存储函数:
</para>
<methodsynopsis>
<type>bool</type><methodname>session_set_save_handler</methodname>
<methodparam><type>object</type><parameter>sessionhandler</parameter></methodparam>
<methodparam choice="opt"><type>bool</type><parameter>register_shutdown</parameter><initializer>&true;</initializer></methodparam>
</methodsynopsis>
<para>
<function>session_set_save_handler</function> 设置用户自定义
会话存储函数。
如果想使用 PHP 内置的会话存储机制之外的方式,
可以使用本函数。
例如,可以自定义会话存储函数来将会话数据存储到数据库。
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
本函数有 2 种原型:
<variablelist>
<varlistentry>
<term><parameter>sessionhandler</parameter></term>
<listitem>
<para>
实现了
<interfacename>SessionHandlerInterface</interfacename>,
<interfacename>SessionIdInterface</interfacename>(可选) 和/或
<interfacename>SessionUpdateTimestampHandlerInterface</interfacename>
接口的对象,
例如 <classname>SessionHandler</classname>。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>register_shutdown</parameter></term>
<listitem>
<para>
将函数 <function>session_write_close</function> 注册为
<function>register_shutdown_function</function> 函数。
</para>
</listitem>
</varlistentry>
</variablelist>
或者
<variablelist>
<varlistentry>
<term><parameter>open(string $savePath, string $sessionName)</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>open</replaceable></methodname>
<methodparam><type>string</type><parameter>savePath</parameter></methodparam>
<methodparam><type>string</type><parameter>sessionName</parameter></methodparam>
</methodsynopsis>
</para>
<para>
open 回调函数类似于类的构造函数,
在会话打开的时候会被调用。
这是自动开始会话或者通过调用 <function>session_start</function> 手动开始会话
之后第一个被调用的回调函数。
此回调函数操作成功返回 &true;,反之返回 &false;。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>close</parameter></term>
<listitem>
<para>
close 回调函数类似于类的析构函数。
在 write 回调函数调用之后调用。
当调用 <function>session_write_close</function> 函数之后,也会调用 close 回调函数。
此回调函数操作成功返回 &true;,反之返回 &false;。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>read</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>string</type><methodname><replaceable>read</replaceable></methodname>
<methodparam><type>string</type><parameter>sessionId</parameter></methodparam>
</methodsynopsis>
</para>
<para>
如果会话中有数据,read 回调函数必须返回将会话数据编码(序列化)后的字符串。
如果会话中没有数据,read 回调函数返回空字符串。
</para>
<para>
在自动开始会话或者通过调用
<function>session_start</function> 函数手动开始会话之后,PHP 内部调用 read 回调函数来获取会话数据。
在调用 read 之前,PHP 会调用 open 回调函数。
</para>
<para>
read 回调返回的序列化之后的字符串格式必须与 <parameter>write</parameter> 回调函数保存数据时的格式完全一致。
PHP 会自动反序列化返回的字符串并填充 <varname>$_SESSION</varname> 超级全局变量。
虽然数据看起来和 <function>serialize</function> 函数很相似,
但是需要提醒的是,它们是不同的。
请参考: <link linkend="ini.session.serialize-handler">session.serialize_handler</link>。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>write</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>write</replaceable></methodname>
<methodparam><type>string</type><parameter>sessionId</parameter></methodparam>
<methodparam><type>string</type><parameter>data</parameter></methodparam>
</methodsynopsis>
</para>
<para>
在会话保存数据时会调用 <parameter>write</parameter> 回调函数。
此回调函数接收当前会话 ID 以及 <varname>$_SESSION</varname> 中数据序列化之后的字符串作为参数。
序列化会话数据的过程由 PHP 根据 <link linkend="ini.session.serialize-handler">session.serialize_handler</link> 设定值来完成。
</para>
<para>
序列化后的数据将和会话 ID 关联在一起进行保存。
当调用 <parameter>read</parameter> 回调函数获取数据时,所返回的数据必须要和
传入 <parameter>write</parameter> 回调函数的数据完全保持一致。
</para>
<para>
PHP 会在脚本执行完毕或调用 <function>session_write_close</function> 函数之后调用此回调函数。
注意,在调用完此回调函数之后,PHP 内部会调用 <parameter>close</parameter> 回调函数。
<note>
<para>
PHP 会在输出流写入完毕并且关闭之后
才调用 write 回调函数,
所以在 write 回调函数中的调试信息不会输出到浏览器中。
如果需要在 write 回调函数中使用调试输出,
建议将调试输出写入到文件。
</para>
</note>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>destroy</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>destroy</replaceable></methodname>
<methodparam><type>string</type><parameter>sessionId</parameter></methodparam>
</methodsynopsis>
</para>
<para>
当调用 <function>session_destroy</function> 函数,
或者调用 <function>session_regenerate_id</function> 函数并且设置 destroy 参数为 &true; 时,
会调用此回调函数。此回调函数操作成功返回 &true;,反之返回 &false;。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>gc</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>gc</replaceable></methodname>
<methodparam><type>int</type><parameter>lifetime</parameter></methodparam>
</methodsynopsis>
</para>
<para>
为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。
调用周期由 <link linkend="ini.session.gc-probability">session.gc_probability</link>
和 <link linkend="ini.session.gc-divisor">session.gc_divisor</link> 参数控制。
传入到此回调函数的 lifetime 参数由 <link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link> 设置。
此回调函数操作成功返回 &true;,反之返回 &false;。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>create_sid</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>string</type><methodname><replaceable>create_sid</replaceable></methodname>
<void/>
</methodsynopsis>
</para>
<para>
需要新的会话 ID 时,执行此回调函数。
它被调用时不会传入参数,其返回值应该是一个字符串格式的、有效的 session ID。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>validate_sid</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>validate_sid</replaceable></methodname>
<methodparam><type>string</type><parameter>key</parameter></methodparam>
</methodsynopsis>
</para>
<para>
开启 <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> 后,
当启动一个 session 时,提供了 session ID 后会执行此回调。
参数 <parameter>key</parameter> 是待验证的 session ID。
如果该 ID 的 session 已经存在,则为有效 session ID。
成功时返回值应当为 &true;,失败时为 &false;。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>update_timestamp</parameter></term>
<listitem>
<para>
实现了以下签名的 callable 回调:
<methodsynopsis>
<type>bool</type><methodname><replaceable>update_timestamp</replaceable></methodname>
<methodparam><type>string</type><parameter>key</parameter></methodparam>
<methodparam><type>string</type><parameter>val</parameter></methodparam>
</methodsynopsis>
</para>
<para>
更新 session 时执行此回调。
参数 <parameter>key</parameter> 是 session ID;参数 <parameter>val</parameter> 是 session 的数据。
成功时返回值应当为 &true;,失败时为 &false;。
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>
自定义会话处理程序:完整代码请参见 <classname>SessionHandlerInterface</classname>。
</title>
<para>
这里仅列出了调用方式,完整代码请参见 <classname>SessionHandlerInterface</classname>。
</para>
<para>
这里使用了 <function>session_set_save_handler</function> 函数的 OOP 原型
并且使用第二个参数来注册 shutdown 函数。
当将对象注册为会话保存处理程序时,建议使用这种方式。
</para>
<programlisting role="php">
<![CDATA[
<?php
class MySessionHandler implements SessionHandlerInterface
{
// 在这里实现接口
}
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
// 现在可以使用 $_SESSION 保存以及获取数据了
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
<warning>
<para>
在对象销毁之后才会调用
<parameter>write</parameter> 和 <parameter>close</parameter> 回调函数,
所以,在这两个回调函数中不可以使用对象,也不可以抛出异常。
如果在函数中抛出异常,PHP 既不会捕获它,也不会跟踪它,
这样会导致程序异常终止。
但是对象析构函数可以使用会话。
</para>
<para>
可以在析构函数中调用 <function>session_write_close</function>
函数来解决这个问题。
但是注册 shutdown 回调函数才是更加可靠的做法。
</para>
</warning>
<warning>
<para>
如果会话在脚本结束后关闭,对于某些 SAPI 而言,当前工作目录可能已经被改变。
可以调用 <function>session_write_close</function>
函数在脚本执行结束之前关闭会话。
</para>
</warning>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member>
<link linkend="ini.session.save-handler">session.save_handler</link>
配置指示
</member>
<member>
<link linkend="ini.session.serialize-handler">session.serialize_handler</link>
配置指示
</member>
<member><function>register_shutdown_function</function></member>
<member><function>session_register_shutdown</function></member>
<member>
完整的实现请参考
<link xlink:href="&url.session-save-handler;">save_handler.inc</link>。
</member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->