需要通过 CURL 将会话共享到 PHP 中同一域中的本地伪服务器
Need to share session to LOCAL psuedo server on same domain in PHP through CURL
我正在使用本地 php 文件构建一个应用程序,该文件接受 post/get 输入和 returns JSON 结果。我这样做是为了分离前端和后端操作,因为它可能最终将后端移动到其他地方(而且它很简洁,因为您可以仅使用浏览器和 URL 变量来测试后端操作。
明确地说,我没有立即甚至长期的计划来实际分离它们:现在它们在同一服务器上的同一文件夹中,甚至 - 我只有一个 backend.php 文件伪装成一个远程服务器,这样我就可以练习解耦了。这个问题的胜利意味着调用 CURL 并让后端接收会话,后端可以 change/update/addto 会话,前端看到所有更改(基本上是前端和后端的一个会话)。
问题是我一直在努力让会话在两者之间工作。当我使用 Javascript 发出 AJAX 请求时,会话工作正常,因为它是在同一台服务器上加载的页面,所以 session_start() 正常工作。但是当我CURL的时候,session数据没有传输。
几个月来我一直在为此苦苦挣扎,所以我的 curl 函数非常混乱,但我想不出使它起作用的神奇组合。在这种情况下,我无法始终如一地找到任何 SO 问题或在线指南:
// Call the backend using the provided URL and series of name/value vars (in an array)
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
//$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_PUT, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
# curl_setopt($ch, CURLOPT_VERBOSE, 1);
# curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
// $strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
$cookieFile = "cookies.txt";
if(!file_exists($cookieFile)) {
$fh = fopen($cookieFile, "w");
fwrite($fh, $_SESSION);
fclose($fh);
}
#curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
#curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIEFILE, $strCookie );
# session_write_close();
// Have to pause the session or the backend wipes the front
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
curl_close($ch);
# session_start();
// "true" makes it return an array
return json_decode($result,true);
}
我从前端这样调用函数从后端获取结果:
// Get user by email or ID
function get_user($emailorid) {
// If it's not an email, see if they've been cached. If so, return them
if (is_numeric($emailorid) && $_SESSION['users'][$emailorid])
return $_SESSION['users'][$emailorid];
return backhand(['get_user'=>$emailorid]);
}
所以如果我在前面的任何地方调用“get_user”,它会跳到后面,运行 数据库查询并将它全部转储到返回的 JSON在值的关联数组中对我来说。这工作正常,但会话数据不能正确保留并且会导致问题。
我什至尝试了一段时间的数据库会话,但这也不一致。我 运行 没有想法,可能必须通过使用数据库和自定义函数来构建某种备用会话功能,但我希望这个 CAN 可以工作......我只是还没有弄清楚如何。
如果您的后端 Web 服务器位于不同的服务器上,您可以保留文件系统存储并与 NFS 共享存储会话的文件目录。
您也可以使用 http://www.php.net/manual/en/function.session-set-save-handler.php 为会话设置不同的保存处理程序,但我不确定将它们存储在数据库中对 I/O.[=11 是个好主意=]
经过 brute-force 反复试验,这似乎可行:
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_HTTPGET, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
// required or it writes the data directly into document instead of putting it in a var below
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
#curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
curl_setopt($ch, CURLOPT_COOKIEJAR, 'somefile');
curl_setopt($ch, CURLOPT_COOKIEFILE, APP_ROOT.'/cookie.txt');
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
// Have to pause the session or the backend wipes the front
session_write_close();
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
@session_start();
curl_close($ch);
// "true" makes it return an array
return json_decode($result,true);
}
我正在使用本地 php 文件构建一个应用程序,该文件接受 post/get 输入和 returns JSON 结果。我这样做是为了分离前端和后端操作,因为它可能最终将后端移动到其他地方(而且它很简洁,因为您可以仅使用浏览器和 URL 变量来测试后端操作。
明确地说,我没有立即甚至长期的计划来实际分离它们:现在它们在同一服务器上的同一文件夹中,甚至 - 我只有一个 backend.php 文件伪装成一个远程服务器,这样我就可以练习解耦了。这个问题的胜利意味着调用 CURL 并让后端接收会话,后端可以 change/update/addto 会话,前端看到所有更改(基本上是前端和后端的一个会话)。
问题是我一直在努力让会话在两者之间工作。当我使用 Javascript 发出 AJAX 请求时,会话工作正常,因为它是在同一台服务器上加载的页面,所以 session_start() 正常工作。但是当我CURL的时候,session数据没有传输。
几个月来我一直在为此苦苦挣扎,所以我的 curl 函数非常混乱,但我想不出使它起作用的神奇组合。在这种情况下,我无法始终如一地找到任何 SO 问题或在线指南:
// Call the backend using the provided URL and series of name/value vars (in an array)
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
//$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_PUT, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
# curl_setopt($ch, CURLOPT_VERBOSE, 1);
# curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
// $strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
$cookieFile = "cookies.txt";
if(!file_exists($cookieFile)) {
$fh = fopen($cookieFile, "w");
fwrite($fh, $_SESSION);
fclose($fh);
}
#curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
#curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIEFILE, $strCookie );
# session_write_close();
// Have to pause the session or the backend wipes the front
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
curl_close($ch);
# session_start();
// "true" makes it return an array
return json_decode($result,true);
}
我从前端这样调用函数从后端获取结果:
// Get user by email or ID
function get_user($emailorid) {
// If it's not an email, see if they've been cached. If so, return them
if (is_numeric($emailorid) && $_SESSION['users'][$emailorid])
return $_SESSION['users'][$emailorid];
return backhand(['get_user'=>$emailorid]);
}
所以如果我在前面的任何地方调用“get_user”,它会跳到后面,运行 数据库查询并将它全部转储到返回的 JSON在值的关联数组中对我来说。这工作正常,但会话数据不能正确保留并且会导致问题。
我什至尝试了一段时间的数据库会话,但这也不一致。我 运行 没有想法,可能必须通过使用数据库和自定义函数来构建某种备用会话功能,但我希望这个 CAN 可以工作......我只是还没有弄清楚如何。
如果您的后端 Web 服务器位于不同的服务器上,您可以保留文件系统存储并与 NFS 共享存储会话的文件目录。
您也可以使用 http://www.php.net/manual/en/function.session-set-save-handler.php 为会话设置不同的保存处理程序,但我不确定将它们存储在数据库中对 I/O.[=11 是个好主意=]
经过 brute-force 反复试验,这似乎可行:
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_HTTPGET, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
// required or it writes the data directly into document instead of putting it in a var below
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
#curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
curl_setopt($ch, CURLOPT_COOKIEJAR, 'somefile');
curl_setopt($ch, CURLOPT_COOKIEFILE, APP_ROOT.'/cookie.txt');
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
// Have to pause the session or the backend wipes the front
session_write_close();
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
@session_start();
curl_close($ch);
// "true" makes it return an array
return json_decode($result,true);
}