Failu augšupielāde ar progresa indikatoru

19.10.2008. 20:39:18 sagatavoja Deniss Fedotovs (deni2s)

Augšupielādējot failu caur HTML formu uz servera sākot ar PHP 5.2 versiju sākot ir iespējams sekot līdzi, cik daudz no faila jau ir ielādējies. Šajā rakstā aprakstīts, kā šo iespēju izmantot praktiski.

Failu augšupielādes progresa indikators

Nepieciešamās priekšzināšanas - HTML, mazliet no PHP un AJAX.

Servera sagatavošana

Sāksim ar to, ka uz servera ar PHP 5.2 ir jābūt pieinstalētam APC jeb Alternative PHP Cache.

Tālāk ir jāpārliecinās, ka ir saliktas pareizas PHP direktīvas php.ini failā (tās var aplūkot ar PHP funkciju phpinfo();):
apc.enabled=on
apc.rfc1867=on
apc.rfc1867_name=APC_UPLOAD_PROGRESS

Jāpārliecinās, kāds ir norādīts maksimālais faila izmērs, kuru var nosūtīt uz serveri ar POST pieprasījumu (šajā gadījumā - 20Mb).
file_uploads=on
post_max_size=20M
upload_max_size=20M

Gadījumā, ja skripts nedarbojas dēļ tā, ka fails augšupielādējas pārāk ilgi, ir vērts apskatīt arī direktīvas max_input_time vērtību.

Faila nosūtīšanas formas sagatavošana

Tālāk izveidojam PHP failu upload.php ar faila augšupielādes formu:
<?php
//nodefinējam unikālu identifikatoru
$id = uniqid('');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="lv" lang="lv">
<head>
<title>Faila augšupielādes forma</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="progress.js" type="text/javascript"></script>
</head>
<body>
<h1>Faila augšupielāde</h1>
<form action="post.php" method="post" enctype="multipart/form-data">
<div>
<input type="hidden" name="APC_UPLOAD_PROGRESS"
value="<?php echo($id) ?>"/>
<input type="hidden" name="MAX_FILE_SIZE" value="20971520"/>
<label for="file">Fails (max izmērs 200 MB): </label>
<input type="file" id="file" name="file"/>
<br />
<label for="apraksts">Apraksts: </label>
<input type="text" id="apraksts" name="apraksts"/>
<br />
<input type="submit" value="Nosūtīt"
onclick="apc_progress('<?php echo($id) ?>');return true;"/>
<div id="apc_progress">&nbsp;</div>
</div>
</form>
</body>
</html>

Uzreiz izstāstīšu, ko kas nozīmē šajā kodā.

HTML taga <form> atribūts enctype="multipart/form-data" norāda uz to, ka ar šīs formas palīdzību tiks sūtīts arī fails.

<input type="hidden" name="MAX_FILE_SIZE" value="20971520"/>
Ar šo rindiņu tiek norādīts, ka maksimālais sūtāmais faila izmērs ir 20971520 baiti (jeb 20 Mb). Patiesībā, pārlūkam pirms sūtīšanas būtu jāpārbauda, vai fails ir lielāks vai mazāks par norādīto izmēru, taču cik meklēju informāciju, tad vismaz Firefox 2.0 un Internet Explorer 6.0 šo iespēju neatbalsta.

<input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?php echo($id) ?>"/>
Šī rindiņa ir tā, kas atbild par faila augšupielādes progresa indikāciju. Atribūta name vērtībai jābūt tādai pašai, kā ir norādīts iekš php.ini apc.rfc1867_name vērtība. Savukārt atribūta value vērtība ir iepriekš ar PHP palīdzību izveidots unikāls identifikators, kas tiks izmantots, lai piekļūtu informācijai par augšupielādējamo failu.

Ļoti būtiski ir atcerēties, ka abām iepriekš aprakstītajām rindiņām jābūt pirms rindiņas šīs rindiņas, kura atbild par to, lai tiktu augšupielādēts fails:
<input type="file" id="file" name="file"/>

Tā kā ar POST pieprasījumu informācija tiek nosūtīta tādā secībā, kādā tā tiek norādīta, tad pretējā gadījumā serveris saņems unikālo faila augšupielādes identifikatoru tikai pēc tam, kad tiks augšupielādēts fails par visiem 100%. Citiem vārdiem sakot, tad, kad tas vairs nebūs vajadzīgs.

