我在我的本地开发服务器和远程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手动设置id($ _ GET ['SESSNAME'])
当使用浏览器直接访问脚本并发送当前会话ID时,即使我手动删除会话cookie,总是也能正常工作。它也始终与我的本地服务器上的uploadify一起使用。但是,在远程服务器上使用uploadify时,它大约有20%的时间是完全随机的。没有模式。当我添加
时,它似乎工作频率更高ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
到剧本,但这可能只是巧合。
有什么想法吗?
本地服务器信息:hxxp://www.dur.ac.uk/n.r.brook/info_local.php
远程服务器信息:hxxp://www.dur.ac.uk/n.r.brook/info.php
(对不起hxxp,没有权限发布多个链接!)
做一些挖掘并查看脚本正在接收的标题,我想我可能已经确定了问题 您需要在使用uploadify时发送会话ID,因为在使用FileReference.upload()(我认为!)方法时,Flash不会发送cookie。但是,除了会话ID之外,在负载平衡环境(例如远程服务器)中还有BALANCEID cookie,它确定用户当前使用的服务器。 Flash不发送此cookie,因此负载均衡器有时会将请求发送到其他服务器,并且在此服务器上该会话不存在。
我通过在打印会话后设置会话变量来测试此行为。执行此操作并重复发送文件会出现问题 - 首先我得到一个空数组,但变量中的一些重复开始出现。
所以,如果以上都是真的,那么我的问题是如何让flash通过上传发送这些数据,以便负载均衡器知道要使用哪个服务器?或者这是一个失败的原因?
经过进一步研究,我发现了以下帖子 - hxxp://swfupload.org/forum/generaldiscussion/977
这表明无法使用FileReference.upload()发送cookie,因此如果要使用会话数据,uploadify不能与负载平衡服务器一起使用。但是,我想我现在将尝试一种解决方案,将链接到会话ID的数据保存到文件中。 uploadify接收脚本可以打开此文件并提取所需数据
这是我第一次使用任何基于Flash的体验,它没有改善我对该技术的看法!
答案 0 :(得分:0)
我对此问题的解决方案是:
在“上传”页面中:
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']));
如果您想在此脚本中回写“会话”,最后:
file_put_contents($some_folder.'/'.$_POST['SESSID'], serialize($vars));
据我所知,不应该有任何与此相关的安全问题,因为您只会使用存储在文件中的少数变量(我只存储递增值和临时文件路径)。确保$ some_folder中有index.html以防止文件列表。
答案 1 :(得分:0)
从闪存发送时,您可以使用Cookie。 php需要使用Cookies来查找会话存储ID。存储在cookie中的值实际上是会话ID,cookie名称在大多数情况下是会话名称。 要在php中进行会话无法通过输入$ _SESSION ['name']来完成,但您可以创建自己包含的会话库。这将让php获得所有nassery值,你可以继续。
这是我在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");