使用include文件的PHP session_start

13

我从我的之前的问题中学到了很多关于会话开始的知识。现在我想知道当文件被包含在其他文件中时如何发生会话锁定。假设我有:

page.php

include('header.php');
...some html content....
include('sub_page.php');
...more html....

header.php:

session_start();
..save session vars...
..print web page header...

子页面.php

session_start();
...use session vars....
..print page content...
当我打开page.php时,是否会在header.php完成后立即解锁会话?还是整个page.php生命周期内都处于活动状态,因此sub_page的会话被阻塞?sub_page中的session_start是否必要?如果每次处理完会话数据后都使用session_write_close是否更好?(尽管这意味着每次想使用会话变量时都需要重新开始session_start)。

1
将所有这些答案综合起来,由于include仅检索文件并将其转储为page.php的一部分,因此第二个session_start不是有效语句,因此锁定不是问题。 - Andrea
5个回答

12
  1. 你应该只在一次会话中开始session。在你的例子中,只需要在page.php的第一行使用session_start()。
  2. 如果之前已经启动了会话,session_start()将生成E_NOTICE。你可以使用@session_start()来忽略它。
  3. 如果你在输出HTML代码后使用session_start(),它也会生成E_NOTICE。

我在头文件中使用了session_start,因为头文件被包含在所有页面中(page.php、page2.php等)。我关闭了e_notice,所以我没有注意到警告。 - Andrea
同意在头文件中使用session_start,因为您将在每个页面中使用header.php。编码时不应关闭e_notice,它有助于代码纠正。 - sonnb

10

我建议创建一个session.php文件,并将其包含在每个页面的第一行。这样,会话在一个文件中处理,以防需要更改验证或会话设置(并且不必担心您的问题)。


但是当一些子页面需要使用会话变量而另一些不需要时,会发生什么? - Andrea
@Andrea:我不确定我理解了。当您包含一个具有会话信息的 session.php 时,它将对其后包含的所有脚本可用。 - Evan Mulawski
当你说“处理会话”时,你是指“与$_SESSION变量交互”,包括从中设置和获取吗? - Andrea
如果存在一个会话,只要最先加载了 session.php,你就可以在 PHP 代码的任何地方访问(读写)$_SESSION - Evan Mulawski
我明白了。那么目前的header.php正在执行该功能。我可以理解将所有会话内容分离到其自己的文件中,然后由header包含它会很好。 - Andrea

10

由于上面的答案提到如果会话已经开始就会出现错误,所以我想指出你可以这样做:

if (!isset($_SESSION))
  {
    session_start();
  }

如果$_SESSION已经启动(设置),它将不会执行启动函数。
虽然没有什么比良好的文件和文件夹布局与良好的框架设置更好,即使只是一个简单的框架结构也分离了业务逻辑和表现层。
这种方式,您将拥有类似于带有初始化脚本的配置文件夹,或者至少在某个文件夹中具有包含在所有页面/脚本中的include文件。
然后,您只需在(根据您的设置)第一个include文件中或单独的include文件中使用session_start(),然后在需要在脚本的特定区域中使用该会话文件时包含该会话文件。
无论哪种方式,您都不需要在任何其他文件中调用它,因为根据您的设计结构,您知道它根本不需要。
如果没有始终被包含的文件,则至少使用isset()检查。

6
从PHP 4.3.3开始,如果在以前已经启动会话的情况下调用session_start()函数,则会产生E_NOTICE级别的错误。此外,第二个会话启动将被简单地忽略。

我关闭了 E_NOTICE,所以我没有看到这个警告。 - Andrea

1
只要您不访问或创建会话变量,就无需担心session_start()。只有在运行的脚本将创建会话变量或依赖于访问会话变量才真正需要担心session_start()。
如果file1未访问或创建其他脚本使用的变量,则不要调用它。如果由file1包含的file2正在创建或依赖于会话中的变量,则file2应调用session_start()。 file2将被包含在会话中,并且可以访问所有会话变量,但是file1将不能。
如果您在file1中调用session_start(),则file2将能够访问所有会话变量,就好像它调用了session_start()一样。
希望这更清楚地解释了情况。
James提供了一个很好的提示,即使用isset。这将防止尝试进行无意义的会话调用。
还要检查php.ini文件中的session.auto_start变量。如果将其设置为1,则所有文件都将运行,就好像它们进行了session_start()调用一样。如果想要自己控制它,请在php.ini文件中将其设置为0。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接