Se você fizer uma consulta às configurações do PHP, verá que existem as novas session.upload_progress.enabled, session.upload_progress.cleanup, session.upload_progress.prefix, session.upload_progress.name, session.upload_progress.freq e session.upload_progress.min_freq. Estas variáveis definem o comportamento do PHP no momento da detecção e atualização das informações dos uploads de arquivos.
Para implementar uma barra de progresso que mostrará ao usuário as informações do upload depois que o formulário teve seu envio disparado, fiz algum código para exemplificar o processo. O código foi feito a partir de uma instalação "limpa" do Apache e do PHP.
upload.php (este é o arquivo que contém o formulário e as declarações de CSS e JavaScript necessárias, que podem estar em arquivos separados e chamados via SRC e HREF)
<?php
$is_PHP54_installed = ($x = @ini_get('session.upload_progress.name'));
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP 5.4 Upload Progress Bar Demo<?php echo (!$is_PHP54_installed ? ' (will not working, installed PHP version is ' . phpversion() . ')' : '') ?></title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<style type="text/css">
#upload_progress_status {
display: none;
width: 50%;
margin: 20px 0px 0px 0px;
overflow: hidden;
}
#upload_progress_status .bar,
#upload_progress_status .bar .progress {
display: block;
line-height: 20px;
overflow: hidden;
}
#upload_progress_status .bar {
border: 1px solid #000;
}
#upload_progress_status .bar .progress {
width: 0%;
background-color: #000;
color: #fff;
font-size: 12px;
font-weight: bolder;
text-align: center;
}
#form {
display: block;
}
#loading {
display: none;
}
</style>
<script type="text/javascript">
<!--
$j = jQuery;
upload_progress_status_timer = <?php echo (int)(@ini_get('session.upload_progress.min_freq')) * 1000 ?>;
upload_progress_status_load = function () {
try { upload_progress_status_load_XMLHTTP.abort(); } catch (e) {}
upload_progress_status_load_XMLHTTP = $j.ajax ({ url: "upload_progress_status.php",
dataType: "json",
error: function () {
setTimeout(function () { upload_progress_status_load(); }, upload_progress_status_timer);
},
success: function (info) {
var ups = $j("#upload_progress_status"),
bu = $j("#upload_progress_status .bytes_processed"),
cl = $j("#upload_progress_status .content_length"),
et = $j("#upload_progress_status .elapsed_time"),
pbp = $j("#upload_progress_status .bar .progress");
if (info != null) {
ups.show();
bu.html(info.bytes_processed_human);
cl.html(info.content_length_human);
et.html(info.elapsed_time_human);
pbp.stop().animate({ width: info.uploaded }, upload_progress_status_timer).html(info.uploaded);
if (!info.done) setTimeout(function () { upload_progress_status_load(); }, upload_progress_status_timer);
else ups.hide();
}
}
});
}
form_loading = function () {
$j("#form").hide();
$j("#loading").show();
}
-->
</script>
</head>
<body>
<div id="form">
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post" enctype="multipart/form-data"<?php if ($is_PHP54_installed) { ?> onsubmit="form_loading(); upload_progress_status_load()"<?php } ?>><?php
if ($is_PHP54_installed) { ?><input type="hidden" name="<?php echo $x ?>" value="demo" /><?php }
for ($k=0; $k<=4; $k ) {
?>File <?php echo $k 1 ?>: <input type="file" name="files[<?php echo $k ?>]" size="30" /><br/><?php
}
?><input type="submit" value="Send files" />
</form>
<?php if (count($_FILES)) echo '<pre>' . print_r($_FILES, true) . '</pre>' ?>
</div>
<div id="loading">Sending...</div>
<div id="upload_progress_status">
<div class="bar"><div class="progress">0%</div></div>
<span class="bytes_processed">0</span> of <span class="content_length">0</span><br/>
<span class="elapsed_time">00:00</span> elapsed time
</div>
</body>
</html>
upload_progress_status.php (este é o arquivo que retornará ao JavaScript as informações do progresso do upload)
<?phpAcrescentei alguns itens no array de informações, que originalmente não existem nas que o PHP cria, como o cronômetro do upload, as informações de tamanho total e já enviado em um formato mais legível, e a porcentagem do total de dados já enviados.
@session_start();
function get_user_readable_filesize ($fs) {
$fsl = array('bytes', 'KB', 'MB', 'GB', 'PB', 'YB');
$y = 0;
while ($fs >= 1024) {
$fs /= 1024;
$y ;
}
return number_format($fs, $y ? 2 : 0, '.', '') . ' ' . $fsl[$y];
}
if (($info = @$_SESSION[ini_get('session.upload_progress.prefix') . 'demo'])) {
$info['content_length_human'] = get_user_readable_filesize($info['content_length']);
$info['bytes_processed_human'] = get_user_readable_filesize($info['bytes_processed']);
$info['elapsed_time'] = time() - $info['start_time'];
$info['elapsed_time_human'] = sprintf('%02d', (int)($info['elapsed_time'] / 60)) . ':' . sprintf('%02d', (int)($info['elapsed_time'] % 60));
$info['uploaded'] = number_format(($info['bytes_processed'] * 100 / $info['content_length']), 2, '.', '') . '%';
$x = $info['files'];
unset($info['files']);
$info['files'] = $x;
}
echo @json_encode($info);
?>
Você pode customizar os arquivos, adicionando estilos CSS, eventos JavaScript, valores de retorno JSON, enfim, o que sua criatividade e necessidade exigirem. O essencial está na variável de sessão que está declarada no arquivo upload.php e no campo hidden declarado no formulário. São eles que tornam possível o monitoramento do progresso do upload no PHP 5.4.0 ou superior.
Postar um comentário