问题是客户端没有记住/传输 PHP 会话 ID。
当 HTTP 客户端(通过 HTTP 服务器)向 php 脚本发出请求时,如果它希望继续先前启动的会话,则必须在请求中包含会话 ID。这可以在 HTTP 标头中作为 cookie 或 URL 参数(默认情况下名为 PHPSESSID)来完成。
如果您不想使用 PHP 的默认会话变量名称,或者您想使用 POST 变量而不是 URL 参数,那么您可以使用任何您希望的请求变量或 URL 参数(无论是 GET、POST 还是 COOKIE) ),但是您需要在服务器端手动解释此变量。
以下是三种解决方案,按最推荐到最不推荐的顺序排列。
- 在 cUrl 中打开 cookie 支持or
- 将会话 ID 作为 URL 参数传递or
- 将会话 ID 作为请求变量 (post/cookie) 或不使用 PHP 所需名称的 URL 参数传递,然后使用该会话 ID 在服务器端手动启动会话。
解决方案#1:在 cUrl 中打开 cookie 支持
每次您从该客户端发出请求时,PHP 都会使用 cookie 中的会话 ID 重新加载会话数据。
在本例中,客户端是 cUrl。您需要设置 cUrl 请求以允许/使用 cookie。
这是通过设置来完成的CURLOPT_COOKIEJAR http://curl.haxx.se/libcurl/c/CURLOPT_COOKIEJAR.html and CURLOPT_COOKIEFILE http://curl.haxx.se/libcurl/c/CURLOPT_COOKIEFILE.html选项。
session_start();
$_POST["username"]= "user";
$_POST["password"]= "password";
$ch = curl_init();
$url = 'signin.php';
//Name of a file to store cookie data in.
//If the file does not exist, it will be created.
//cUrl (or your web server) needs to have write permissions to the folder.
$cookieFile = "/some/writable/folder/filename";
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($_POST));
curl_setopt($ch,CURLOPT_POSTFIELDS, $_POST);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
//Tell cUrl about the cookie file
curl_setopt($ch,CURLOPT_COOKIEJAR, $cookieFile); //tell cUrl where to write cookie data
curl_setopt($ch,CURLOPT_COOKIEFILE, $cookieFile); //tell cUrl where to read cookie data from
$result = json_decode(curl_exec($ch),true);
curl_close($ch);
任何使用 $cookieFile 表示 CURLOPT_COOKIEJAR 和 CURLOPT_COOKIEFILE 的后续 cUrl 调用都将具有与先前调用相同的会话数据。
解决方案#2:使用预期的参数名称在 URL 查询字符串中传递会话 ID(默认为 PHPSESSID,但这可以更改)
您可以将会话 ID 附加到所有 url,如下所示:
somepage.php?PHPSESSID=sessionidgoeshere
“PHPSESSID”是 PHP 中默认使用的变量名称。如果服务器是设置为使用非默认名称 http://php.net/manual/en/function.session-name.php,那么您需要使用该变量名称。
使用解决方案#2,您仍然需要以某种方式在客户端存储会话 ID。
解决方案 #3:将会话 ID 作为请求变量或 URL 参数传递,然后使用该会话 ID 在服务器端手动启动会话。
一般情况下不建议使用此解决方案。与之前的解决方案不同,此解决方案需要更改服务器端脚本以及客户端 (cUrl)。仅当您特别希望将会话 ID 作为 URL 参数或 cookie 以外的其他内容发送,或者您希望使用服务器期望的名称以外的变量名称时,此解决方案才有用。
放置在启动会话之前,在服务器端 PHP 中处理请求的以下代码 http://php.net/manual/en/function.session-id.php:
session_id($_POST[<param_name>]);
or session_id($_GET[<param_name>]);
or session_id($_COOKIE[<param_name>]);
我建议使用解决方案#1,除非您有令人信服的理由不这样做。
此外,PHP 并不关心请求是 GET 还是 POST 或任何其他 HTTP 请求方法。无论采用何种 HTTP 请求方式,如果 session id 为作为 URL 参数或在 cookie 中传递 http://php.net/manual/en/session.idpassing.php,那么相关的会话就会在服务器端持久化。