我在本地开发服务器和远程Web服务器上都使用PHP版本5.3.2。
我正在尝试使用uploadify将多个文件上传到服务器。在接收脚本中,我想使用会话中存储的数据,但是,因为uploadify使用Flash将文件发送到脚本,所以它不会发送会话Cookie。解决此问题的方法是让uploadify到GET或POST会话ID到脚本,但是我发现这非常不可靠。在我的脚本中,我有以下内容:
<?php
ini_set('session.use_only_cookies', FALSE);
ini_set('session.use_trans_sid', TRUE);
session_name('SESSNAME');
session_start();
print_r($_SESSION);
脚本网址类似于script.php?SESSNAME = sessionid,我已经尝试使用上述透明会话ID,并且还使用session_id($ _ GET ['SESSNAME'])手动设置了ID。
当直接用浏览器直接访问脚本并发送当前会话ID时,即使我手动删除了会话cookie,此always也可以使用。它也可以在我的本地服务器上与uploadify一起使用。但是,在远程服务器上使用uploadify时,它的工作时间大约是20%,完全是随机的。没有模式。当我添加时,它似乎以更高的频率工作
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
对于脚本,但是这可能只是巧合。
本地服务器信息:http://www.dur.ac.uk/n.r.brook/info_local.php远程服务器信息:http://www.dur.ac.uk/n.r.brook/info.php
进行一些挖掘,查看脚本收到的标题,我想我可能已经确定了问题。使用uploadify时需要发送会话ID,因为使用FileReference.upload()(我认为!)方法时flash不会发送cookie。但是,除了会话ID外,在负载平衡的环境(如远程服务器)中,还有BALANCEID cookie,它确定用户当前正在使用的服务器。 Flash不会发送此cookie,因此负载均衡器有时会将请求发送到其他服务器,并且在该服务器上,会话不存在。
我已经在打印会话后通过设置会话变量来测试此行为。这样做并重复发送文件会出现问题-最初我得到一个空数组,但是变量中出现了一些重复。
因此,如果以上都是正确的,那么我的问题是我该怎么做才能使Flash随上传一起发送此数据,以便负载均衡器知道要使用哪个服务器?还是这是一个失败的原因?
经过进一步研究,我发现了以下帖子-http://swfupload.org/forum/generaldiscussion/977这表明无法通过FileReference.upload()发送cookie,因此,如果要使用会话数据,则不能将uploadify与负载平衡的服务器一起使用。但是,我想我现在将尝试一种解决方案,将链接到会话ID的数据保存到文件中。 uploadify接收脚本可以打开此文件并提取所需的数据。这是我第一次使用任何基于Flash的经验,但并没有改善我对该技术的看法!
我对这个问题的解决方案是:
在“上传”页面:
file_put_contents($some_folder.'/'.session_id(), serialize($just_the_vars_you_will_be_using));
在您的使用加载uploadify的JavaScript中:
var start = document.cookie.indexOf("PHPSESSID=");
var end = document.cookie.indexOf(";", start); // First ; after start
if (end == -1) end = document.cookie.length; // failed indexOf = -1
var cookie = document.cookie.substring(start+10, end);
$('#fileInput').uploadify({
'uploader' : 'uploadify.swf',
'script' : 'uploadify.php',
'cancelImg' : 'cancel.png',
'auto' : true,
'multi' : true,
'scriptData': { SESSID : cookie }
});
在接收文件的脚本中:
$vars = unserialize(file_get_contents($some_folder.'/'.$_POST['SESSID']));
如果要在此脚本中写回'session',请在最后:
file_put_contents($some_folder.'/'.$_POST['SESSID'], serialize($vars));
据我所知,应该没有与此相关的任何安全问题,因为您将只使用文件中存储的少数变量(我仅存储一个递增值和一个临时文件路径)。确保$ some_folder中有一个index.html以防止文件列表。
从Flash发送邮件时,有一种可以使用Cookie的方法。PHP需要Cookies才能找到会话存储ID。 cookie中存储的值是实际的会话ID,而cookie名称在大多数情况下是会话名称。要输入php中的会话,不能通过键入$ _SESSION ['name']完成,但是您可以创建自己的会话库。这将使php获得所有的鼻涕值,您可以继续。
这是我在php中放在一起的会话库:
function SESSION_OPEN($PATH,$NAME){
global $SESSION_PATH, $SESSION_NAME;
$SESSION_PATH=$PATH;
$SESSION_NAME=$NAME;
return(true);
}
function SESSION_CLOSE(){
return(true);
}
function SESSION_GET($ID){
global $SESSION_PATH, $SESSION_NAME;
$STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";
if($RESOURCE = @fopen($STR_PATH,"r")){
$CONTENT = @fread($RESOURCE ,filesize($STR_PATH));
return($CONTENT);
}else{
return(false);
}
}
function SESSION_PUT($ID,$VALUE){
global $SESSION_PATH, $SESSION_NAME;
$STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";
if($RESOURCE = @fopen($STR_PATH,"w")){
fwrite($RESOURCE , $VALUE );
return(true);
}else{
return(false);
}
}
function SESSION_DEST($ID){
global $SESSION_PATH, $SESSION_NAME;
$STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";
return(@unlink($STR_PATH));
}
function SESSION_GC($MAX_EXECUTION){
return(true);
}
session_set_save_handler("SESSION_OPEN","SESSION_CLOSE","SESSION_GET","SESSION_PUT","SESSION_DEST","SESSION_GC");