08.09.2010 Ob 12:29
Menu
· Domov
· Članki
· Forum
· Skripte
· Iskanje
· Kontaktirajte me
Aktualno na forumu
Zadnje teme
· Spletna trgovina
· ENOSTAVNO ZASLUŽITI ...
· Trogon d.o.o. išče Z...
· Zastonjski streznik
· OOP - Problem z prid...
Najbolj komentirane teme
· Moja stran [114]
· Izdelava majic [ ... [81]
· upload datotek [71]
· Gostovanje Pajek.Net [68]
· Postavitev server... [60]
Najnovejši članki
· Naprednejsi regex
· Regex za zacetnike
· CakePHP framework
· Progress bar v phpju
· Postavitev spletnega...
Anketa
Vam je všeč, da smo upgrejdali portal?









Za glasovanje morate biti prijavljeni.
Izmenjava
Število uporabnikov
· Št. online gostov: 2

· Št. online članov: 0

· Vseh članov: 712
· Najnovejši član: lega
Progress bar v phpju

Kaj je progress bar?

Progress bar je prikazovanje napredka programa. Uporablja se pri programih, katerih izvajanje lahko traja dalj casa. Primer progress bara je recimo v vašem priljubljenem brskalniku, kjer kaže koliko procentov spletne strani je naloženo. Seveda pa ga nikakor ne uporabjamo le za prikaz upload-a  ali download-a, pac pa lahko povsod, kjer vemo število korakov, ki jih mora program izvesti.

Slika pove vec kot tisoc besed o tem kaj bom opisal v tem clanku...



Zakaj pa bi naredili svojega, saj ga ima že sam brskalnik?

Zato, ker brskalnik ne ve poteka izvajanja skripte.  Od strežnika dobi le podatek o velikosti strani in potem ko postopoma prenaša košcek za košckom spletne strani preracuna koliko spletne strani se je naložilo. Prav tako vcasih ko delamo z ajax-om ne zahtevamo nove strani in tako se z brskalnikovim progress barom ne dogaja nic.


Kdaj lahko in kdaj ne moremo narediti progress bara?

Lahko ga naredimo takrt ko poznamo deloto in lahko spremljamo kdaj je doloceno število korakov opravljeno. Ce recimo pomanjšujemo sliko z phpjem ne moramo spremlljati poteka izvajanja kode, kajti php nadaljuje izvajanje kode šele takrat ko je slika že pomanjšana, tako bi lahko prikazali le nic in sto procentov izvedene kode.

Primer ko pa lahko naredimo progress bar je ko imamo naprimer 100 slik in vsako pomanjšamo z phpjem. Ker je potrebno pomanjšati vsako posebej, lahko spremljamo kdaj se je en korak koncal - torej ena slika je pomanjšana. Za celoto lahko vzamemo 100 slik in vsaka slika bo tocno 1% celote.  Seveda je to prelahko da bi delovalo kot bi moralo. Vse slike se ne izvedejo enako hitro, to je namrec odvisno od števila barv, dimenzij itd. Dober rezultat lahko dobimo ce vzamemo za celoto vsota velikosti vseh slik (v bajtih) in nato del te celote predstavlja velikost posamezne slike. Torej vcasih je lahko vec nacinov kako ugotoviti kolikšen del kode (korakov) se je izvedel, seveda se pri takih situacijah odlocimo za najbolj natancno možnost.

Progress bar v PHP-ju

No, pa se lotimo izdelave progress bara v phpju. Problem ki ga opazimo je, da se spletna stran pošlje brskalniku šele ko se izvede celotna php koda, kar pomeni, da ne moremo sproti spreminjati vrednosti progress bara. Kako poslati podatke iz phpja "ven" tako da jih bo lahko brala kakšna druga skripta? Za to je vec nacinov, tukaj vam bom opisal dva, ki sem jih sam že veckrat uporabil in preizkušeno delujeta.

Primer kode, kateri bomo dodali progress bar:

<?php
for($i=1$i<2000$i++)
{
    for(
$j=1$j<1700$j++)
    {
        
$a=sin($i*$j)+cos($i/$j)+tan($i+$j);
        
$b=sin($i*$a)+cos($a/$j)+tan($i+$a);
        
$c=pow($a,$b)/cos($i-$j);
    }
}

?>


Koda za izvajanje porabi okoli 20 sekund, kar ni vec tako malo da bi kar preskocili, in morda bi bilo uporabniku prijazneje, ce bi pokazali koliko kode se je že izvedlo.

Torej kako narediti progress bar na tej kodi? Najprej moramo poznati število korakov ki se izvedejo. V našem primeru je ta številka velika - 2000*1700 = 3.400.000. V tem primeru bi en korak pomenil 1/3400000 kar je 0,000003%. Nikakor nebi bilo smotrno sporocati tako majhne spremembe, saj se taka sprememba zgodi zelo hitro - v šestih miljoninkah sekunde. Tako preracunavanje pa nebi bilo smotrno tudi zato, ker vsako preracunavanje delno upocasni kodo. Pri majhnem številu korakov se to nebi poznalo, v našem primeru pa bi se celotna koda lahko upocasnila za 5 sekund in vec kar pa vsekakor ni zanemarljivo.

Optimalno pri tej kodi je, da izracunamo napredek kode za 1% kar se zgodi vsakic, ko se spremenljivka $i poveca za 20. Kako pa bomo ugotovil da se je spremenljivka povecala za 20? Preprosto, kadar je številka deljiva z 20 - to se zgodi kadar je ostanek deljenja nic - $i%20==0.

Ce to dodamo kodi, bo izgledala takole:

<?php
for($i=1$i<2000$i++)
{
    for(
$j=1$j<1700$j++)
    {
        
$a=sin($i*$j)+cos($i/$j)+tan($i+$j);
        
$b=sin($i*$a)+cos($a/$j)+tan($i+$a);
        
$c=pow($a,$b)/cos($i-$j);
    }
    
    if(
$i%20==0$pct=round($i/2000*100);
}

?>

In napredek kode je shranjen v spremenljivki $pct... samo kaj nam to koristi ko pa tega ne moremo videti? Lahko uporabimo echo... AMPAK vse kar izpišemo z echo se izvede šele po tem ko je vsa koda že izvedena. Na sreco obstaja funkcija flush() ki pošlje vsebino brskalniku, ko se koda še vedno izvaja in tako lahko dobimo podatke iz php-ja v brskalnik.

Po tem ko to dodamo v kodo....

<?php
for($i=1$i<2000$i++)
{
    for(
$j=1$j<1700$j++)
    {
        
$a=sin($i*$j)+cos($i/$j)+tan($i+$j);
        
$b=sin($i*$a)+cos($a/$j)+tan($i+$a);
        
$c=pow($a,$b)/cos($i-$j);
    }
    
    if(
$i%20==0)
    {
        
$pct=round($i/2000*100);
        echo(
$pct."%<br>");
        
flush();
    }
}
?>

Tale koda pa ni kaj prevec prijazna uporabniku... izpiše namrec nekaj takega:

13%
14%
15%
16%
17%.....

Seveda pa se da to prav lepo spremeniti... ce uporabimo malo javascripta. Lepo je, ce se zraven pojavi tudi progress bar... to o cemer govori clanek.
No pa se lotimo dela... namesto
echo($pct."%<br>");
napišemo echo("<script>pg(".$pct.")</script>"); nato pa se lotimo pisanja  javascript funkcije  pg() ki bo spreminjala progress bar. Kratko ime funkcije sem izbral le zato, ker se na koncu nabere veliko tega v izvorni kodi kar pa ni najboljše.


Torej kako bi sploh ustvarili izgled progress bara? En div v drugem :) Prvi ima fiksno širino, v našem primeru 250 pikslov, drugemu pa se širina spreminja glede na to koliko procentov kode se je izvedlo. Da bo progress bar izgledal  "lepše" bomo drugemu divu za ozadje nastavili tole sliko: 
  No da ne bom prevec zakompliciral vsega, to dosežemo s to kodo:

<div style='padding-left:0px; width:250; height:16px; border:1px solid navy;' id='ldiv'>
<div style='padding-left:0px; padding-top:1px; position:absolute;width:250;text-align:center; font-family:verdana;font-size:12px;' id='ldiv3'>0%</div>
<div style='padding-left:0px;width:0; height:16px; background:url(progress-bar.gif);text-align:right;font-family:verdana;' id='ldiv2'>
</div>
</div>
Do konca še <span id='do_konca'>neznano</span> sekund.

ldiv - Glavni div z modro obrobo
ldiv2 - Div, ki spreminja širino in tako kaže napredek kode
ldiv3 - Div na sredini, ki z številko kaže napredek
do_konca - Span, ki kaže ocenjen preostali cas izvajanja kode

seveda lahko zgornjo kodo po želji spremenite, tako da bo izgled drugacen... samo naj bo v principu enaka. No sedaj pa javascript funkcije...

<script language='javascript'>
<!--
function pg(pct)
{
sirina=Math.floor(pct/100*25
0); //izracunamo širino glede na procente
document.getElementById('ldiv2').style.width=sirina//Nastavimo širino divu

document.getElementById('ldiv3').innerHTML=pct//Pokažemo procente z številko
}
//-->
<
/script> Tako... progress bar deluje... kaj pa racunanje preostalega casa? Hmm... Vsekakor moramo meriti cas, ki ga potrebuje koda da opravi 1%. Cas bomo merili kar z javascriptom, saj ni potrebe da bi to delal php, pa še lažje bo dostopen. Preostali cas bomo izracunali po sledecem algoritmu: - Ko se nalaganje zacne zacnemo meriti cas - Vsakic ko se procenti spremenijo izracunamo koliko casa koda potrebuje za 1% - Glede na razmerje med casom in procenti (procenti na sekundo) izracunamo cas do konca Da bo izracun casa cim bolj natancen, moramo zaceti meriti cas ko se koda zacne izvajati, tako da na zacetek kode dodamo: echo("<script>start_progress()</script>"); flush(); <script language='javascript'> <!-- cas=0//definiramo spremenljivko cas

//Funkcijo klicemo na zacetku nalaganja, da zacnemo meriti cas
function start_progress()
{
date=new Date();
cas=date.getTime();
}

function 
pg(pct)
{
sirina=Math.floor(pct/100*250); //izracunamo širino glede na procente
document.getElementById('ldiv2').style.width=sirina//Nastavimo širino divu
document.getElementById('ldiv3').innerHTML=pct//Pokažemo procente z številko


date=new Date();
razlika=date.getTime()-cas//Porabljen cas
na_sekundo=pct/razlika//Izracunamo procente na sekundo


//Deljimo s 1000 ker javascript sporoca cas v milisekundah
do_konca=Math.round((100-pct)/na_sekundo/1000); //Ocenjen cas do konca v sekundah
document.getElementById('do_konca').innerHTML=do_konca//Pokažemo cas do konca
}

//-->
<
/script> Celotno kodo primera dobite TUKAJ

Obstaja še en nacin, ki ga uporabimo takrat ko zgoraj opisanega iz takšnih ali drugacnih razlogov ne moremo.  To storimo tako, da z phpjem procente zapišemo v datoteko, te pa se nato preberejo v brskalniku z AJAX-om.

Komentarji
#1 | mtK na 30.12.2007 ob 16:22
Lepo si tole povedu Smile
#2 | amino na 04.03.2008 ob 21:36
temu se reče good work Cool
#3 | DorcH na 31.05.2008 ob 21:51
Hvala lepa! keep it up!
#4 | abadon na 16.11.2008 ob 08:23
Na žalost, sine, tale skripta ti ne more delati, ker se z bufferji in streamingom dela popolnoma drugače, kot ti to počneš; tudi v php-ju.
Npr. tvoja bo delala le v tem primeru:

Code
<?php
if (ob_get_level() == 0) {ob_start();}
echo str_pad('Skripta se izvaja... ',1024)."<br />\n";
for($i=1; $i<2000; $i++)
{
    for($j=1; $j<1700; $j++)
    {
        $a=sin($i*$j)+cos($i/$j)+tan($i+$j);
        $b=sin($i*$a)+cos($a/$j)+tan($i+$a);
        $c=pow($a,$b)/cos($i-$j);
    }

    if($i%20==0)
    {
        $pct=(round($i/2000*100)); $w = $pct/100;

#print "<img src='proBar.gif' width='$w px' height='20px'>";
print "<script>document.getElementById('procent').innerHTML=($pct)+' %'</script>";
print "<div id = 'procent'></div>";

flush(); ob_flush();
    }

}
ob_end_flush();
?>




Če hočeš pa sličico, pa naredi en gif, velik 1 x 20 pixlov in odkomentiraj ustrezen del kode.
Potem pa se igraj...
...
...
In šele čez mnogooo let napiši kaj o programiranju. Seveda, po slovensko, ali pa po angleško, le da bo berljivo in razumljivo.

PS - pa brez zamere, ampak iz tvojih člankov vidim, da nimaš kaj prida talenta za programiranje.
#5 | abadon na 16.11.2008 ob 08:25
Code
<?php
if (ob_get_level() == 0) {ob_start();}
echo str_pad('Skripta se izvaja... ',1024)."<br />\n";
for($i=1; $i<2000; $i++)
{
    for($j=1; $j<1700; $j++)
    {
        $a=sin($i*$j)+cos($i/$j)+tan($i+$j);
        $b=sin($i*$a)+cos($a/$j)+tan($i+$a);
        $c=pow($a,$b)/cos($i-$j);
    }

    if($i%20==0)
    {
        $pct=(round($i/2000*100)); $w = $pct/100;

#print "<img src='proBar.gif' width='$w px' height='20px'>";
print "<script>document.getElementById('procent').innerHTML=($pct)+' %'</script>";
print "<div id = 'procent'></div>";

flush(); ob_flush();
    }

}
ob_end_flush();
?>


#6 | Kolibri na 29.11.2008 ob 11:45
Bom to uzel kot konstruktivno kritiko, in ja, priznam da je članek daleč od popolnega.

P.S.: Če pa meniš da imaš ti večji talent, nevem zakaj ga ne pokažeš v člankih, in zanimivo je ugotavljat da najraje provokativno komentirate ravno tisti, ki še od daleč niste videli pisanja članka in časa porabljenega za to.
#7 | vojkoz na 14.12.2008 ob 13:06
Super.. sam neki me zanima kako pol za tem počisti ta progress da ga ni več na strani in prikaže vsebino?
#8 | selba na 09.11.2009 ob 18:03
#9 | lank na 07.08.2010 ob 07:50
buy gucci shoes Love your life, poor as it is. cheap gucci shoes You may perhaps have some pleasant, thrilling, cheap kamas glorious hours, even dofus kamas in a poorhouse. The kamas setting sun is reflected from the timberland shoes windows of the alms. Sq
Pošlji komentar
Za komentiranje se morate prijaviti.
Ocene
Za ocenjevanje se morate prijaviti.

Zelo dobro Zelo dobro 67% [2 ocen]
Dobro Dobro 0% [ni ocen]
Povprečno Povprečno 0% [ni ocen]
Slabo Slabo 0% [ni ocen]
Zelo slabo Zelo slabo 33% [1 ocena]
Prijava
Uporabniško ime

Geslo



Še nisi član?
Klikni tu za registracijo.

Si pozabil geslo?
Ni problema, klikni tu in dobil boš novega.
Mini klepet
Za pošiljanje sporočil morate biti prijavljeni.

24.08.2010 ob 09:25
hi all!

29.07.2010 ob 16:19
ajmo ju3 vsi na SchengenFest Grin

18.06.2010 ob 20:58
Zdravo Iščem program ali pa kodo za drop down menu, katero vstavim v php stran narejeno z DW CS4. Takšno u izi in da lahko spreminjam barvo gumbov menijev in podmenijev oziroma zamenjam barvo gu

14.06.2010 ob 18:41
tnx vsem, sem zaključil pobiranje pri 1071 popolnoma izpolnjenih anketah Smile

08.06.2010 ob 16:40
@Profesor: hvala Wink pa tut anketo sm izpolnu Wink

08.06.2010 ob 14:39
če ima kdo čas (5 minut) in bi rad izvedel tudi koliko se česa pri plačevanju uporablja na spletu bi ga prosil za izpolnitev ankete (pišem diplomo): http://bit.ly/asrv
nd

08.06.2010 ob 14:38
@kraVa: eko Smile

05.06.2010 ob 23:17
@Profesor: Da Da Da Grin...eto Wink

02.06.2010 ob 21:46
Profesor, se absolutno strinjam da je še vedno poceni, sploh za tri dni... saj pravim, če ne bi bil takrat odsoten bi se je udeležil

02.06.2010 ob 20:02
se je samo zmanjšalo iz 10 na 5. Vam je bolj všeč, če jih je 10? 3x Da (kot na Talentih) pa bo nazaj Smile

Stran sprocesirana v 0.06 sekunde 1,680,896 različnih obiskovalcev