1

我在本地开发服务器和远程 Web 服务器上都使用 PHP 5.3.2 版。

我正在尝试使用uploadify将多个文件上传到服务器。在接收脚本中,我想使用存储在会话中的数据,但是因为 uploadify 使用 flash 将文件发送到脚本,所以它不会发送会话 cookie。
这个问题的解决方法是上传到 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);

脚本 url 类似于 script.php?SESSNAME= sessionid,我已经尝试使用上面的透明会话 id 并使用 session_id($_GET['SESSNAME']) 手动设置 id。

这在直接使用浏览器访问脚本并发送当前会话 ID 时始终有效,即使我手动删除会话 cookie。它也总是适用于我本地服务器上的uploadify。然而,当在远程服务器上使用 uploadify 时,它大约有 20% 的时间工作,完全随机。没有模式。当我添加时,它似乎以更高的频率工作

ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);

剧本,然而这可能只是巧合。

本地服务器信息:http
://www.dur.ac.uk/nrbrook/info_local.php 远程服务器信息:http ://www.dur.ac.uk/nrbrook/info.php


一些猜测...

做一些挖掘并查看脚本正在接收的标题,我想我可能已经确定了这个问题。
使用uploadify 时需要发送会话ID,因为使用FileReference.upload()(我认为!)方法时flash 不会发送cookie。但是,除了会话 id 之外,在负载平衡环境(例如远程服务器)中,还有 BALANCEID cookie,它确定用户当前正在使用哪个服务器。Flash 不发送此 cookie,因此负载平衡器有时会将请求发送到不同的服务器,并且在此服务器上不存在会话。

在打印会话后,我通过设置会话变量来测试此行为。这样做并重复发送文件会出现问题 - 起初我得到一个空数组,但变量中开始出现一些重复。

所以,如果以上都是真的,那么我的问题是我该怎么做才能让闪存通过上传发送这些数据,以便负载均衡器知道要使用哪个服务器?或者这是一个失败的原因?


答案?

经过进一步研究,我发现以下帖子 - http://swfupload.org/forum/generaldiscussion/977
这表明无法使用 FileReference.upload() 发送 cookie,因此如果出现负载平衡服务器,则无法使用 uploadify你想使用会话数据。但是,我想我现在将尝试一种解决方案,将链接到会话 ID 的数据保存到文件中。uploadify 接收脚本可以打开这个文件并拉出需要的数据。
这是我第一次使用任何基于 Flash 的东西,它并没有改善我对技术的看法!

4

2 回答 2

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 以防止文件列出。

于 2010-07-31T15:36:56.553 回答
0

有一种方法可以在从 flash 发送时使用 cookie。php 需要 cookie 来查找会话存储 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");
于 2011-09-01T17:15:57.303 回答