我正在尝试在php.ini中进行一系列更改之后使工作成为upload_progress会话,如:
session.upload_progress.enabled = On
;session.upload_progress.cleanup = On
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "123"
session.upload_progress.freq = "1%"
session.upload_progress.min_freq = "1"
并创建了基于html的页面,其中包含用于提交文件的表单:
<form action="upload_progress.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="submit" />
</form>
然后是正确上传文件的服务器端脚本:
session_start();
move_uploaded_file($_FILES['file1']['tmp_name'], './uploads/'.$_FILES['file1']['name']);
move_uploaded_file($_FILES['file2']['tmp_name'], './uploads/'.$_FILES['file2']['name']);
print_r($_SESSION);
$_SESSION
全局变量中有一个空数组,尽管文件上传已正确完成。会话设置有什么问题?
我正在使用 PHP 5.4.5
Notice: Undefined index: upload_progress_123 in C:\apache\localhost\www\upload_progress.php on line 13
答案 0 :(得分:3)
通过PHP会话上传进度非常棘手并非所有上下文和环境都有详细记录。 Number of similar questions indicates it causes troubles。我个人在这方面失去了一天以上,所以我的建议是帮助你。
php.ini
session.upload_progress.cleanup = Off中禁用立即会话属性清理这样,您可以在上传完成后检查会话的内容。
找出存储会话的位置(session.save_path
中的变量php.ini
,linux机器上的典型值为/var/lib/php/sessions
)并检查它们,查找名为{{的{ 1}}上传后启动。
要激活特定的上传进度跟踪,通常会使用隐藏的HTML表单元素。必须先将发送到文件。如果您考虑它是合乎逻辑的:当PHP处理请求时,它必须首先遇到信号以开始跟踪文件上载进度,然后识别文件本身。反过来说,它不会起作用。
upload_progress_xxxxxxxxxxx
小心提交AJAX。虽然不太可能,但某些JS库可能会更改HTTP请求中元素的顺序。您应该使用浏览器中的开发人员工具检查实际的HTTP通信,并确保发送的元素的顺序与前一点一致。
会话名称。虽然您可以在代码中使用任何可能的会话名称,但PHP不知道它并将上传进度始终写入默认会话,通常是<form action="upload_progress.php" method="POST" enctype="multipart/form-data">
<input type="hidden"
name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="myfile1" />
<input type="submit" />
</form>
(请咨询您的PHPSESSID
' s属性php.ini
来检查实际值。)This behavior is not a bug.
如果您介意创建两个会话,则应更改代码以使用默认值或更改session.name
的默认值,这并非总是可行(例如,共享托管)。请注意,该值也可以通过session.name
更改。
在将上传进度写入会话时,一些PHP框架(Zend,Cake PHP)拥有自己的会话内容结构,而PHP引擎会破坏会话。导致丢失存储的信息,从而导致签名等损失,导致对跟踪等的损害Issue,issue,issue。 我得出的结论是,在这种情况下必须使用2个不同的会话。
我正在使用Zend Framework,最后我有两个单独的会话。我使用以下普通的PHP脚本来报告特定的文件上载进度。该脚本与Zend Framework完全隔离,并使用默认的.htaccess
命名空间。
PHPSESSID
在Zend Framework之上创建的应用程序在session_start();
if(!isset($_GET['id']))
die("unsupported");
$id = $_GET['id'];
if(!preg_match('/^[a-zA-Z0-9]{1,32}$/', $id))
die("unsupported");
$sessionKey = ini_get('session.upload_progress.prefix') . $id;
$uploadInfo = (isset($_SESSION[$sessionKey])) ? $_SESSION[$sessionKey] : null;
$status = [
'total' => 0,
'current' => 0,
'rate' => 0,
'message' => '',
'done' => false,
];
if($uploadInfo === null)
{
header('Content-Type: application/json');
echo json_encode($status);
return;
}
$status = $uploadInfo + $status;
$status['total'] = $status['content_length'];
$status['current'] = $status['bytes_processed'];
$time = time() - $status['start_time'];
$status['rate'] = ($time > 0) ? $status['bytes_processed'] / $time : 0;
if (!empty($status['cancel_upload'])) {
$status['done'] = true;
$status['message'] = 'The upload has been canceled';
}
header('Content-Type: application/json');
echo json_encode($status);
的{{1}}方法中设置了自己的会话命名空间:
Module.php
答案 1 :(得分:1)
上传进度可以在$ _SESSION数组中看到,因此可以检查另一个php请求的进度。
$ _ SESSION将在上传文件之前上传文件。所以一旦你处理完文件就会消失。你应该在上传文件时在单独的请求中print_r这个。不在同一个请求中。
就像在这个例子中一样
check_progress.php
<?php
if(isset($_SESSION['upload_progress_123']))){
print_r($_SESSION['upload_progress_123']);
}
?>
示例数组
<?php
$_SESSION["upload_progress_123"] = array(
"start_time" => 1234567890, // The request time
"content_length" => 57343257, // POST content length
"bytes_processed" => 453489, // Amount of bytes received and processed
"done" => false, // true when the POST handler has finished, successfully or not
"files" => array(
0 => array(
"field_name" => "file1", // Name of the <input/> field
// The following 3 elements equals those in $_FILES
"name" => "foo.avi",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => true, // True when the POST handler has finished handling this file
"start_time" => 1234567890, // When this file has started to be processed
"bytes_processed" => 57343250, // Number of bytes received and processed for this file
),
// An other file, not finished uploading, in the same request
1 => array(
"field_name" => "file2",
"name" => "bar.avi",
"tmp_name" => NULL,
"error" => 0,
"done" => false,
"start_time" => 1234567899,
"bytes_processed" => 54554,
),
)
);
完成教程可以在这里找到,如pilif所说
http://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/
http://oliversmith.io/technology/2011/12/04/php-5-4-file-upload-progress-and.html5-progress-bars/
也可以看到这个答案。 PhP Upload progress in PhP 5.4 is not working. Session variables not set
答案 2 :(得分:0)
如果您将DockerCompose与NGINX和PHP的单独容器一起使用,则会话upload_progress_xxx将不会更新。它仅适用于设置为“Apache x.x Handler”的PHP Server API。
我删除了NGINX,而只使用官方的PHP / Apache图像,现在它工作正常。这是我的Docker-Compose文件:
version: '3'
services:
php:
image: "php:7.0-apache"
ports:
- "8080:80"
volumes:
- ./www:/var/www/
- ./etc/php/php.ini:/usr/local/etc/php/php.ini
答案 3 :(得分:0)
我知道有点晚了,但这也许可以帮助别人。
确保已将php.ini中的 session.autostart 设置为“ 打开”,且不带引号。这对我来说是个问题,所以我得到一个空数组,试图跟踪上传进度。
我使用php进行了有效的上传。
请参阅:
https://github.com/TychaK/Track-Upload-Progress-using-Session-Upload-Progress-PHP-JavaScript-Ajax
我希望这对其他开发人员有所帮助:-)