2

这里只是一个新手,所以请原谅我的错误。
我正在使用 .shtml 页面 (SSI) 开发网站。我正在尝试将 PHP 脚本包含到我的 .shtml 页面中。到目前为止,一切都运行良好:PHP 脚本被包含在内,它完成了它的预期用途。这是实际的例子。主页 (index.shtml) 包含一个名为 security_check.php 的脚本,其中包含以下指令:

<!--#include virtual="includes/security_check.php?idOp=000&idPage=0000" -->

这是 security_check.php 的 PHP 代码:

<?php

session_start();

include('config.php');
include('myfunctions.php');
include('security_functions.php');

$idOp                 = $_GET['idOp'];
$idPage               = $_GET['idPage'];
$allowedReferer       = array();

// Connection to the database (defined in myfunctions.php)
$link   = DB_Connect($DBhost, $DBuser, $DBpass, 1, $DBname);

// Check if the PHP session already exists. If not, create one
// (that is insert a record in the DB and returns the id, which
// will be stored in the PHP session variable).
// user ID is 0 because not logged yet
if (!isset($_SESSION['idSess'])) {
    $_SESSION['idUser'] = 0;
    $_SESSION['idSess'] = create_session(); // security_functions.php
}

// Please note that create_session() correctly use $_SESSION['idUser']
// in order to do its work, even if it's not passed as a parameter
// (as it should be: $_SESSION is a superglobal!) and the same goes
// for activity_supervisor().

// Defined in security_functions.php:
// it uses both $_SESSION['idUser'] and $_SESSION['idSess']
activity_supervisor($idPage,$allowedReferer,2,$link);

mysql_close($link);

?>  

此时,主页已正确显示,其中有一个“注册”按钮,调用sign.shtml。此 sign.shtml 页面包含完全相同的security_check.php 脚本,除了在本例中为 0001 的 idPage 参数的值之外,该脚本具有完全相同的 include 指令。

我希望脚本能够识别 PHP 会话,因此 不会创建新会话,但实际上每次都会创建一个新会话。

我已经阅读了与 PHP 会话不起作用的所有其他帖子,我什至尝试了那里提出的解决方案。
- session_start() 写在每个脚本之上,因为只有一个脚本
- session.save_path 等于 /var/lib/php/session 并且可由 Web 服务器写入
- 我已经尝试设置 session.gc_probability = 0 并且重新启动网络服务器(无济于事,所以我回到 session.gc_probability = 1)
- 我尝试使用不同的浏览器(即 Firefox 和 Chrome),结果相同

所以我尝试了以下测试(注意 session_start() 之前的那两个空行:我总是以这种方式间隔指令以提高可读性)创建一个简单的 test.php 脚本

<?php

session_start();

if (!isset($_SESSION['foo'])) {
    $_SESSION['foo'] = 1;
    echo ('Value is '.$_SESSION['foo'].'<br/>');
    echo ('<a href="test.php">Refresh</a>');
}
else {
    $_SESSION['foo']++;
    echo ('Value is '.$_SESSION['foo'].'<br/>');
    echo ('<a href="test.php">Refresh</a>');
}

?>  

好吧,不管你信不信,每次我点击“刷新”时,值 都会增加,因此 PHP 会识别会话(test.php 脚本与 index.shtml 和 sign.shtml 页面位于同一域内)。
我什至试图让 PHP 脚本显示指向 .html 文件(不是 .shtml)的链接,然后显示指向 test.php 的链接。它工作正常!

似乎只有当 PHP 脚本包含在 .shtml 页面中时会话设置不正确,即使我没有看到任何原因。也许你知道为什么,最重要的是,如何规避这种无聊的行为?它是一个功能吗?它是否取决于 php.ini 中的参数设置?

最后提示:
操作系统:CentOS 6.3,内核为 2.6.32-279.el6.x86_64
服务器版本:Apache/2.2.15 (Unix)
PHP 5.3.3
服务器是我的,所以如果需要,我可以配置一切。

提前感谢并原谅我的长篇文章:我试图明确表示 PHP 会话在我所知道的所有其他情况下都能完美运行。

4

1 回答 1

0

我认为这不会起作用,因为 SSI 将执行 PHP 脚本,然后将其输出发送到 Web 服务器。您将需要某种方式重写 URL,以便它们不依赖于 cookie,因为 cookie 在服务器将它们发送到浏览器之前被“吃掉”。

尝试使用

ini_set("session.use_cookies",0);
ini_set("session.use_trans_sid",1);

然后您需要在传出 URL 中发送 SID(以及在 POST 页面上)。例如,请参阅此答案

具体来说,您需要将用户重定向到sign.shtml而不是重定向到类似的东西

$sidkey = session_name();
$sidval = session_id();
print "sign up: <a href=\"sign.shtml?{$sidkey}={$sidval}\">here</a>";

并将其包含在 SSI 输出中。

更新:问题的根源在于 SSI 无法创建会话(只能发送纯 HTML 之外的任何内容。使用 cookie 的会话依赖于标题,而不仅仅是 HTML)。但是,如果您使用在 SSI 外部启动的 PHP 脚本创建会话,该脚本能够设置 cookie,那么从那时起,所有 PHP 脚本(无论是否 SSI)都能够读取cookie,因此将能够访问和修改会话(这是由会话 cookie 的值标识的服务器上的文件/内存/Redis/其他)。

您可以检查是否在 SSI 中设置了 cookie,如果没有,您可以重定向到设置会话 cookie 并使用 HTTP 重定向发送回原始 shtml 的纯 PHP 页面。

于 2015-10-08T15:00:31.303 回答