Using PHP to upload a file through a HTML fine is common, its normal however expecting or trying to get a progress bar to track the upload is wacky. That’s not how PHP works and doing live changes to a page is best left to JavaScript. However it is very much possible to get a progress bar for a PHP file upload, getting ideas and examples from here and here on how to do the JavaScript side of things i got a nice working example.
The form is style with Bootstrap and some other custom CSS. Here is index.html it contains a HTML form to upload a video (.mp4)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Upload Mp4</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="upload.js"></script>
</head>
<body>
<div class="container">
<div class="row text-center">
<div class="col-2"></div>
<div class="col-8">
<form id="upload_form" enctype="multipart/form-data" method="post">
<div class="form-group">
<input type="file" name="uploadingfile" id="uploadingfile">
</div>
<div class="form-group">
<input class="btn btn-primary" type="button" value="Upload File" name="btnSubmit"
>
upload.js contains the Ajax JavaScript which handles “real time” progress
function _(abc) {
return document.getElementById(abc);
}
function uploadFileHandler() {
var file = _("uploadingfile").files[0];
var formdata = new FormData();
formdata.append("uploadingfile", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "upload.php");
ajax.send(formdata);
}
function progressHandler(event) {
var loaded = new Number((event.loaded / 1048576));//Make loaded a "number" and divide bytes to get Megabytes
var total = new Number((event.total / 1048576));//Make total file size a "number" and divide bytes to get Megabytes
_("uploaded_progress").innerHTML = "Uploaded " + loaded.toPrecision(5) + " Megabytes of " + total.toPrecision(5);//String output
var percent = (event.loaded / event.total) * 100;//Get percentage of upload progress
_("progressBar").value = Math.round(percent);//Round value to solid
_("status").innerHTML = Math.round(percent) + "% uploaded";//String output
}
function completeHandler(event) {
_("status").innerHTML = event.target.responseText;//Build and show response text
_("progressBar").value = 0;//Set progress bar to 0
document.getElementById('progressDiv').style.display = 'none';//Hide progress bar
}
function errorHandler(event) {
_("status").innerHTML = "Upload Failed";//Switch status to upload failed
}
function abortHandler(event) {
_("status").innerHTML = "Upload Aborted";//Switch status to aborted
} Here is upload.php which does the PHP file upload handling
<?php
if (!$_FILES["uploadingfile"]["tmp_name"]) {//No file chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
} else {
$extension = pathinfo($_FILES['uploadingfile']['name'], PATHINFO_EXTENSION);//Gets the file extension
if ((($_FILES["uploadingfile"]["type"] == "video/mp4")) && $extension == 'mp4') {//Check if MP4 extension
$folderPath = "uploads/";//Directory to put file into
$original_file_name = $_FILES["uploadingfile"]["name"];//File name
$size_raw = $_FILES["uploadingfile"]["size"];//File size in bytes
$size_as_mb = number_format(($size_raw / 1048576), 2);//Convert bytes to Megabytes
if (move_uploaded_file($_FILES["uploadingfile"]["tmp_name"], "$folderPath" . $_FILES["uploadingfile"]["name"] . "")) {//Move file
echo "$original_file_name upload is complete";
//echo "$original_file_name uploaded to $folderPath it is $size_as_mb Mb.";
}
} else {
echo "File is not a MP4";
exit;
}
} Make sure you have an uploads folder, here is the style.css if you wanted my form style;
body, html {
background-color: #0b1025;
color: #e8e8e8;
}
form {
margin-top: 50%;
background: #191922;
border-radius: .3rem;
padding: 1.3rem;
border: #2274ac40 1px solid;
}
input {
width: 100%;
background: #3c4760;
border: 0;
padding: 20px;
border-radius: 6px;
margin-bottom: 10px;
border: 1px solid #839af5;
}
.btn {
width: 100%;
padding: .5rem;
border: 0;
background: #2b2a60;
font-size: 1.2em;
color: #fff;
text-shadow: 1px 1px 0px rgba(0, 0, 0, .4);
box-shadow: 0px 3px 0px #3a41a2;
margin-top: 1.2rem;
}
.btn:hover {
background: #1e1e3c;
color: #b5b5b5;
box-shadow: none;
}
.form-control {
display: block;
width: 100%;
height: calc(1.5em + .75rem + 2px);
padding: .375rem .75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #d6d8db;
background-color: #3c4760;
background-clip: padding-box;
border: 1px solid #72a7db;
border-radius: .25rem;
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.progress {
background-color: #3fee8c;
position: relative;
margin: 20px;
height: 1.2rem;
}
.progress-bar {
background-color: #7eeed8;
width: 100%;
height: 1.2rem;
}
progress::-webkit-progress-value {
background: #3fee8c;
}
progress::-webkit-progress-bar {
background: #1e1e3c;
}
progress::-moz-progress-bar {
background: #3fee8c;
}
A drained and empty Kennington reservoir images from a drone in early July 2024. The…
Merrimu Reservoir from drone. Click images to view larger.
Some early September spring shots from a bushwalk, It is still too early for wildflowers.
I recently needed to clone over a smaller NVMe to a 2TB SK Hynix Platinum…
If you ever needed a simple solution in Laravel to delete an entire directory and…
How to enforce only one user to register or be registered in a Laravel web…