Rundiz / upload

PHP file upload class for single or multiple files with many validations.
http://rundiz.com/web-resources/php-upload-v2
MIT License
26 stars 9 forks source link

Progress bar/stats ? #4

Closed shubhank008 closed 5 years ago

shubhank008 commented 5 years ago

Neat and clean library.
But are any upload progress stats or a progress bar data available ?

For large file uploads, a progress bar/stats and upload speed stats become kind of necessary.

ve3 commented 5 years ago

upload progress can be implement separately.

examples:

And these are my examples that tested and work.

test1-upload-form.php

<?php

if ($_POST || $_FILES) {
    print_r($_POST);
    echo PHP_EOL;
    print_r($_FILES);
    if (isset($_FILES['my-file']['tmp_name'])) {
        $unlinkStatus = @unlink($_FILES['my-file']['tmp_name']);
        echo 'unlink status: ' . var_export($unlinkStatus, true);
    }

    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        // is ajax request.
        exit();
    }
}
?>
<!doctype html>
<html>
    <head>
        <style type="text/css">
            .debug-area {
                border: 1px dashed #ccc;
                margin: 15px 0;
                padding: 10px;
            }
        </style>
    </head>
    <body>
        <h1>Upload progress using jQuery</h1>
        <!-- reference https://stackoverflow.com/a/10811427/128761 -->

        <form id="my-form" method="post" enctype="multipart/form-data">
            <input type="hidden" name="additional-form-data" value="value of additional form data.">
            <input type="hidden" name="additional-form-data2" value="value of additional form data 2.">
            <?php /*<input id="my-php-upload-progress" type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="my-file" />*/ ?>
            <input id="my-file" type="file" name="my-file" multiple><br>
            Total file size: <span id="total-file-size"></span><br>
            Upload progress: <progress id="uploaded-progress-bar" value="0" max="100"></progress><br>
            Max file size: <?php echo ini_get('upload_max_filesize'); ?><br>
            <br>
            <button type="submit">Upload</button>
        </form>

        <div class="debug-area"></div>

        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script>
            /**
             * @link https://stackoverflow.com/a/14919494/128761 Copied from here.
             */
            function humanFileSize(bytes, si) {
                var thresh = si ? 1000 : 1024;
                if(Math.abs(bytes) < thresh) {
                    return bytes + ' B';
                }
                var units = si
                    ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
                    : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
                var u = -1;
                do {
                    bytes /= thresh;
                    ++u;
                } while(Math.abs(bytes) >= thresh && u < units.length - 1);
                return bytes.toFixed(1)+' '+units[u];
            }// humanFileSize

            function progressHandlingFunction(e) {
                if (e.lengthComputable) {
                    jQuery('#uploaded-progress-bar').attr({value: e.loaded, max: e.total});
                }
            }// progressHandlingFunction

            /**
             * Start upload
             *
             * @link https://stackoverflow.com/a/10811427/128761 Upload progress copied from here.
             * @return void
             */
            function startUpload() {
                let $ = jQuery.noConflict();
                let formData = new FormData($('#my-form')[0]);

                $('.debug-area').append('<p>Uploading...</p>');

                $.ajax({
                    'url': '<?php echo $_SERVER['REQUEST_URI'] ?>',
                    'method': 'POST',
                    'data': formData,
                    'cache': false,
                    'contentType': false,
                    'processData': false,
                    xhr: function() {
                        var myXhr = $.ajaxSettings.xhr();
                        if (myXhr.upload) { // Check if upload property exists
                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
                        }
                        return myXhr;
                    }
                })
                .always(function(jqXHR, textStatus, errorThrown) {
                    if (typeof(jqXHR) !== 'undefined' && typeof(jqXHR.responseJSON) !== 'undefined') {
                        var response = jqXHR.responseJSON;
                    } else {
                        var response = jqXHR;
                    }
                    if (typeof(response) === 'undefined' || response === '' || response === null) {
                        response = {};
                    }

                    $('.debug-area').append('<pre>' + response + '</pre>');
                    $('.debug-area').append('<hr>');
                });
            }// startUpload

            jQuery(function($) {
                $('#my-file').on('change', function(e) {
                    let thisFile = $(this)[0];
                    let totalSize = 0;
                    // copied from https://stackoverflow.com/a/9316405/128761
                    for (i = 0; i < thisFile.files.length; i++) {
                        totalSize = parseInt(totalSize) + parseInt(thisFile.files[i].size);
                    }
                    $('#total-file-size').text(humanFileSize(totalSize, true));
                });

                $('#my-form').on('submit', function(e) {
                    e.preventDefault();
                    startUpload();
                });
            });
        </script>
    </body>
