Home > Article > Backend Development > PHP file upload progress bar is implemented based on Session and Javascript_PHP tutorial
If you are using php before 5.4, you can only achieve it through ajax, iframe or some other methods. If you are using php5.4, we can use session.upload_progress to quickly combine with js to implement the file upload progress bar. .
Below we will introduce in detail the new session.upload_progress feature of PHP 5.4.
Principle introduction
When the browser uploads a file to the server, PHP will store the detailed information of the file upload (such as upload time, upload progress, etc.) in the session. Then, as the upload progresses, the information in the session is periodically updated. In this way, the browser can use Ajax to periodically request a server-side script, and the script returns the progress information in the session; the browser-side Javascript can display/update the progress bar based on this information.
So, how is the file upload information stored? How do we access it? Let’s explain in detail below.
Some configuration items have been introduced in PHP 5.4 (set in php.ini)
session.upload_progress.enabled = "1"
session.upload_progress.cleanup = "1"
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.freq = "1%"
session.upload_progress.min_freq = "1"
Among them, enabled controls whether the upload_progress function is enabled or not, which is enabled by default; cleanup sets whether to clear session-related information after the file upload request is submitted, which is enabled by default.
The prefix and name are used to set the variable name/key name where the progress information is stored in the session. See below for detailed usage of these two items.
freq and min_freq are used to set the frequency of updating progress information on the server side. Properly setting these two items can reduce the load on the server.
In the form for uploading files, you need to set an identifier for this upload and use this identifier to reference progress information in the subsequent process. Specifically, there needs to be a hidden input in the upload form, whose name attribute is the value of session.upload_progress.name in php.ini; its value is an identifier defined by yourself. As follows:
name=""
value="test" />
After receiving the file upload form, PHP will create a new key in the $_SESSION variable. The key name is a string obtained by concatenating the value of session.upload_progress.prefix with your custom identifier above. It can be obtained like this:
$name = ini_get('session.upload_progress.name');
$key = ini_get('session.upload_progress.prefix') . $_POST[$name];
$_SESSION[$key]; // Here is the progress information of this file upload
The structure of the variable $_SESSION[$key] is as follows:
$_SESSION["upload_progress_test"] = array(
"start_time" => 1234567890, // Start time
"content_length" => 57343257, //Total data length of POST request
"bytes_processed" => 453489, // Received data length
"Done" = & gt; false, // whether the request is completed, and the False is not completed
// Information about a single file
"files" => array(
0 => array( ... ),
// Multiple files can be included in the same request
1 => array( ... ),
)
);In this way, we can use the two items content_length and bytes_processed to get the progress percentage.
Program Example
Now that the principle has been introduced, let’s completely implement a file upload progress bar based on PHP and Javascript.
Code repository for this sample: Github: pureweber/samples/php-upload-progress
Upload form
First, let’s write our upload form page index.php, the code is as follows:
#progress This div is used to display the progress bar.
Note: Don’t forget to add session_start() at the beginning of index.php.
Process uploaded files
The action of the form points to upload.php. We process the uploaded file in upload.php and transfer it to the current directory. There is no difference from the normal upload processing here.
move_uploaded_file($_FILES['file1']['tmp_name'], "./{$_FILES['file1']['name']}");
}
?>Ajax to get progress information
This step is the key. We need to create a progress.php file to read the progress information in the session; then we add Javascript code to index.php, initiate an Ajax request to progress.php, and then update it based on the obtained progress information. Progress bar.
session_start();
$i = ini_get('session.upload_progress.name');
$key = ini_get("session.upload_progress.prefix") . $_GET[$i];
if (!empty($_SESSION[$key])) {
$current = $_SESSION[$key]["bytes_processed"];
$total = $_SESSION[$key]["content_length"];
echo $current < $total ? ceil($current / $total * 100) : 100;
}else{
echo 100;
}
?>Here we get the progress information in the $_SESSION variable, and then output a progress percentage.
function fetch_progress(){
$.get('progress.php',{ '' : 'test'}, function(data){
var progress = parseInt(data);
$('#progress .bar').css('width', progress + '%');
setTimeout('fetch_progress()', 100);
}else{
$('#progress .label').html('Done!');
}
}, 'html');
}
$('#progress').show();
setTimeout('fetch_progress()', 100);
});
When the #upload-form is submitted, we display the progress bar, then repeatedly call fetch_progress() to obtain the progress information, and update the progress bar until the file is uploaded and 'Complete!' is displayed.
For the complete code, see: Github: pureweber/samples/php-upload-progress
Notes
The position of the input tag
The input tag with name session.upload_progress.name must be placed in front of the file input .
Cancel upload
The current upload can be canceled by setting $_SESSION[$key]['cancel_upload'] = true. However, only files that are being uploaded and files that have not yet been started can be cancelled. Files that have been successfully uploaded will not be deleted.
fetch_progress() should be called through setTimeout() to ensure that one request returns before starting the next request. If you use setInterval(), this cannot be guaranteed, and it may cause the progress bar to appear 'not forward but backward'.