Sebuah masalah yang telah menjangkiti pengembang web selama bertahun-tahun adalah bagaimana untuk menambahkan informasi real-time pada aplikasi mereka, seperti progress bar untuk upload file. Pengguna tidak sabar, mereka tidak ingin duduk dan menunggu sementara browser melakukan sesuatu dan bertanya-tanya apakah ia telah dibekukan atau jika mereka memiliki koneksi yang lambat. Menyediakan indikator kemajuan memberikan pengguna informasi yang berguna dan memungkinkan mereka tahu persis apa yang terjadi.

Pada pikiran pertama, Anda mungkin berpikir mencapai ini dapat dilakukan dengan mudah dengan terlebih dahulu mendapatkan ukuran file dari komputer pengguna dan kemudian melakukan beberapa perhitungan sederhana terhadap direktori pada server di mana file tersebut sedang di-upload. Setelah dipikir-pikir, Anda akan menemukan hal-hal yang tidak sesederhana itu.

JavaScript dapat mengakses nama file, jenis, dan bahkan lebar dan tinggi dari gambar lokal, tapi tidak sampai HTML5 bisa digunakan untuk mengakses ukuran file. Sayangnya, standar HTML5 masih  belum selesai dan tidak merata didukung di semua browser. Sebuah solusi alternatif adalah dengan mengandalkan Flash, Java, atau ActiveX Plugin, tidak, terima kasih, aku akan melewatinya. Namun solusi lain adalah dengan menginstal ekstensi Alternatif PHP Cache, tapi itu mungkin tidak tersedia, tergantung pada lingkungan hosting Anda dan sepertinya berlebihan untuk suatu tugas kecil seperti ini.

Ini akan tampak seolah-olah semua pilihan yang penuh dengan gangguan dan tugas dengan cepat membuat sakit kepala. Tapi dalam kata-kata Yoda, “Tidak … Ada lagi.”

Salah satu dari banyak alasan saya mencintai PHP adalah bahwa hal itu membuat tugas yang tampaknya susah menjadi gampang. Pada PHP 5.4, mereka telah melakukannya lagi dengan satu set perintah konfigurasi baru, session.upload_progress.

Dalam artikel ini saya akan menunjukkan kepada Anda bagaimana fitur ini dapat digunakan untuk membuat progress bar sederhana tanpa perpustakaan eksternal atau dependensi browser. Pertama saya akan membahas cara kerjanya, dan kemudian saya akan memandu Anda melalui penciptaan empat file yang dibutuhkan untuk menyelesaikan tugas (form upload, beberapa JavaScript, CSS sedikit, dan file untuk mengembalikan status upload).

Session Upload Progress

Selain persyaratan umum untuk memungkinkan upload file, ada dua lagi untuk melacak kemajuan. Direktif session.upload_progress.enabled harus diaktifkan dan harus ada field tersembunyi dalam form web Anda dengan nama yang ditentukan oleh direktif session.upload_progress.name. Ketika session.upload_progress.enabled bernilai true (seperti yang secara default di PHP 5.4 dan mungkin di luar) dan $ _POST [session.upload_progress.name] dikirim selama upload, informasi tentang transfer file dibuat dan tersedia dalam superglobal array $ _SESSION.

output fungsi print_r() dari array $ _SESSION  akan terlihat mirip dengan berikut ini selama transfer file:

<?php
Array
(
    [upload_progress_myForm] => Array
        (
            [start_time] => 1323733740
            [content_length] => 721127769
            [bytes_processed] => 263178326
            [done] => 
            [files] => Array
                (
                    [0] => Array
                        (
                            [field_name] => userfile
                            [name] => ubuntu-10.04.3-desktop-i386.iso
                            [tmp_name] => 
                            [error] => 0
                            [done] => 
                            [start_time] => 1323733740
                            [bytes_processed] => 263178026
                        )
                )
        )
)
?>

Ketika Anda mengembangkan baik secara lokal atau pada jaringan yang cepat dan meng-upload file kecil, Anda tidak akan dapat secara visual mengamati kemajuan karena transfer terjadi begitu cepat. Dalam hal ini, Anda mungkin ingin mencoba mentransfer file besar. Pastikan pengaturan dalam file php.ini Anda memungkinkan upload file besar, khususnya pengaturan post_max_size dan upload_max_filesize, dan kemudian memverifikasi mereka memiliki nilai-nilai yang wajar ketika berada dalam lingkungan produksi.

Membuat Form

File pertama yang akan saya sajikan adalah form upload. Hanya untuk menjaga hal-hal sesederhana mungkin, misalnya akan memposting ke dirinya sendiri dan hanya menangani satu file upload pada satu waktu. Selain itu, saya tidak akan repot-repot menyimpan file setelah di-upload.

