我正在尝试将会话上传进度功能(http://php.net/manual/en/session.upload-progress.php)用于Kohana。我已经设法使用以下代码在没有Kohana的情况下在本地工作:
<?php
session_start();
if (isset($_GET['progress']))
{
// does key exist
$key = ini_get("session.upload_progress.prefix") . 'demo';
if ( !isset( $_SESSION[$key] ) ) exit( "uploading..." );
// workout percentage
$upload_progress = $_SESSION[$key];
$progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 );
exit( "Upload progress: $progress%" );
}
?>
<!doctype html>
<head>
</head>
<body>
<section>
<h1>Upload Form</h1>
<form action="" method="POST" enctype="multipart/form-data" target="upload-frame">
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="<?php //echo $uid; ?>demo">
<p>
<label>File:</label>
<input type="file" name="file" required="required">
</p>
<p><input type="submit" name="submit" value="Upload"></p>
</form>
<iframe id="upload-frame" name="upload-frame" width="1280" height="600"></iframe>
<div id="file_upload_progress"></div>
</section>
<script src="jquery-1.7.1.min.js"></script>
<script>
$(document).ready(function() {
var uploading = false;
$('form').submit(function() {
uploading = true;
$('#upload-frame').one('load', function(){
uploading = false;
});
function update_file_upload_progress() {
$.get("?progress", function(data) {
$("#file_upload_progress").html(data);
if (uploading) {
setTimeout( update_file_upload_progress, 500 );
}
})
.error(function(jqXHR, error) {
alert(error);
});
}
// first call
update_file_upload_progress();
});
});
</script>
</body>
</html>
但是当我在Kohana中使用此代码时(当然将PHP分离到控制器中),不会创建$_SESSION
变量来跟踪上传的进度。
我认为这与Kohana会议的工作方式有关。我不能在脚本开头有session_start()
,因为它与已经运行的Kohana会话冲突。如果我转储$_SESSION
或Session::instance()
内容,那么应该由PHP上传进度功能添加的变量不存在。
那么如何让会话变量与Kohana一起使用?
更新
我已经创建了一个干净的Kohana安装,以帮助缩小这个问题。我发现通过不在Kohana中实例化Session
类我可以使用上面的代码并且它可以正常工作。
但是,当Session
类被实例化,它需要用于我的Web应用程序时,它将停止工作,并且不再创建包含上载进度的$_SESSION
变量。这让我相信问题在于Kohana如何管理会话信息。我尝试使用配置设置关闭加密,但这没有什么区别。
我正在使用原生会话。
答案 0 :(得分:2)
会话cookie名称必须与php config(session.name
)中设置的名称完全相同,例如:
return array(
'native' => array(
'encrypted' => FALSE,
'name' => ini_get('session.name'),
),
);
如果您不想使用PHP的默认会话cookie名称,将不会通过在运行时设置值来解决此问题,即这不会起作用:
ini_set('session.name', 'my_kohana_session_name');
你将通过设置.htaccess文件中的值来解决这个问题:
php_flag session.name "my_kohana_session_name"
这样你可以保持php.ini不受影响,但你可以保留你的Kohana应用程序的自定义cookie名称。
我的测试证明,使用本机会话驱动程序时,会话加密不会影响上载进度信息。这肯定是因为使用本机驱动程序时不使用加密来重新设置该设置。 ;)
PS。我还建议一件事 - 确保没有缓存ajax请求。有很多情况下它被缓存而没有显示出新的反应。
答案 1 :(得分:1)
我找到了解决方案。
我所做的是隔离了将PHP生成的$_SESSION
变量读入其自己的Controller
的代码。在我的情况下,我有一个AJAX控制器用于通用AJAX检查,如验证电子邮件,Web URL等。来自默认extends
的控制器Controller
,以便它不会从我的自定义控制器继承任何会话信息(是我的其他控制器扩展而来的。)
所以我的新独立Controller
看起来像这样:
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Ajax extends Controller {
public function action_upload_progress()
{
// get upload progress key
$key = (!empty($_POST['key'])) ? $_POST['key'] : FALSE;
// start session to get PHP 5.4 generated $_SESSION variables
session_start();
// does key exist
$key = ini_get("session.upload_progress.prefix") . $key;
if ( !isset( $_SESSION[$key] ) ) {
exit( "uploading..." );
}
// workout percentage
$upload_progress = $_SESSION[$key];
$progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 );
exit( "Upload progress: $progress%" );
}
}
我对实际表单使用与以前相同的代码,并对JavaScript进行微调,请求此控制器/操作检索上载进度数据。问题解决了!