ugrás a tartalomhoz

PHP+AJAX+JS fájl-feltöltés mérő

Velias9 · 2008. Szep. 10. (Sze), 15.14
Sziasztok!

Ez a téma már előkerül egy korábbi témán belül, de nem találtam meg, és az emlékeim szerint nem lett kidolgozva, csak, mint ötlett lett felvetve.

Az ötlet az volt, hogy a fájlt normál módon töltjük fel (pl.: iframe), aztán bizonyos időközönként kérdést küldünk a szervernek (itt jön az AJAX), hogy mekkora a fájl mérete. Ebből azt adatból és a fájl eredeti méretéből kiszámolható, hogy hol tart a feltöltés.

A problémám a következő:
- honnan tudom, hogy mi a fájl neve
- honnan tudom, hogy mekkora volt az eredeti mérete

A megvalósítás ötlete a FreeMail-ről származik. Ennyit sikerült kihámoznom belőle (nem segít sokat):
Eredeti from:
  1. <head>  
  2. <link rel="stylesheet" type="text/css" href="/gfx/popup.css" media="screen, projection" />  
  3. <meta http-equiv="Content-Script-Type" content="text/javascript" />  
  4. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />  
  5. <meta name="robots" content="all" />  
  6. <script type="text/javascript" language="JavaScript">  
  7. <!--  
  8. function kuld() {  
  9.     if (document.upload.hm.value == '') {  
  10.         alert('Hiányzó fájlnév');  
  11.         return;  
  12.     }  
  13.     parent.progress.location.href = "status.php?id=87e716b57c96f9448f103bfd0ac4f4e5";  
  14.     document.upload.submit();  
  15. }  
  16. function torol() {  
  17.     document.upload.reset();  
  18. }  
  19. //-->  
  20. </script>  
  21. </head>  
  22. <body>  
  23. <form enctype="multipart/form-data" name="upload" action="complete.php" method="post">  
  24. <input type="hidden" name="file_upload_status_uniqueid" value="87e716b57c96f9448f103bfd0ac4f4e5">  
  25. <input type="hidden" name="email" value="velias_##kukac##freemail.hu">  
  26. <img src="/gfx/freemail-logo.gif" class="logogif" alt="" />  
  27. <div id="cim"><span>Óriásfájl csatolása</span></div>  
  28. <label for="csatoltfile" class="label-ofile">Csatolt file:</label>  
  29. <input type="file" id="csatoltfile" name="hm" />  
  30. </form>  
  31. </body>  
  32. </html>  
Aztán:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="hu">  
  3. <head>  
  4.     <title>[freemail] - Óriásfájl</title>  
  5.     <link rel="Shortcut Icon" type="image/ico" href="/gfx/favicon.ico" />  
  6.     <link rel="stylesheet" type="text/css" href="/gfx/cimlap.css" media="screen, projection" />  
  7. </head>  
  8. <frameset rows="105,*" scroll="none" frameborder="0" framespacing="0">  
  9.     <frame src="upload.php?email=velias_##kukac##freemail.hu" name="upload">  
  10.     <frame src="bottom.php" name="progress">  
  11.   
  12. </frameset>  
  13. <noframes>  
  14. </noframes>  
  15. </script>  
  16. </html>  
Status.php:
  1. <head>  
  2.     <title>[freemail]</title>  
  3.     <link rel="stylesheet" type="text/css" href="/gfx/cimlap.css" media="screen, projection" />  
  4.     <meta http-equiv="Content-Script-Type" content="text/javascript" />  
  5.     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />  
  6.     <meta name="robots" content="all" />  
  7.     <meta http-equiv="Refresh" Content="1; URL=/oriaslevel/status.php?id=87e716b57c96f9448f103bfd0ac4f4e5&start_time=1221051848">  
  8. </head>  
  9. <body id="inner-body">  
  10.     <div id="popup-ablak">  
  11.     <div id="szelesseg-ofile" style="display:block;">  
  12.     <span id="allapot-ofile">Feltöltés folyamatban 5% <br /><img src="/gfx/tarhely1.gif" height="19" width="19" /><img src="/gfx/tarhely0.gif" height="19" width="336" /></span>  
  13.     <span id="baloszlop-ofile">Státusz: <br />Eltelt idő: <br />Várható befejezés:</span>  
  14.     <span id="jobboszlop-ofile">9.21&nbsp;MB/170.11&nbsp;MB (17.43&nbsp;KB/sec)<br /> 00:09:01<br /> 02:37:34</span>  
  15.     </div>  
  16.     </div>  
  17. </body>  
  18. </html>  