Ini adalah kode untuk form.php:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST" && !empty($_FILES["userfile"])) {
    // move_uploaded_file()
}
?>
<html>
 <head>
  <title>File Upload Progress Bar</title>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div id="bar_blank">
   <div id="bar_color"></div>
  </div>
  <div id="status"></div>
  <form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="POST"
   id="myForm" enctype="multipart/form-data" target="hidden_iframe">
   <input type="hidden" value="myForm"
    name="<?php echo ini_get("session.upload_progress.name"); ?>">
   <input type="file" name="userfile"><br>
   <input type="submit" value="Start Upload">
  </form>

  <script type="text/javascript" src="script.js"></script>
 </body>
</html>

Dalam contoh kode untuk benar-benar memproses file tersebut telah dihilangkan untuk menjaga hal-hal tetap sederhana. Jika Anda tertarik pada apa isi kode tersebut untuk memproses file yang diupload, periksa artikel File Uploads with PHP oleh Timothy Boronczyk.

Setelah bagian kepala yang memberikan judul halaman dan termasuk stylesheet , Anda akan melihat koleksi kecil elemen div . Div dengan ID ” bar_blank ” merupakan wadah bagi progress bar . Div dengan ID ” bar_color ” akan diperbarui secara dinamis ketika file upload berlangsung . div “status ”  akan menampilkan nilai numerik persen upload .

Form diatur untuk mengirimkan isinya ke URL yang sama dan atribut target menunjuk ke elemen iframe yang tersembunyi . Mengirimkan formulir ke frame tersembunyi memungkinkan Anda untuk menjaga pengunjung pada halaman yang sama sementara pekerjaan sedang dilakukan di latar belakang. Bahkan , ini adalah praktek umum ketika melakukan ” Ajax upload file ” karena tidak mungkin untuk mengirim isi file secara langsung menggunakan objek XMLHttpRequest JavaScript.

Dalam form , field tersembunyi khusus diperlukan untuk mengisi array $ _SESSION  yang muncul, diikuti dengan masukan file upload dan tombol submit . Mengirimkan formulir akan memicu fungsi JavaScript bernama startUpload( ) yang akan ditentukan oleh file JavaScript yang disertakan .

Di bagian bawah halaman adalah frame yang tersembunyi pada formulir yang akan diproses dan impor file script.js.

Menambahkan beberapa Style

File selanjutnya, style.css, cukup lurus ke depan. Aku telah menetapkan ukuran progress bar kontainer dan memberikannya perbatasan hitam 1px, warna progress bar saat ia dimuat, dan kedua iframe dan progress bar yang tersembunyi.

#bar_blank {
  border: solid 1px #000;
  height: 20px;
  width: 300px;
}

#bar_color {
  background-color: #006666;
  height: 20px;
  width: 0px;
}

#bar_blank, #hidden_iframe {
  display: none;
}

Fungsionalitas Sisi Klien

File script.js  yang terbesar dari kelompok file. Ini berisi enam fungsi yang akan saya bahas di bawah ini. Banyak orang suka menggunakan jQuery untuk menyediakan beberapa fungsi di sini, dan Anda tentu bebas untuk melakukannya jika Anda ingin, tapi saya pribadi lebih suka pendekatan old-school. Mirip dengan bagaimana orang Jepang menempatkan nilai tinggi pada barang kerajinan tangan, saya hanya merasa lebih bergairah tentang kode jika itu adalah saya buat sendiri.

function toggleBarVisibility() {
    var e = document.getElementById("bar_blank");
    e.style.display = (e.style.display == "block") ? "none" : "block";
}