<input type="submit" value="Nosūtīt" 
onclick="apc_progress('<?php echo($id) ?>');return true;"/>
Te mēs norādam, ka noklikšķinot uz nosūtīšanas pogu, jāpalaiž javascript funkcija apc_progress() kurai par parametru iedodam iepriekš izveidoto faila unikālo identifikatoru. Tieši šī funkcija būs atbildīga par faila augšupielādes informācijas saņemšanu ar AJAX palīdzību.

Un visbeidzot rindiņa, kuras vietā būs redzams faila augšupielādes progresa indikators:
<div id="apc_progress"></div>

Informācijas par augšupielādējamo failu iegūšana

Izveidojam PHP failu progress.php, kurš nodrošinās AJAX ar nepieciešamo informāciju par to, cik tālu fails ar piešķirto identifikatoru ir augšupielādēts.
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s").'GMT');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
header('Content-Type: text/html; charset=utf-8');

if(isset($_GET['id']))
{
$status=apc_fetch(('upload_'.$_GET['id']));
echo('Augšupielādēti '.$status['current'].' baiti no '.$status['total'].' baitiem.');
}
?>

Kā redzams, PHP funkcija apc_fetch() ir tā, kas atgriež informāciju masīvā par augšupielādējamo failu, kamēr tas vēl tiek augšupielādēts. Par funkcijas apc_fetch() parametru tiek iedots iepriekš izveidotais faila unikālais identifikators, kuram priekšā ir pielikts prefikss upload_.

Funkcija atgriež masīvu, kura elements ['current'] ir faila pašreizējais augšupielādētais izmērs baitos, bet elements ['total'] - faila kopējais izmērs baitos.

Visa apvienošana kopā ar AJAX palīdzību

Tagad atliek to visu apvienot kopā ar AJAX palīdzību. Izveidojam failu progress.js ar šādu saturu:

//f-ja, kas palaižas nospiežot nosūtīšanas pogu
function apc_progress(nr)
{
//paņemam div elementu, kurā rādīsim progresu
var progdiv=document.getElementById('apc_progress');

//padzēšam div saturu -
//nepieciešams, ja lietotājs nospiež BACK pogu pārlūkā
progdiv.removeChild(progdiv.firstChild);

//parādam tekstu, ka notiek datu ielāde
var txt=document.createTextNode('Lūdzu uzgaidi...');
progdiv.appendChild(txt);

//pēc sekundes palaižam AJAX f-ju, kas saņems datus
setTimeout(('apc("'+nr+'");'),1000)
}

//f-ja, kas parāda saņemto augšupielādes progresu
function update_apc_status(txt2,nr)
{
//paņemam div elementu, kurā rādam progresu
var progdiv=document.getElementById('apc_progress');

//padzēšam div saturu -
progdiv.removeChild(progdiv.firstChild);

//parādam saņemto info par faila ielādes progresu
var txt=document.createTextNode(txt2);
progdiv.appendChild(txt);

//pēc 1/10 sekundes palaižam atkal AJAX f-ju,
//lai atjaunotu informāciju par failu augšupielādi
setTimeout(('apc("'+nr+'");'),100)
}

//AJAX f-ja, kas saņem informāciju no faila apc_progress.php
//par faila augšupielādes progresu
function apc(nr)
{
if (prog.readyState==4 || prog.readyState==0)
{
//nododam failam progress.php kā parametru faila unikālo identifikatoru
prog.open('GET','progress.php?id='+nr+'&rand='+Math.floor(Math.random()*1000),true);
prog.onreadystatechange=function()
{
if(prog.readyState==4)update_apc_status(prog.responseText,nr);
};
prog.send(null)
}
}

// Šī ir galvenā AJAX f-ja, kas ir diezgan sarežģīta, tāpēc
// vienkārši neaiztieciet to, bet atstājiet, kā ir.
function getHTTPObject(){
var xmlhttp;
/*@cc_on
@if (@_jscript_version >=5)
try{xmlhttp=new ActiveXObject("Msxml2.XMLHTTP")}
catch(e){
try{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")}
catch(E){xmlhttp=false}}
@else
xmlhttp=false;
@end @*/
if(!xmlhttp && typeof XMLHttpRequest!='undefined')
try{xmlhttp=new XMLHttpRequest()}
catch(e){xmlhttp=false}
return xmlhttp}