A forrásokon néhány sortörés kivételével nem változtattam.

A CGI, Flash és egyéb megoldások nem játszanak (egyébként ezekről is volt említés abban a témában, de nem voltak kidolgozva).

Ha valaki tudja, hogy melyik volt az a téma, akkor legyen szives a válaszában linkelje be!

Előre is köszönöm a (lehetséges) linket és a segítséget!
 
1

SESSION

Poetro · 2008. Szep. 10. (Sze), 16.09
A PHP oldalon ellenőrzöd a feltölteni kívánt fájlt ($_FILES tömb, illetve is_uploaded_file). Eltárolod SESSION-ben a file elérési útját ($_FILES['file_mezo_neve']['tmp_name']) és máris tudod ellenőrizgetni, csak sessionből kell lekérdezni az elérési utat. Mivel kettő feltöltés is futhat párhuzamosan, nem árt, ha a formod mindig kap valami egyedi azonosítót hogy tudd most akkor melyik feltöltésedről is van szó. A $_FILES['file_mezo_neve']['size'] adja vissza a fájl méretét.
Az egyetlen probléma az egésszel, hogy a PHP egészen addig nem kap vezérlést, ameddig a file nincs teljesen feltöltve, azaz a fenti út alapból járhatatlan, mivel nem állnak rendelkezésre az adatok. Ha jól emlékszem akkor létezik valamilyen PHP kiegészítés amivel a dolgot meg lehet valósítani, de a nevét nem tudom.

A Flash megoldása különbözik, a Flash ugyanis azt tudja a felhasználó mennyit töltött fel, és nem azt, mennyi érkezett meg a szerverhez, és hogy azt a szerver feldolgozta-e. Azaz a feltöltés után a Flashnek általában várakoznia kell amíg megkapja a választ, hogy a feltöltött fájlt feldolgozták, de addig is ki lehet írni, hogy feltöltés kész, feldolgozás folyamatban.

A CGI megoldás tökéletesen tudja azt amit az imént felvázoltam PHP esetén, csak itt működik is.
3

$_FILES

SamY · 2008. Szep. 11. (Cs), 07.26
PHP -ból ez a dolog azért nem ment tökéletesen sosem mert a $_FILES már csak akkor jön létre mikor feltöltődött a fájl, addig az apache hozzá sem szól a php -hoz. lehet, hogy más webszerver alatt ez máshogyan működik, de az Apache úgy tudom így csinálja. Annó találtam egy ügyeskedést ami megkeresi a tmp könyvtárban a legutolsó feltöltés alatt lévő fájlt, és annak a méretét nézegeti. Érdemes a körülnézni a "php upload progress bar" kulcsszavakra, bár nagyon sok a CGI megoldásos találat.
2

Van egy régi hackes megoldás, amiben egy (perl) cgi csak annyi

Fraki · 2008. Szep. 10. (Sze), 17.46
Van egy régi hackes megoldás, amiben egy (perl) cgi csak annyi szerepet játszott, hogy megkaptad a fájl méretét. A többi php volt.

A vezérlés először a cgi-hez ment – ugye minden iframe-be van targetolva –, ami rögtön visszaadta a fájlméretet. Ezután a kliensoldal elkezdte felküldeni a fájlt, s közben elkezdett ajaxszal pollozni egy másik szkriptet, ami nézegette a feltöltődő fájl méretét. Hogy melyik fájl méretét kell néznie, arra nem volt 100%-os az algoritmus, a rendszer temp könyvtárában keresett új phpXXXX nevű fájlt. Épp emiatt nem is volt használható több feltöltésre egy szájton, haha.

Linket erre nem tudok adni, mert a szerzője már az új módszert propagálja, arra viszont van link:

http://webreflection.blogspot.com/2007/10/upload-progress-bar-with-php5-apc-and.html
4

Flash upload?

janoszen · 2008. Szep. 11. (Cs), 08.25
Próbálkozz meg a flash filefeltöltéssel, az alapból tud progress bart és talán netről le is lehet tölteni ilyesmit, sokkal kevesebb szívás mint JS-sel hackelni, patchelgetni a PHP forrást, stb.