function createRequestObject() {
    var http;
    if (navigator.appName == "Microsoft Internet Explorer") {
        http = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {
        http = new XMLHttpRequest();
    }
    return http;
}

function sendRequest() {
    var http = createRequestObject();
    http.open("GET", "progress.php");
    http.onreadystatechange = function () { handleResponse(http); };
    http.send(null);
}

function handleResponse(http) {
    var response;
    if (http.readyState == 4) {
        response = http.responseText;
        document.getElementById("bar_color").style.width = response + "%";
        document.getElementById("status").innerHTML = response + "%";

        if (response < 100) {
            setTimeout("sendRequest()", 1000);
        }
        else {
            toggleBarVisibility();
            document.getElementById("status").innerHTML = "Done.";
        }
    }
}

function startUpload() {
    toggleBarVisibility();
    setTimeout("sendRequest()", 1000);
}

(function () {
    document.getElementById("myForm").onsubmit = startUpload;
})();

y

Fungsi toggleBarVisibility() mengatur style yang tepat pada div “bar_blank” untuk menampilkan atau menyembunyikan progress bar sesuai kebutuhan. Awalnya dimulai tersembunyi, namun akan ditampilkan setelah upload dimulai dan disembunyikan lagi ketika upload selesai .

Fungsi createRequestObject ()  menciptakan XMLHttpRequest atau objek ActiveXObject berdasarkan browser pengguna. Ini mungkin fungsi dimana kebanyakan orang akan melihat ke  jQuery atau kerangka JavaScript lain untuk memberikannya.

Fungsi sendRequest ()  meminta file progress.php dengan permintaan GET, dan kemudian memanggil fungsi handleResponse ()  untuk menangani data yang dikembalikan.

Fungsi handleResponse ()  menangani respon dari progress.php yang akan menjadi angka antara 1-100 tergantung pada kemajuan upload file. Saya juga memperbarui “status” div dengan nilai yang sesuai. Jika persen saat ini adalah di bawah 100 maka saya memanggil fungsi setTimeout() asli dari JavaScript  untuk mengirim permintaan lain untuk mengupdate setelah 1 detik (Anda mungkin ingin menyesuaikan nilai ini), kalau tidak aku menyembunyikan progress bar lagi dan mengatur status menjadi “Selesai.”

Fungsi startUpload ()  membuat bar upload terlihat dan mengirimkan permintaan untuk diupdate setelah penundaan dari 1 detik. Penundaan kecil ini diperlukan dalam rangka memberikan waktu agar proses upload dimulai.

Fungsi terakhir adalah fungsi anonim self-executing yang meregister startUpload () dengan menyerahkan event submit dari form.

Progress Real-Time

File terakhir yang membawa semuanya bersama-sama adalah file progress.php:

<?php
session_start();

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

Script melakukan beberapa matematika sederhana pada saat ini jumlah byte yang ditransfer dibagi dengan total ukuran file, dikalikan 100 dan dibulatkan untuk memberikan persen.

Informasi tentang transfer diperoleh dengan gabungan dari nilai direktif session.upload_progress.prefix  dan nilai field session.upload_progress.name tersembunyi itu. Karena form saya dilewatkan dengan “myForm”, kunci sesi ditentukan dengan ini_get (“session.upload_progress.prefix”). “myForm“.

Berikut adalah screenshot dari progress bar dalam aksinya:

progressbar

Fine-Tuning Perilaku

PHP menyediakan beberapa petunjuk tambahan untuk membantu menyempurnakan perilaku session upload yang sebaiknya kamu ketahui. Misalnya, session.upload_progress.cleanup , yang diatur ke 1 secara default , membersihkan data sesi tambahan segera setelah upload selesai . Anda harus berhati-hati untuk menghindari kondisi lomba potensial.

Coba lihat lagi di kode di progress.php dan Anda akan melihat bahwa saya memeriksa untuk melihat apakah $ _SESSION [ $ key ] kosong atau tidak sebelum melanjutkan . Fungsi JavaScript My menembakkan setiap detik selama hasilnya dikembalikan dari progress.php kurang dari 100. Jika session.upload_progress.cleanup diaktifkan dan script saya menjemput 99% dari upload dan 1/2-second kemudian upload selesai , $ _SESSION [ $ key ] tidak akan ada untuk dicek berikutnya. Jika saya tidak mengambil yang menjadi pertimbangan maka fungsi JavaScript saya mungkin tetap menembak, bahkan setelah upload selesai .

Dua direktif session.upload_progress.freq dan session.upload_progress.min_freq yang keduanya menentukan seberapa sering sesi harus diperbarui . Nilai freq dapat diberikan baik dalam byte (yaitu , 100 ) atau persentase total byte ( yaitu , 2 % ) . Nilai min_freq diberikan dalam hitungan detik dan menunjukkan jumlah minimum detik antara update . Tentunya jika min_freq ditetapkan untuk diupdate setiap 1 detik , maka akan ada gunanya bagi JavaScript Anda untuk memeriksanya setiap 100 milidetik .

Kesimpulan

Anda sekarang harus memiliki pemahaman yang solid tentang cara membuat progress bar untuk upload file menggunakan fitur session upload progress. Ke depan, saya mendorong Anda untuk bereksperimen dengan meng-upload beberapa file, memberikan pilihan untuk membatalkan upload yang sedang berlangsung menggunakan $ _SESSION [$ key] [“cancel_upload”], atau apa pun ide lain di pikiran Anda yang bisa anda kumpulkan. Silakan berbagi di komentar mengenai pengalaman dan perbaikan yang Anda buat agar orang lain dapat memanfaatkan dan menikmati juga!

translated from http://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/

Advertisements

About phpgeek programmer

pemimpi yang berharap menjadi the best programmer di zamannya

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s