// sasaistam mainīgo prog ar austāk esošo AJAX f-ju
var prog=getHTTPObject();

Kods ir diezgan labi komentēts, tāpēc to šeit sīkāk neiztirzāšu. Ja ir kādas neskaidrības par to, kā darbojas AJAX, tad es ieteiktu izlasīt rakstu "AJAX - praktisks piemērs", kur ir diezgan sīki izskaidrots kas un kā.

Nobeigumā

Jāņem vērā, ka PHP funkcija apc_fetch() parāda nevis paša augšupielādējamā faila izmēru, bet gan visa POST pieprasījuma izmēru, līdz ar to, ja tiks vienā formā augšupielādēti vairāki faili, tad apc_fetch() funkcija rādīs informāciju par visiem failiem kopā (un papildus parametriem, kas tiek nodoti ar POST pieprasījumu). Tāpēc nebrīnieties, ka pat nosūtot formu kurā vispār nav norādīts augšupielādējamais fails, tiek uzrādīt daži baiti, kas tiek nosūtīti.

Failu augšupielādes progresa indikatorsRakstā apskatītais piemērs ir tīri izglītības mērķiem, praktiskā situācijā, protams, augšupielādējamais fails vēl ir pēc nepieciešamības jāapstrādā uz servera, kā arī progresa indikatoru var "izskaistināt" ar CSS un uzlabot.

Pārbaudīt darbībā Failu augšupielādes progresa indikātoru var te, bet lejupielādēt ZIP failā te: file-upload-progress-bar.zip.

Raksta sagatavošanā izmantotie resursi:

7 komentāri Komentēšana pieejama visiem.
Jur komentēja 21.11.2008. 20:40:03 (ip:87.110.51.190)
Komentāra reitings: 0

vai tajaa faila ir visi ir visi faili kas taja http://web.hc.lv/piemeri/file-upload-progress-bar/upload.php ?
jo man strada uploads bet nezinu kur saglaba failu un nerada progresu

Pipuks komentēja 02.02.2009. 00:15:29 (ip:82.131.27.209)
Komentāra reitings: 0

Denis, noņem apakšā xHTML un CSS validācijas ikoniņas. Nevalidējas ne viens, ne otrs. :)

d2s komentēja 26.02.2009. 02:14:55 (ip:80.233.128.162)
Komentāra reitings: 0

Taga validējas atkal ;)

jan (direktorss@inbox.lv) komentēja 16.06.2009. 20:31:42 (ip:86.163.213.231)
Komentāra reitings: 0