</html>

.................................................
test2-upload-form.php

<?php

if ($_POST || $_FILES) {
    print_r($_POST);
    echo PHP_EOL;
    print_r($_FILES);
    if (isset($_FILES['my-file']['tmp_name'])) {
        $unlinkStatus = @unlink($_FILES['my-file']['tmp_name']);
        echo 'unlink status: ' . var_export($unlinkStatus, true);
    }

    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        // is ajax request.
        exit();
    }
}
?>
<!doctype html>
<html>
    <head>
        <style type="text/css">
            .debug-area {
                border: 1px dashed #ccc;
                margin: 15px 0;
                padding: 10px;
            }

            #hidden-iframe {
                display: none;
            }
        </style>
    </head>
    <body>
        <h1>Upload progress using hidden iframe and jQuery ajax + PHP progress</h1>
        <!-- reference https://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/ -->

        <form id="my-form" method="post" enctype="multipart/form-data" target="hidden-iframe">
            <input type="hidden" name="additional-form-data" value="value of additional form data.">
            <input type="hidden" name="additional-form-data2" value="value of additional form data 2.">
            <input id="my-php-upload-progress" type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="my-file" />
            <input id="my-file" type="file" name="my-file" multiple><br>
            Total file size: <span id="total-file-size"></span><br>
            Upload progress: <progress id="uploaded-progress-bar" value="0" max="100"></progress><br>
            Max file size: <?php echo ini_get('upload_max_filesize'); ?><br>
            <br>
            <button type="submit">Upload</button>
        </form>

        <div class="debug-area"></div>
        <iframe id="hidden-iframe" name="hidden-iframe" src="about:blank"></iframe>

        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script>
            /**
             * @link https://stackoverflow.com/a/14919494/128761 Copied from here.
             */
            function humanFileSize(bytes, si) {
                var thresh = si ? 1000 : 1024;
                if(Math.abs(bytes) < thresh) {
                    return bytes + ' B';
                }
                var units = si
                    ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
                    : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
                var u = -1;
                do {
                    bytes /= thresh;
                    ++u;
                } while(Math.abs(bytes) >= thresh && u < units.length - 1);
                return bytes.toFixed(1)+' '+units[u];
            }// humanFileSize

            function getProgress() {
                let $ = jQuery.noConflict();

                $.ajax({
                    'url': 'test2-progress.php',
                    'method': 'GET'
                })
                .always(function(jqXHR, textStatus, errorThrown) {
                    if (typeof(jqXHR) !== 'undefined' && typeof(jqXHR.responseJSON) !== 'undefined') {
                        var response = jqXHR.responseJSON;
                    } else {
                        var response = jqXHR;
                    }
                    if (typeof(response) === 'undefined' || response === '' || response === null) {
                        response = {};
                    }

                    $('#uploaded-progress-bar').val(response);
                    $('.debug-area').append('<pre>' + response + '</pre>');

                    if (response < 100) {
                        setTimeout('getProgress()', 1000);
                    } else {
                        $('.debug-area').append('Completed.<hr>');
                    }
                });
            }// getProgress

            function startUpload() {
                let $ = jQuery.noConflict();

                $('.debug-area').append('<p>Uploading...</p>');

                setTimeout('getProgress()', 1000);
            }// startUpload

            jQuery(function($) {
                $('#my-file').on('change', function(e) {
                    let thisFile = $(this)[0];
                    let totalSize = 0;
                    // copied from https://stackoverflow.com/a/9316405/128761
                    for (i = 0; i < thisFile.files.length; i++) {
                        totalSize = parseInt(totalSize) + parseInt(thisFile.files[i].size);
                    }
                    $('#total-file-size').text(humanFileSize(totalSize, true));
                });

                $('#my-form').on('submit', function(e) {
                    startUpload();
                });
            });
        </script>
    </body>
</html>

.................................................
test2-progress.php

<?php

session_start();

$key = ini_get("session.upload_progress.prefix") . "my-file";
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;
}