• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 位置: php 中文手册 -> php 内置函数

    php 会话函数session

    基本用法

    通过为每个独立用户分配唯一的会话 ID,可以实现针对不同用户分别存储数据的功能。会话通常被用来在多个页面请求之间保存及共享信息。一般来说,会话 ID 通过 cookie 的方式发送到浏览器,并且在服务器端也是通过会话 ID 来取回会话中的数据。如果请求中不包含会话 ID 信息,那么 PHP 就会创建一个新的会话,并为新创建的会话分配新的 ID。

    会话的工作流程很简单。当开始一个会话时,PHP 会尝试从请求中查找会话 ID (通常通过会话 cookie),如果请求中不包含会话 ID 信息,PHP 就会创建一个新的会话。会话开始之后,PHP 就会将会话中的数据设置到$_SESSION 变量中。当 PHP 停止的时候,它会自动读取$_SESSION中的内容,并将其进行序列化,然后发送给会话保存管理器来进行保存。

    默认情况下,PHP 使用内置的文件会话保存管理器(files)来完成会话的保存。也可以通过配置项 session.save_handler 来修改所要采用的会话保存管理器。对于文件会话保存管理器,会将会话数据保存到配置项 session.save_path 所指定的位置。

    可以通过调用函数session_start()来手动开始一个会话。如果配置项 session.auto_start 设置为1,那么请求开始的时候,会话会自动开始。

    PHP 脚本执行完毕之后,会话会自动关闭。同时,也可以通过调用函数session_write_close()来手动关闭会话。

    在$_SESSION 中注册变量。

    <?php
    session_start();
    if (!isset($_SESSION['count'])) {
      $_SESSION['count'] = 0;
    } else {
      $_SESSION['count']++;
    }
    ?>
    

    $_SESSION中反注册变量。

    <?php
    session_start();
    unset($_SESSION['count']);
    ?>
    

    Caution
    千万不要使用unset($_SESSION)来复位超级变量$_SESSION,因为这样会导致无法继续在$_SESSION中注册会话变量。

    Warning
    由于无法将一个引用恢复到另外一个变量,所以不可以将引用保存到会话变量中。

    Warning
    如果会话中存在和全局变量同名的变量,那么 register_globals 会导致全局变量被会话变量覆盖。更多信息请参考注册全局变量。

    Note:

    • 无论是通过调用函数 session_start()手动开启会话,还是使用配置项 session.auto_start 自动开启会话,对于基于文件的会话数据保存(PHP 的默认行为)而言,在会话开始的时候都会给会话数据文件加锁,直到 PHP 脚本执行完毕或者显式调用 session_write_close()来保存会话数据。在此期间,其他脚本不可以访问同一个会话数据文件。
    • 对于大量使用 Ajax 或者并发请求的网站而言,这可能是一个严重的问题。解决这个问题最简单的做法是如果修改了会话中的变量,那么应该尽快调用 session_write_close()来保存会话数据并释放文件锁。还有一种选择就是使用支持并发操作的会话保存管理器来替代文件会话保存管理器。

    传送会话ID

    有两种方式用来传送会话 ID:CookiesURL参数

    会话模块支持这两种方式。 Cookie 方式相对好一些,但是用户可能在浏览器中关闭 Cookie,所以第二种方案就是把会话 ID 直接并入到 URL 中,以保证会话 ID 的传送。

    无需开发人员干预,PHP 就可以自动处理 URL 传送会话 ID 的场景。如果启用了 session.use_trans_sid 选项, PHP 将会自动在相对 URI 中包含会话 ID。

    Note:
    arg_separator.output在php.ini配置指令允许你自定义会话 ID 参数分隔符。可以设定为&来保持和XHTML的一致性。

    会话开始之后,可以使用 SID 常量。如果客户端未提供会话 cookie,该常量的展开形式为 session_name=session_id,反之,该常量为空字符串。因此,可以直接在 URL 中包含此常量的展开字符串而无需考虑会话 ID 的实际传送方式。

    下例演示了如何在会话中注册变量以及如何使用 SID 常量正确的链接到另一页面。某单一用户的点击数

    <?php
    session_start();
    if (empty($_SESSION['count'])) {
       $_SESSION['count'] = 1;
    } else {
       $_SESSION['count']++;
    }
    ?>
    <p>
    Hello visitor, you have seen this page <?php echo $_SESSION['count']; ?> times.
    </p>
    <p>
    To continue, <a href="nextpage.php?<?php echo htmlspecialchars(SID); ?>">click here

    可以使用 htmlspecialchars()来打印 SID 常量的展开字符串以避免 XSS 相关的攻击。

    如果使用--enable-trans-sid 参数编译的 PHP,上例中打印 SID 常量部分就可以省略。

    Note:
    非相对 URL 将被视为指向外部站点的链接,从安全角度考虑,外站的链接 URL 中将不包含 SID 常量,以避免将 SID 泄露到外部服务器的风险。

    自定义会话管理器

    如果需要在数据库中或者以其他方式存储会话数据,需要使用session_set_save_handler()函数来创建一系列用户级存储函数。 PHP 5.4.0 之后,你可以使用 SessionHandlerInterface 类或者通过继承 SessionHandler 类来扩展内置的管理器,从而达到自定义会话保存机制的目的。

    函数session_set_save_handler()的参数即为在会话生命周期内要调用的一组回调函数: open, read, write 以及 close。还有一些回调函数被用来完成垃圾清理:destroy 用来删除会话, gc 用来进行周期性的垃圾收集。

    因此,会话保存管理器对于 PHP 而言是必需的。默认情况下会使用内置的文件会话保存管理器。可以通过session_set_save_handler()函数来设置自定义会话保存管理器。一些 PHP 扩展也提供了内置的会话管理器,例如:sqlite, memcache 以及 memcached,可以通过配置项 session.save_handler 来使用它们。

    会话开始的时候,PHP 会调用 open 管理器,然后再调用 read 回调函数来读取内容,该回调函数返回已经经过编码的字符串。然后 PHP 会将这个字符串解码,并且产生一个数组对象,然后保存至$_SESSION 超级全局变量。

    当 PHP 关闭的时候(或者调用了 session_write_close()之后), PHP 会对$_SESSION 中的数据进行编码,然后和会话 ID 一起传送给 write 回调函数。 write 回调函数调用完毕之后,PHP 内部将调用 close 回调函数。

    销毁会话时,PHP 会调用 destroy 回调函数。

    根据会话生命周期时间的设置,PHP 会不时地调用 gc 回调函数。该函数会从持久化存储中删除超时的会话数据。超时是指会话最后一次访问时间距离当前时间超过了$lifetime 所指定的值。

    运行时配置

    这些函数的行为受 php.ini 中的设置影响。

    会话配置选项
    名字默认可修改范围更新日志
    session.save_path""PHP_INI_ALL
    session.name"PHPSESSID"PHP_INI_ALL
    session.save_handler"files"PHP_INI_ALL
    session.auto_start"0"PHP_INI_PERDIR
    session.gc_probability"1"PHP_INI_ALL
    session.gc_divisor"100"PHP_INI_ALL
    session.gc_maxlifetime"1440"PHP_INI_ALL
    session.serialize_handler"php"PHP_INI_ALL
    session.cookie_lifetime"0"PHP_INI_ALL
    session.cookie_path"/"PHP_INI_ALL
    session.cookie_domain""PHP_INI_ALL
    session.cookie_secure""PHP_INI_ALL
    session.cookie_httponly""PHP_INI_ALL自 PHP 5.2.0 起有效
    session.cookie_samesite""PHP_INI_ALL自 PHP 7.3.0 起有效
    session.use_strict_mode"0"PHP_INI_ALL自 PHP 5.5.2 起有效
    session.use_cookies"1"PHP_INI_ALL
    session.use_only_cookies"1"PHP_INI_ALL
    session.referer_check""PHP_INI_ALL
    session.cache_limiter"nocache"PHP_INI_ALL
    session.cache_expire"180"PHP_INI_ALL
    session.use_trans_sid"0"PHP_INI_ALL
    session.trans_sid_tags"a=href,area=href,frame=src,form="PHP_INI_ALL自 PHP 7.1.0 起有效。
    session.trans_sid_hosts$_SERVER['HTTP_http://127.0.0.1/lanmper/public']PHP_INI_ALL自 PHP 7.1.0 起有效。
    session.sid_length"32"PHP_INI_ALL自 PHP 7.1.0 起有效。
    session.sid_bits_per_character"4"PHP_INI_ALL自 PHP 7.1.0 起有效。
    session.upload_progress.enabled"1"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.upload_progress.cleanup"1"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.upload_progress.prefix"upload_progress_"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.upload_progress.name"PHP_SESSION_UPLOAD_PROGRESS"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.upload_progress.freq"1%"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.upload_progress.min_freq"1"PHP_INI_PERDIR自 PHP 5.4.0 起有效。
    session.lazy_write"1"PHP_INI_ALL自 PHP 7.0.0 起有效。
    url_rewriter.tags"a=href,area=href,frame=src,form="PHP_INI_ALL自 PHP 7.1.0 起,session 功能不再使用此选项。
    session.hash_function"0"PHP_INI_ALL自 PHP 7.1.0 起移除。
    session.hash_bits_per_character"4"PHP_INI_ALL自 PHP 7.1.0 起移除。
    session.entropy_file""PHP_INI_ALL自 PHP 7.1.0 起移除。
    session.entropy_length"0"PHP_INI_ALL自 PHP 7.1.0 起移除。
    session.bug_compat_42"1"PHP_INI_ALL自 PHP 5.4.0 起移除。
    session.bug_compat_warn"1"PHP_INI_ALL自 PHP 5.4.0 起移除。

    会话管理系统支持许多配置选项,可以在自己的 php.ini 文件中设定。这里只是个简短的概览。

      • session.save_handler (string)session.save_handler 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files。Note that individual extensions may register their own save_handlers; registered handlers can be obtained on a per-installation basis by referring to phpinfo().参见 session_set_save_handler()。
      • session.save_path (string)session.save_path 定义了传递给存储处理器的参数。如果选择了默认的 files 文件处理器,则此值是创建文件的路径。默认为/tmp。参见 session_save_path()。
        此指令还有一个可选的 N 参数来决定会话文件分布的目录深度。例如,设定为'5;/tmp'将使创建的会话文件和路径类似于/tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If。要使用 N 参数,必须在使用前先创建好这些目录。在 ext/session 目录下有个小的 shell 脚本名叫 mod_files.sh,windows 版本是 mod_files.bat 可以用来做这件事。此外注意如果使用了 N 参数并且大于 0,那么将不会执行自动垃圾回收,更多信息见 php.ini。另外如果用了 N 参数,要确保将 session.save_path 的值用双引号"quotes"括起来,因为分隔符分号(;)在 php.ini 中也是注释符号。
        文件储存模块默认使用 mode 600 创建文件。通过修改可选参数 MODE 来改变这种默认行为: N;MODE;/path ,其中 MODE 是 mode 的八进制表示。 MODE 设置不影响进程的掩码(umask)。
        Warning
        如果将此设定为一个全局可读的目录,例如/tmp(默认值),服务器上的其他用户有可能通过该目录的文件列表破解会话。

        Caution
        使用以上描述的可选目录层级参数 N 时请注意,对于绝大多数站点,大于1或者2的值会不太合适——因为这需要创建大量的目录:例如,值设置为 3 需要在文件系统上创建 64^3 个目录,将浪费很多空间和 inode。
        仅仅在绝对肯定站点足够大时,才可以设置 N 大于2。

        Note:
        在 PHP 4.3.6 之前,Windows 用户必须修改此选项以使用 PHP 的会话函数。必须指定一个合法路径,例如:c:/temp。
      • session.name (string)session.name 指定会话名以用做 cookie 的名字。只能由字母数字组成,默认为 PHPSESSID。参见 session_name()。
      • session.auto_start (boolean)session.auto_start 指定会话模块是否在请求开始时自动启动一个会话。默认为 0(不启动)。
      • session.serialize_handler (string)session.serialize_handler 定义用来序列化/解序列化的处理器名字。当前支持 PHP 序列化格式(名为 php_serialize)、 PHP PHP 内部格式(名为 php 及 php_binary)和 WDDX (名为 wddx)。如果 PHP 编译时加入了 WDDX 支持,则只能用 WDDX。自 PHP 5.5.4 起可以使用 php_serialize。 php_serialize 在内部简单地直接使用 serialize/unserialize 函数,并且不会有 php 和 php_binary 所具有的限制。使用较旧的序列化处理器导致$_SESSION 的索引既不能是数字也不能包含特殊字符(| and !)。使用 php_serialize 避免脚本退出时,数字及特殊字符索引导致出错。默认使用 php。
      • session.gc_probability (integer)session.gc_probability 与 session.gc_divisor 合起来用来管理 gc(garbage collection 垃圾回收)进程启动的概率。默认为 1。详见 session.gc_divisor。
      • session.gc_divisor (integer)session.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor 计算得来。例如 1/100 意味着在每个请求中有 1%的概率启动 gc 进程。session.gc_divisor 默认为 100。
      • session.gc_maxlifetime (integer)session.gc_maxlifetime 指定过了多少秒之后数据就会被视为“垃圾”并被清除。垃圾搜集可能会在 session 启动的时候开始(取决于session.gc_probability 和 session.gc_divisor)。
        Note:
        如果不同的脚本具有不同的 session.gc_maxlifetime 数值但是共享了同一个地方存储会话数据,则具有最小数值的脚本会清理数据。此情况下,与 session.save_path 一起使用本指令。
      • session.referer_check (string)session.referer_check 包含有用来检查每个 HTTP Referer 的子串。如果客户端发送了 Referer 信息但是在其中并未找到该子串,则嵌入的会话 ID 会被标记为无效。默认为空字符串。
      • session.entropy_file (string)session.entropy_file 给出了一个到外部资源(文件)的路径,该资源将在会话 ID 创建进程中被用作附加的熵值资源。例如在许多 Unix 系统下都可以用/dev/random 或/dev/urandom。在 Windows 上自 PHP 5.3.3 起加入了此功能。设置 session.entropy_length 为非零的值将使 PHP 使用 Windows Random API 作为熵值源。Note:自 PHP 5.4.0 起,默认情况下, session.entropy_file 在/dev/urandom 或/dev/arandom 可用的时候使用它们。在 PHP 5.3.0 中此指令默认留空。
      • session.entropy_length (integer)session.entropy_length 指定了从上面的文件中读取的字节数。默认为 0(禁用)。
      • session.use_strict_mode (boolean)session.use_strict_mode specifies whether the module will use strict session id mode. If this mode is enabled, the module does not accept uninitialized session ID. If uninitialized session ID is sent from browser, new session ID is sent to browser. Applications are protected from session fixation via session adoption with strict mode. Defaults to 0 (disabled).
      • session.use_cookies (boolean)session.use_cookies 指定是否在客户端用 cookie 来存放会话 ID。默认为 1(启用)。
      • session.use_only_cookies (boolean)session.use_only_cookies 指定是否在客户端仅仅使用 cookie 来存放会话 ID。。启用此设定可以防止有关通过 URL 传递会话 ID 的攻击。自PHP 5.3.0开始,默认值为1(启用)
      • session.cookie_lifetime (integer)session.cookie_lifetime 以秒数指定了发送到浏览器的 cookie 的生命周期。值为 0 表示“直到关闭浏览器”。默认为 0。参见 session_get_cookie_params()和 session_set_cookie_params()。
        Note:
        The expiration timestamp is set relative to the server time, which is not necessarily the same as the time in the client's browser.
      • session.cookie_path (string)session.cookie_path 指定了要设定会话 cookie 的路径。默认为/。参见 session_get_cookie_params()和 session_set_cookie_params()。
      • session.cookie_domain (string)session.cookie_domain 指定了要设定会话 cookie 的域名。默认为无,表示根据 cookie 规范产生 cookie 的主机名。参见 session_get_cookie_params()和 session_set_cookie_params()。
      • session.cookie_secure (boolean)session.cookie_secure 指定是否仅通过安全连接发送 cookie。默认为 off。此设定是 PHP 4.0.4 添加的。参见 session_get_cookie_params()和 session_set_cookie_params()。
      • session.cookie_httponly (boolean)Marks the cookie as accessible only through the HTTP protocol. This means that the cookie won't be accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity theft through XSS attacks (although it is not supported by all browsers).
      • session.cookie_samesite (string)Allows servers to assert that a cookie ought not to be sent along with cross-site requests. This assertion allows user agents to mitigate the risk of cross-origin information leakage, and provides some protection against cross-site request forgery attacks. Note that this is not supported by all browsers. An empty value means that no SameSite cookie attribute will be set. Lax and Strict mean that the cookie will not be sent cross-domain for POST requests; Lax will sent the cookie for cross-domain GET requests, while Strict will not.
      • session.cache_limiter (string)session.cache_limiter 指定会话页面所使用的缓冲控制方法(none/nocache/private/private_no_expire/public)。默认为 nocache。参见 session_cache_limiter()。
      • session.cache_expire (integer)session.cache_expire 以分钟数指定缓冲的会话页面的存活期,此设定对 nocache 缓冲控制方法无效。默认为 180。参见 session_cache_expire()。
      • session.use_trans_sid (boolean)session.use_trans_sid 指定是否启用透明 SID 支持。默认为 0(禁用)。
        Note:
        基于 URL 的会话管理比基于 cookie 的会话管理有更多安全风险。例如用户有可能通过 email 将一个包含有效的会话 ID 的 URL 发给他的朋友,或者用户总是有可能在收藏夹中存有一个包含会话 ID 的 URL 来以同样的会话 ID 去访问站点。自 PHP 7.1.0 开始,透明 SID 开始使用完整的 URL 绝对路径,例如 https://php.net/。在此之前 PHP 只会使用相对路径。使用 session.trans_sid_hosts 定义重写的目标 host。
      • session.trans_sid_tags (string)session.trans_sid_tags specifies which HTML tags are rewritten to include session id when transparent sid support is enabled. Defaults to a=href,area=href,frame=src,input=src,form= form is special tag. is added as form variable.
        Note:
        Before PHP 7.1.0, url_rewriter.tags was used for this purpose. Since PHP 7.1.0, fieldset is no longer considered as special tag.
      • session.trans_sid_hosts (string)session.trans_sid_hosts specifies which hosts are rewritten to include session id when transparent sid support is enabled. Defaults to $_SERVER['HTTP_http://127.0.0.1/lanmper/public'] Multiple hosts can be specified by ",", no space is allowed between hosts. e.g. php.net,wiki.php.net,bugs.php.net
      • session.bug_compat_42 (boolean)PHP 4.2.3 以及更低版本有一个未公开的特性/错误,它允许用户在 register_globals 被禁用的情况下在全局范围内初始化一个会话变量。PHP 4.3.0 及更高版本会在使用此特性时并且启用了 session.bug_compat_warn 时发出警告。此特性/错误可以通过关闭此选项而禁用。
        Note:
        PHP 5.4.0 中已经移除。
      • session.bug_compat_warn (boolean)PHP 4.2.3 以及更低版本有一个未公开的特性/错误,它允许用户在 register_globals 被禁用的情况下在全局范围内初始化一个会话变量。PHP 4.3.0 及更高版本会在使用此特性时并且同时启用了 session.bug_compat_42 和 session.bug_compat_warn 时发出警告。
        Note:
        PHP 5.4.0 中已经移除。
      • session.sid_length (integer)session.sid_length allows you to specify the length of session ID string. Session ID length can be between 22 to 256. The default is 32. If you need compatibility you may specify 32, 40, etc. Longer session ID is harder to guess. At least 32 chars are recommended.
        TipCompatibility
        Note:
        Use 32 instead of session.hash_function=0 (MD5) and session.hash_bits_per_character=4, session.hash_function=1 (SHA1) and session.hash_bits_per_character=6. Use 26 instead of session.hash_function=0 (MD5) and session.hash_bits_per_character=5. Use 22 instead of session.hash_function=0 (MD5) and session.hash_bits_per_character=6. You must configure INI values to have at least 128 bits in session ID. Do not forget to set an appropriate value for session.sid_bits_per_character, otherwise you will have weaker session ID.
        Note:
        This setting is introduced in PHP 7.1.0.
      • session.sid_bits_per_character (integer)session.sid_per_character allows you to specify the number of bits in encoded session ID character. The possible values are '4'(0-9, a-f),'5'(0-9, a-v), and '6'(0-9, a-z, A-Z,"-",","). The default is 4. The more bits results in stronger session ID. 5 is recommended value for most environments.
        Note:
        This setting is introduced in PHP 7.1.0.url_rewriter.tags (string)url_rewriter.tags 指定在使用透明 SID 支持时哪些 HTML 标记会被修改以加入会话 ID。默认为 a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=。
        Note:
        如果要符合 XHTML,去掉 form 项并在表单字段前后加上标记。
      • session.hash_function (mixed)session.hash_function 允许用户指定生成会话 ID 的散列算法。'0'表示 MD5(128 位),'1'表示 SHA-1(160 位)。Since PHP 5.3.0 it is also possible to specify any of the algorithms provided by the hash extension (if it is available), like sha512 or whirlpool. A complete list of supported algorithms can be obtained with the hash_algos() function.
        Note:
        这是 PHP 5 引进的。
      • session.hash_bits_per_character (integer)session.hash_bits_per_character 允许用户定义将二进制散列数据转换为可读的格式时每个字符存放多少个比特。可能值为'4'(0-9,a-f),'5'(0-9,a-v),以及'6'(0-9,a-z,A-Z,"-",",")。
        Note:
        这是 PHP 5 引进的。
      • session.upload_progress.enabled (boolean)Enables upload progress tracking, populating the $_SESSION variable. Defaults to 1, enabled.
      • session.upload_progress.cleanup (boolean)Cleanup the progress information as soon as all POST data has been read (i.e. upload completed). Defaults to 1, enabled.
        Note:
        It is highly recommended to keep this feature enabled.
      • session.upload_progress.prefix (string)A prefix used for the upload progress key in the $_SESSION. This key will be concatenated with the value of $_POST[ini_get("session.upload_progress.name")] to provide a unique index. Defaults to "upload_progress_".
      • session.upload_progress.name (string)The name of the key to be used in $_SESSION storing the progress information. See also session.upload_progress.prefix. If $_POST[ini_get("session.upload_progress.name")] is not passed or available, upload progressing will not be recorded. Defaults to "PHP_SESSION_UPLOAD_PROGRESS".
      • session.upload_progress.freq (mixed)Defines how often the upload progress information should be updated. This can be defined in bytes (i.e."update progress information after every 100 bytes"), or in percentages (i.e."update progress information after receiving every 1% of the whole filesize"). Defaults to "1%".
      • session.upload_progress.min_freq (integer)The minimum delay between updates, in seconds. Defaults to "1"(one second).
      • session.lazy_write (boolean)session.lazy_write, when set to 1, means that session data is only rewritten if it changes. Defaults to 1, enabled.register_globals 配置选项影响到会话变量是怎样存储和恢复的。
        Upload progress will not be registered unless session.upload_progress.enabled is enabled, and the $_POST[ini_get("session.upload_progress.name")] variable is set. See Session Upload Progress for mor details on this functionality.