Man ne suuda nenotiek. Kur saglabaa failu progresu nesaada .Ai nekas te nesanaak :(

deni2s komentēja 09.08.2011. 11:00:49
Komentāra reitings: 0

http://www.phpriot.com/articles/php-ajax-file-uploads

Robicock (eleonora@domainseoforum.com) komentēja 15.01.2017. 11:14:41 (ip:146.185.223.111)
Komentāra reitings: 0

Prix Viagra Generique Amoxicillin Yogurt <a href=http://apctr50.com>levitra with dapoxetine reviews</a> Viagra Effets Immediats Amoxicillin Cause Gas Propecia Canadian Pharmacy Cialis Acquisto Forum Kamagra En France En Ligne <a href=http://drugs20.com>cialis price</a> Online Propecia Order Prednisone 10 Mg Levitra Generico In Parafarmacia <a href=http://drugsed.com>buy kamagra with american express</a> Pharmacy Prices For Levitra Zithromax Doses Order Now Dutasteride 0.5mg Real Price Fedex Shipping <a href=http://zgdkdz.com>Cheap Viagra</a> Swollen Tongue Amoxicillin Newborn Mail Order Fluoxetine Propecia Era Bueno <a href=http://qedmeds.com>viagra</a> Viagra Generika Rezeptfrei Kaufen Zithromax Overnight Kamagra Jelly Orale 10 Bustine Buy Cytotec 200mg Online Order Now Generic Stendra Mastercard Free Consultation <a href=http://shopcurerx.com>canada oil kamagra chewable</a> Overseas Pharmacy Vente De Viagra Sans Ordonnance Prix Amoxicillin 10 Acquisto Cialis Contrassegno <a href=http://asooog.com>Cheap Cialis</a> Buying Online Cialis Levitra Generic Lowest Prices Cialis Testimonianze Cheapest Price Propecia Cheap <a href=http://fra-rx.com>generic cialis</a> Cephalexin For Dogs No Perscription Buy Viagra Fast Delivery Comparatif Viagra Generique Levitra <a href=http://dolobid.net>viagra</a> Farmacia Online Can I Purchase Discount Amoxicilina Website <a href=http://ussmd.com>cialis</a> Rhine Ink Generic Propecia Prescription Zithromax Typical Dosage

Robicock (eleonora@domainseoforum.com) komentēja 06.02.2017. 16:47:21 (ip:146.185.223.111)
Komentāra reitings: 0

Cialis Wo Rezeptfrei Was Kostet Priligy Mit Rezept Buy Doxycycline Generic <a href=http://drugsor.com>filitra vardenafil tablets</a> Acheter Amoxil En Ligne Dutas Barato Cialis Tadalafil Lilly Price Of Levitra 20mg <a href=http://demalan.com>viagra</a> Achat Boite Kamagra Does Keflex Cure A Tooth Infection Vente Cialis 10mg Cephalexin 500 Mg Picture <a href=http://cure-rx.com>cialis</a> Canada Online Amoxicillian Viagra super active 100mg Forum Cialis Effetti Collaterali Acheter Du Viagra En Toute Confiance Priligy 60 Mg Une Critique <a href=http://drugslr.com>cialis buy online</a> Mail Order Cialis Canada Gentipress Viagra Controindicazioni Ou Acheter Viagra Cialis Levitra Viagra Rezeptfrei Direkt Kaufen Viagra Erfahrungsberichte Nebenwirkungen <a href=http://frigra.com>Buy Cialis</a> Acheter Finasteride Ligne Anastrozole Benefits For Men Viagra Con Cerveza Order Amoxicillin Without Prescription Direct Zentel Trichostrongyliasis In Internet With Free Shipping <a href=http://dan5325.com>viagra</a> Cialis 5mg Bestellen Purchase Viagra Without Precription Spanish 5mg Cialis Price100 Mg Brand Viagra And Cialis Viagraforsaleaustralia Cialis Viagra En France <a href=http://deantxi.com>cialis</a> Viagra Kaufen 100mg Lasix Uk <a href=http://etrobax.com>cialis buy online</a> Dose Amoxil 875 Cialis Viagra Habitamos Cephalexin Is Expired Is It Okay Isotretinoin worldwide price amex accepted online Viagra Generica Barata <a href=http://shopcurerx.com>over the counter kamagra</a> Viagra 100 Mg Best Price Cialis Prix Pharmacie Lyon Propecia E Cialis Use Of Keflex In Cats <a href=http://edrug1.com>cialis price</a> Safe Place To Buy Priligy How To Buy Provera Medication No Prescription Needed Renovables A Propecia Prix Cialis Sur Ordonnance <a href=http://exdrugs.com>generic viagra</a> Viagra Italiano Tadalafil Tablets 10 Mg Viagra Assunzione Cena Vente De Clomid Prix Levitra Selbsthilfe Ngu And Amoxicillin <a href=http://fzlaka.com>Cheap Cialis</a> Keflex Dog Dosages Dosing Keflex Oral Suspension <a href=http://oc-35.com>rollei propecia</a> Online Amoxicilina Best Website Canadian No Prescription Viagra Dutasteride France Drugs Free Consultation Express Delivery Zithromax Tab <a href=http://feldene.net>viagra</a> Amoxicillin Dose Pedriatic Priligy Bugiardino Priligy Approved Countries <a href=http://ciaolis.com>cialis online pharmacy</a> Cephalexin And Strep Throat

Komentāra pievienošana

Ar * atzīmētie lauciņi ir jāaizpilda obligāti.





[ uz rakstu sarakstu ]

Reklāma
Par web.hc.lv

web.hc.lv ir vortāls, kurā tiek aplūkoti mājaslapu veidošanas un mārketinga aspekti, no idejas līdz gandarījumam.

[Valid RSS] Valid XHTML 1.0! Valid CSS!

RSS 2.0 ziņu barotne (news feed)  Twitter

reģistrēties