圌ã®äœåã®å°ããªãã¢ãçšæããgithubã«ãœãŒã¹ãã¡ã€ã«ãããŒãžã£ãŒãé 眮ããŸããã åºæ¬çã«ã¯ã2007幎ã®1幎ãã€ãŸã5幎åã«ç§ãæžããããããœãŒã¹ããã¹ãã®å質ã¯ããã»ã©é«ããããŸããã
2002幎ã ããããã¹ãŠå§ãŸã£ãæ¹æ³ã PHPFM 1.0
å®éãç§ãæžãããšã«ããæåã®ãããžã§ã¯ãã¯ãã¡ã€ã«ãããŒãžã£ãŒã§ããã ãã®çç±ã¯éåžžã«åçŽã§ãããMySQLã®äœ¿çšæ¹æ³ã¯ããããŸããã§ãããããã¡ã€ã«ã«ã€ããŠã¯å€å°ãªããšãåŠç¿ããŸãã:)ã ãã¡ã€ã«ãããŒãžã£ãŒPHPFMãåŒã³åºãã aaãšããååã§cgi.myweb.ruã«æçš¿ããŸããã PHPFM ãããã³æåã®2æåãaãããªã¹ãã®äžçªäžã«è¿œå ããŸãã:)ã ãŸã äœããããŠã³ããŒãããããšã¯ã§ããŸãããããã®ãšã³ãŒã¯ãŸã ãããã¯ãŒã¯äžã§èŠã€ããããšãã§ããŸãããããªãŒãœãããŠã§ã¢ãã䜿çšãããµã€ãã¯ãäœããã®å埩ã§ãœãŒã¹ã³ãŒãã¢ãŒã«ã€ãã倱ã£ãããã§ãã
ãã¹ãŠãéåžžã«ç°¡åã«å®è£ ãããŸãã-ãã©ã«ããæäœããããã®åãã³ãŒãã¯æ¬¡ã®ãããªãã®ã§ããïŒ
ãŽããã³ããïŒ
// , PHP , htmlspecialchars, .. $dh = opendir($dir); while ($f = readdir($dh)) { if ($f == '.' || $f == '..') continue; $fullpath = $dir . '/' . $f; $is_dir = is_dir($fullpath); ?><tr><td><input type="checkbox" name="files[]" value="<?=$f?>" /></td><td><img src="..." /></td><td><a href="..."><?=$f?></a></td></tr><? }
ã³ãŒãã¯PHPã®å€å žçãªgovnokodã§ãããPHPãšHTMLã®ã³ãŒããæ··åãããšã¹ã±ãŒãããããPHPã§ã®åçåä»ãã®éèªæãªãšã©ãŒã¯èš±å¯ãããŸãïŒå®éããã£ã¬ã¯ããªã®èªã¿åãã¯whileïŒfalseïŒ==ïŒ$ f = readdirïŒ $ dhïŒïŒïŒ ããã以å€ã®å Žåãèªã¿åãã¯ã0ããšããååã®ãã¡ã€ã«ã§çµäºããŸãïŒã ããã«ãããããããéåžžã«ããŸãæ©èœãã0.5ç§ä»¥å ã«1,000ãã¡ã€ã«ã§ãå¿çãçæããŸããããã¬ã³ããªã³ã°ã«å€ãã®æéãããããŸããã
ãã®ãã¡ã€ã«ãããŒãžã£ãŒã«ã¯å€ãã®æ¬ ç¹ããããŸãããããã¯Web 1.0ã§ãããWebãµãŒããŒãå®è¡ããŠãããŠãŒã¶ãŒã«ãã¡ã€ã«ãžã®æžã蟌ã¿æš©éããªãå Žåãæ£ããåäœããããŸã£ããç·šéã§ããŸããã§ããã ã¡ãªã¿ã«ãããã¯å ±æãã¹ãã£ã³ã°ã®äžè¬çãªã¢ãããŒãã§ããWebãµãŒããŒãŠãŒã¶ãŒïŒwww-dataãªã©ïŒãšã¯ç°ãªããŠãŒã¶ãŒïŒyuriyãªã©ïŒããã®FTPã¢ã¯ã»ã¹ã§ãã
2003幎ã ããŒãžã§ã³2ãæ¹å
ãã¡ã€ã«ãããŒãžã£ã®æåã®ããŒãžã§ã³ãæžãæããäž»ãªçç±ã¯ããã®ãããªçšèªã¯ååšããŸããã§ãããããããWeb 2.0ãã«ããããšããç§ã®é¡æã§ããã éåžžã®Windowsãšã¯ã¹ãããŒã©ãŒã®ããã«ããã¡ã€ã«ãã¯ãªãã¯ããŠãã¡ã€ã«ãéžæããã³ã³ããã¹ãã¡ãã¥ãŒããµããŒãã§ããããã«ããããšèããŸããã ãã®ããŒãžã§ã³ã¯ãã§ã«ããã€ãã®å Žæã§ä¿åãããŠããŸã ïŒ çŽæ¥ãªã³ã¯çµç±ã§ããŠã³ããŒãã§ããŸããç»é²ããå¿ èŠã¯ãããŸããïŒã ã¡ãªã¿ã«ãïŒå°ãªããšãPHP 5.3ã§ã¯:)ããã§ãåäœããŸãããIE 6ã§ã¯ã¬ã€ã¢ãŠããšJSã匷åãããããããã¹ãŠã®æ©èœãææ°ã®ãã©ãŠã¶ãŒã§å©çšã§ããããã§ã¯ãããŸããã å®éã«ã¯ãå³ã¯ãªãã¯ã®ã³ã³ããã¹ãã¡ãã¥ãŒãéããéžæãããã¡ã€ã«ã«é¢ããæ å ±ã[詳现]ã¿ãã«è¡šç€ºããããšã«ããããŸã å¥è·¡çã«æ©èœããŸãïŒXMLHttpRequestã®ååšãäžçããŸã ç¥ããªãã£ããããiframeã§å®è£ ïŒã
以äžã«ããã£ã¬ã¯ããªãåé€ããé¢æ°ã®äŸã瀺ããŸããããã¯ãã»ãŒåããšã©ãŒã§ãåæ§ã®åœ¢åŒã§ãã¡ã€ã«ãããŒãžã£ã«ãŸã ååšããŠããŸã:)ã çŸåšã®ããŒãžã§ã³ã§ã¯ããããã®ãšã©ãŒã¯ä¿®æ£ãããŠããŸãããæåããããçŽããæçµçã«ã¯æ¬åœã«ããŸãæ©èœããæãããªã»ãã¥ãªãã£ãšã©ãŒãå«ãŸãããé©åãªæ§é ãæã€é©åãªããŒãžã§ã³ãäœæããããšãèããŠããããã§ãã
// , function removedir($dir) { $dh=opendir($dir); while ($file=readdir($dh)) { if($file!="." && $file!="..") { $fullpath=$dir."/".$file; if(!is_dir($fullpath)) { unlink($fullpath); }else { removedir($fullpath); } } } closedir($dh); if(rmdir($dir)) { return true; }else { return false; } }
ããã§ã¯å°ãªããšã3ã€ã®ããšãééã£ãŠããŸãã
1ïŒopendirã®çµæã®æ€èšŒã¯ãããŸãã
2ïŒã·ã³ããªãã¯ãªã³ã¯ã®ãã§ãã¯ã¯ãããŸããïŒãã£ã¬ã¯ããªã«ã/ããžã®ã·ã³ããªãã¯ãªã³ã¯ãããå Žåãååãªæš©éãããéããé¢æ°ã¯ã«ãŒããã¡ã€ã«ã·ã¹ãã ãååž°çã«åé€ãå§ããŸã:)ïŒ
3ïŒç¡å¹ãªãã£ã¬ã¯ããªèªã¿åãã³ãŒãïŒé¢æ°ã¯ã0ããšããååã®ãã¡ã€ã«ã§åæ¢ããŸã
2004-2005幎ã 3çªç®ã®ããŒãžã§ã³ãäœæããããšããŸã
ãWindows 2.0ãã®ã¢ã€ãã¢ããšãŠãæ°ã«å ¥ã£ãã®ã§ããã®Windowsãšã¯ã¹ãããŒã©ã®ããã«ããã¬ãŒã ã§ãã¹ãŠãå®è¡ããæçµçã«ãªã¹ãã§ã¯ãªããã¢ã€ã³ã³ããè¿œå ããããšã«ããŸããã å®éããšã¯ã¹ãããŒã©ãŒã®åäœã®å€§éšåãã³ããŒããåŸãJavaScriptã³ãŒããéåžžã«æ··ä¹±ãã絶察ã«ãµããŒãã§ããŸããã§ãã:)ã
ããã«ç§ããã©ãŒã©ã ã§æžãããã®ããããŸãã
ã¡ãã»ãŒãžæ¬æ
玳士ãç§ã¯ãŸãïŒãã¹ãŠã®æéãç¥ããŸããã§ãã...ïŒãã¹ãŠã®é¡ããèæ
®ã«å
¥ããããšã«ããŸãã...ãããŠããã¬ãŒã äžã«æ°ããPhpFM 3.0ãäœæããŸãïŒãšã¯ã¹ãããŒã©ã®ç»åã§ïŒã +ããã«ããã¥ãŒã®ãµããŒãããªã¹ãã ãã§ãªããã¢ã€ã³ã³ã®åœ¢åŒã§ããµããŒãããŸãã çŸåšéçºäžã®ããŒãžã§ã³ã¯éåžžã«å°é£ã§ãããã¯ãã¹ãã©ãŠã¶ãŒJavaScriptïŒã€ãŸããOperaïŒããŠã¹ã®å³ãã¿ã³ã§ã®ã¯ãªãã¯ã®ã€ã³ã¿ãŒã»ãããæå¹ã«ããããã«å¿
èŠãªJavaScriptèšå®ïŒïŒãMozillaãããã³IEã§åäœããŸãã ãããŸã§ã®éçºæ®µéã§ã¯ã次ã®ããšãè¡ãããŠããŸãã
1ïŒãã¬ãŒã æ§é ããŽã èšèšïŒ
2ïŒã¢ãã¬ã¹ããŒïŒãé·ç§»ããã¿ã³ã¯è£ 食çã§ãïŒïŒãããŠããã¢ããããã¿ã³ã¯äžéšãã¬ãŒã ã§æ©èœããŸã
3ïŒå·ŠåŽã®ãã¬ãŒã ã§ãããã©ã«ããŒãã¢ãŒããæå¹ã«ãªã£ãŠãããšã¯ã¹ãããŒã©ãŒã®ããã«è¡šç€ºããŸãã JSHTTPRequestã§ã¯æ©èœããŸãããïŒããã«åºã¥ããŠããçŽãäºå®ã§ã-éåžžã«äŸ¿å©ãªããšã§ãïŒããã¹ãŠã®ãã©ã«ããŒãåçã«ïŒé衚瀺ã®IFRAMEã䜿çšããŠïŒéãããŸãã ãã©ã«ãã®æãããã¿ãšæãããã¿ã¯æ©èœããŸã-ã³ã³ããã¹ãã¡ãã¥ãŒã¯ãããŸããïŒ
4ïŒã¢ã€ã³ã³ã®åœ¢åŒã®ã¡ã€ã³ãã¬ãŒã ïŒååãšããŠãªã¹ãã®åœ¢åŒã§ããããŸãããç¹å¥ãªãã®ã§ã¯ãããŸããïŒãjavascriptã§æç»ããããã¬ãŒã ã®ãµã€ãºãå€æŽãããšãããŒãžããªããŒãããã«ã³ã³ãã³ããåæç»ãããŸãã ãã¡ã€ã«éžæã¯ããŠã¹ã§æ©èœããŸãïŒãããŸã§ã¯è€æ°éžæã¯ãããã°ãããŠããŸããïŒããã°ããããŠãã¡ã€ã«ã«ã«ãŒãœã«ãåããããšããã¡ã€ã«æ å ±ãå«ãã¿ã€ãã«ããããã¢ããããŸãïŒä»¥åã¯ãã©ã«ããŒã§ãè¡ãããŠããŸããïŒã é·ãããååã¯åãæšãŠãããŸãããã¡ã€ã«ãŸãã¯ãã©ã«ããŒãã¯ãªãã¯ãããšããã®ååã¯ãã«ãµã€ãºã«åŸ©å ãããŸãïŒãã ããæ¹è¡ã¯ãããŸããïŒã ãã¡ã€ã«ãŸãã¯ãã©ã«ããŒã2åã¯ãªãã¯ãããå Žåã«ãã©ã«ããŒãããã«ã¯ãªãã¯ãããšããŠã£ã³ããŠãéãããã¡ã€ã«ã®ååãå€æŽãããŸãïŒ<input type = text ...ã®ä»£ããã«äœ¿çšããããšã¯ã§ããŸããã§ããïŒã ãã¡ã€ã«ãšãã©ã«ããŒã®å Žåãã³ã³ããã¹ãã¡ãã¥ãŒãæ©èœããŸãã ãããŸã§ã®ãšãããããã«å€ãã®ãã®ãå®è£ ãããŠããŸãããå°ãªããšãã¢ã€ãã¢ãè©äŸ¡ããŠãã ããã
ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã¢ãã¬ã¹ïŒ<æ®å¿µãªãããé皌åã¢ãã¬ã¹>ããã¹ã¯ãŒããèŠã€ããããã«LANãäœæãããã¹ã¯ãŒããéä¿¡ããŸãïŒäºé²æªçœ®ïŒã
1ïŒãã¬ãŒã æ§é ããŽã èšèšïŒ
2ïŒã¢ãã¬ã¹ããŒïŒãé·ç§»ããã¿ã³ã¯è£ 食çã§ãïŒïŒãããŠããã¢ããããã¿ã³ã¯äžéšãã¬ãŒã ã§æ©èœããŸã
3ïŒå·ŠåŽã®ãã¬ãŒã ã§ãããã©ã«ããŒãã¢ãŒããæå¹ã«ãªã£ãŠãããšã¯ã¹ãããŒã©ãŒã®ããã«è¡šç€ºããŸãã JSHTTPRequestã§ã¯æ©èœããŸãããïŒããã«åºã¥ããŠããçŽãäºå®ã§ã-éåžžã«äŸ¿å©ãªããšã§ãïŒããã¹ãŠã®ãã©ã«ããŒãåçã«ïŒé衚瀺ã®IFRAMEã䜿çšããŠïŒéãããŸãã ãã©ã«ãã®æãããã¿ãšæãããã¿ã¯æ©èœããŸã-ã³ã³ããã¹ãã¡ãã¥ãŒã¯ãããŸããïŒ
4ïŒã¢ã€ã³ã³ã®åœ¢åŒã®ã¡ã€ã³ãã¬ãŒã ïŒååãšããŠãªã¹ãã®åœ¢åŒã§ããããŸãããç¹å¥ãªãã®ã§ã¯ãããŸããïŒãjavascriptã§æç»ããããã¬ãŒã ã®ãµã€ãºãå€æŽãããšãããŒãžããªããŒãããã«ã³ã³ãã³ããåæç»ãããŸãã ãã¡ã€ã«éžæã¯ããŠã¹ã§æ©èœããŸãïŒãããŸã§ã¯è€æ°éžæã¯ãããã°ãããŠããŸããïŒããã°ããããŠãã¡ã€ã«ã«ã«ãŒãœã«ãåããããšããã¡ã€ã«æ å ±ãå«ãã¿ã€ãã«ããããã¢ããããŸãïŒä»¥åã¯ãã©ã«ããŒã§ãè¡ãããŠããŸããïŒã é·ãããååã¯åãæšãŠãããŸãããã¡ã€ã«ãŸãã¯ãã©ã«ããŒãã¯ãªãã¯ãããšããã®ååã¯ãã«ãµã€ãºã«åŸ©å ãããŸãïŒãã ããæ¹è¡ã¯ãããŸããïŒã ãã¡ã€ã«ãŸãã¯ãã©ã«ããŒã2åã¯ãªãã¯ãããå Žåã«ãã©ã«ããŒãããã«ã¯ãªãã¯ãããšããŠã£ã³ããŠãéãããã¡ã€ã«ã®ååãå€æŽãããŸãïŒ<input type = text ...ã®ä»£ããã«äœ¿çšããããšã¯ã§ããŸããã§ããïŒã ãã¡ã€ã«ãšãã©ã«ããŒã®å Žåãã³ã³ããã¹ãã¡ãã¥ãŒãæ©èœããŸãã ãããŸã§ã®ãšãããããã«å€ãã®ãã®ãå®è£ ãããŠããŸãããå°ãªããšãã¢ã€ãã¢ãè©äŸ¡ããŠãã ããã
ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã¢ãã¬ã¹ïŒ<æ®å¿µãªãããé皌åã¢ãã¬ã¹>ããã¹ã¯ãŒããèŠã€ããããã«LANãäœæãããã¹ã¯ãŒããéä¿¡ããŸãïŒäºé²æªçœ®ïŒã
2006幎ã ã€ã«ã«ïŒDolphin.phpïŒ
ãã°ããããŠããã§ã«å€ããå°ãªããçµéšãç©ãã§ããããšã«æ°ã¥ãïŒãããŠJavaScriptã§äœããç解ãå§ããŸããïŒãä»ã§ã¯ãç§ã倢èŠãŠããããšãåŠçã§ããããã«ãªããŸããã ïŒ ãã®ããŒãžã§ã³ã®ã¹ã¯ãªãŒã³ã·ã§ããã®1ã€ã次ã«ç€ºããŸãã
ã¡ãã¥ãŒé ç®ã¯è£ 食çã§ãããããã¿ã³ã¯ãæ»ããããé²ãããªã©ã§ãã Webäžã§è¡ãã®ãçã«ããªã£ãŠããã®ãšåãããããšã¯ã¹ãããŒã©ãŒã®è¿ãã§ã¢ãã¡ãŒã·ã§ã³åãããã¹ãã«ãã©ãã ããã£ãããããããŸããã å®éãç§ãæŸæ£ããPHPFM 3.0ã§ããããšã¯ã¹ãããŒã©ãŒãšåãããã«æ©èœãã誰ããããããå®æãããïŒäžè¶³ããŠããæ©èœããæ£åžžã«æ©èœãããã¬ãã«ã«è¿œå ãïŒãããæœèšã§ãã¡ã€ã«ãã¹ãã£ã³ã°ãµãŒãã¹ãšããŠã€ã³ã¹ããŒã«ããŸããã 誰ãã以åã®ããŒãžã§ã³ã®PHPFMãã¢ã«ãŠã³ãã£ã³ã°ã®ãã¡ã€ã«ãšã€ããšããŠããŒã«ã«ãããã¯ãŒã¯ã«ã€ã³ã¹ããŒã«ããŸããããã¹ãŠãExplorerã«éåžžã«ãã䌌ãŠããŠã人ã ãããã²ãŒãããã®ãéåžžã«ç°¡åã ã£ãããã§ãã
2007幎 ãã€ã¯ããœããã®ã³ããŒã©ã€ã¿ãŒã®åå¿ã®æãã«ãããã¶ã€ã³ã®å€æŽ:)
2006幎ãã2007幎ã«ãããŠãã€ã«ã«ããç©æ¥µçã«éçºããŠããŸããããããæç¹ã§ä»ã®äººã®ãã¶ã€ã³ãã³ããŒããã®ã¯è¯ããªãããšããããŠãšã¯ã¹ãããŒã©ãŒããã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ãåãç¶ãããšçè«çã«ã¯èäœæš©ãç§ãæ»æããããšã«æ°ä»ããŸãã:)ã ãã®ããããã¶ã€ã³ãå€æŽããããšã«ããŸããããã®çµæããã¡ã€ã«ãããŒãžã£ãŒã¯æªå®æã®ç¶æ ã®ãŸãŸã§ãããã®å€æŽã«é¢é£ãããã¹ãŠã®ãã°ãå®å šã«ãã£ããã§ããªãã£ãããã§ãã å®éãç§ã¯ãããããŸãããŸããã§ããã
ããã§ããã¡ã€ã«ãããŒãžã£ã¯æ¬¡ã®ããã«ãªããŸãã
ããã©ãŒãã³ã¹ã®æé©å
ç§ã¯æ£çŽãçç£æ§ãéèŠãã人ã ã®ã«ããŽãªãŒã«å±ããŠããŸãã ãã¹ãŠãè¿ éã«æ©èœãããšãã¯æ¬åœã«æ°ã«å ¥ã£ãŠããŸãããã¡ã€ã«ãããŒãžã£ãŒã«ãšã£ãŠã¯ãäœæ¥ãé«éåããããã®æ°ããæ¹æ³ãåžžã«èæ¡ããããšããŸããã ç§ãã¹ããŒãã¢ãããããã£ãäž»ãªããšã¯ããã¡ã€ã«ãªã¹ããéãããšã§ãã-ãã¡ã€ã«ãããŒãžã£ã§æãäžè¬çã«äœ¿çšãããæ©èœã§ãã ããã«ç§ãæãã€ããä»äºã®é床ãäžããããã®ããã€ãã®ã¢ã€ãã¢ããããŸãïŒ
1.ãã£ã¬ã¯ããªèªã¿åããµã€ã¯ã«ã§å®è¡ãããæäœã®æ°ãæå°éã«æãã
説æ
ã³ãŒãïŒ
50,000ãã¡ã€ã«ã®ãã©ã«ããŒã§ã®ããã©ãŒãã³ã¹è©äŸ¡ïŒ
<?php function d_filelist_fast($dir) { setreadable($dir,true); if(!(@$dh=opendir($dir)) && !(@$ftp_list=d_ftplist($dir))) return false; if($dh) { $dirs = $files = $fsizes = array(); /* chdir($dir); */ while(false!==(@$file=readdir($dh))) { if($file=='.' || $file=='..') continue; if(is_dir($dir.'/'.$file)) $dirs[]=$dir.'/'.$file; else $files[]=$dir.'/'.$file; $fsizes[$dir.'/'.$file] = filesize($dir.'/'.$file); } closedir($dh); }else return $ftp_list; return array('dirs'=>$dirs,'files'=>$files,'fsizes'=>$fsizes); }
50,000ãã¡ã€ã«ã®ãã©ã«ããŒã§ã®ããã©ãŒãã³ã¹è©äŸ¡ïŒ
488 msçæ
33.51 Mbã¡ã¢ãª
gzipã§246 KBïŒããŠã³ããŒãããšã«+ 500ããªç§ïŒ
ãã©ãŠã¶ã§305ããªç§
= 1300ããªç§
+ããŒã¿ã®ããŠã³ããŒããªãïŒäžè¬ïŒ
-æãé ããªãã·ã§ã³
-倧éã®ã¡ã¢ãªãå¿ èŠ
2. Windowsã§i386ãã©ã«ããŒãéããšãã®ããã©ãŒãã³ã¹åæã«ãããWindowsã§statïŒïŒãåŒã³åºãããšã¯éåžžã«é«äŸ¡ãªæäœã§ããããšãæããã«ãªããŸããã çµæãããŒãžã«åå²ããçŸåšã®ããŒãžã®ãã¡ã€ã«ã«å¯ŸããŠã®ã¿statïŒïŒãåŒã³åºããšãå€ããç¯çŽã§ããŸãã ãŸããããªã³ã¶ãã©ã€ãã§ã³ãŒããçæãããããevalã«æž¡ãããšã§ãããããç¯çŽããããšããŸããããã®ãããã³ãŒãã¯éåžžã«è€éã§ããããéåžžã«é«éã§ããã
説æ
ã³ãŒãïŒ
ããã©ãŒãã³ã¹åæïŒ
/* extremely complicated :), extremely fast (on huge directories) and extremely customizable sorted filelist :) $dir -- directory from which to get filelist $params -- array with optional parameters (see beginning of function for details) RETURN: array( 'pages' => array( $pagemin => array( 'files' => array('field1' => $list1, ..., 'fieldN' => $listN), 'dirs' => ... (array of the same format) ), ... (the intermediate pages) $pagemax => array( 'files' => ..., 'dirs' => ... ) ), 'pages_num' => ..., 'items_num' => ... ) where field1, ..., fieldN -- requested fields (default 'name' and 'size') $list1, ..., $listN -- a list of values (array('value1', 'value2', ...,'valueN')), $pagemin and $pagemax -- the page numbers of the specified range (default 1) pages_num -- filtered number of pages (returns 1 if you do not ask not to split to pages) items_num -- filtered number of files + total number of folders EXAMPLE: $res = d_filelist_exteme('/home/yourock'); print_r($res); this will result in: Array ( [pages] => Array ( [1] => Array ( [files] => Array ( [name] => Array ( [0] => file1 [1] => file3 [2] => file20 ) [size] => Array ( [0] => 1000 [1] => 2000 [2] => 300000 ) ) [dirs] => Array ( [name] => Array ( [0] => dir1 ) [size] => Array ( [0] => 512 ) ) ) ) [pages_num] => 1 [items_num] => 4 ) */ /* TODO: move it to config.php in some time */ define('LIGHT_PERPAGE', 30); function d_filelist_extreme($dir, $params=array()) { /* set defaults: $key = ''; is equal to default value for $params['key'] */ $fields = array('name', 'size'); // name, chmod or any field of stat(): (size, mtime, uid, gid, ...) $filt=''; // filename filter $sort='name'; // what field to sort (see $fields) $order='asc'; // sorting order: "asc" (ascending) or "desc" (descending) $fast=true; // use some optimizations (eg can allow to get some range from a filelist of 5000 files in 0.1 sec) $maxit=defined('JS_MAX_ITEMS') ? JS_MAX_ITEMS : 200; // how many items is enough to enable optimization? $split=true; // split result to pages and return only results for pages from $pagemin to $pagemax (including both) $pagemin=1; $pagemax=1; // see description for $split $perpage=LIGHT_PERPAGE; // how many files per page $ftp=true; // try to get filelist through FTP also (can affect performance) /* read parameters, overwriting default values */ extract($params,EXTR_OVERWRITE); if($sort!='name') { /*return d_error('Not supported yet');*/ $fast = false; if(array_search('mode', $fields) === false) $fields[] = 'mode'; } if($pagemax < $pagemin) $pagemax = $pagemin; if(array_search($sort, $fields)===false) $fields[] = $sort; if($order != 'asc') $order = 'desc'; $filt = strtolower($filt); /* check required fields */ $st = stat(__FILE__); foreach($fields as $k=>$v) { if($v == 'name' || $v=='chmod') continue; if(!isset($st[$v])) { $keys = array_filter(array_keys($st), 'is_string'); return d_error('Unknown field: '.$v.'. Use the following: name, chmod, '.implode(', ', $keys)); } } setreadable($dir, true); if(!@$dh = opendir($dir)) { if(!$ftp) return d_error('Directory not readable'); if(!@$ftp_list=d_ftplist($dir)) return d_error('Directory not readable'); } if($dh) { $it = array(); /* items */ if(!$filt) { while(false!==(@$f=readdir($dh))) { if($f=='.' || $f=='..') continue; $it[] = $f; } }else { while(false!==(@$f=readdir($dh))) { if($f=='.' || $f=='..') continue; if(strpos(strtolower($f),$filt)!==false) $it[] = $f; } } closedir($dh); if(!$split) $perpage = sizeof($it); $old_dir = getcwd(); chdir($dir); $l = sizeof($it); if($l < $maxit) $fast = false; /* $fast means do not sort "folders first" */ if($fast) /* $sort = 'name' and $split = true */ { if($order=='asc') sort($it); else rsort($it); }else { $dirs = $files = array(); if($sort=='name') { for($i = 0; $i < $l; $i++) { if(is_dir($it[$i])) $dirs[] = $it[$i]; else $files[] = $it[$i]; } if($order=='asc') { sort($dirs); sort($files); $it = array_merge($dirs, $files); }else { rsort($files); rsort($dirs); $it = array_merge($files, $dirs); } } } /* array_display($it); */ $res = array('pages_num' => ceil($l / $perpage), 'items_num' => $l); $all = $pages = array(); /* fix invalid page range, if it is required */ if($pagemin > $res['pages_num']) { $pagemin = //max(1, $pagemin + ($pagemax - $res['pages_num']) ); $pagemax = $res['pages_num']; } $cd = $cf = $ci = ''; /* Code for Directories, Code for Files and Code for Items */ foreach($fields as $v) { $t = '[\''.$v.'\'][] = '; if ($v == 'name') $t .= '$n'; else if ($v == 'chmod') $t .= 'decoct($s[\'mode\'] & 0777)'; else $t .= '$s[\''.$v.'\']'; if($sort == 'name') { $cd .= '$pages[$page][\'dirs\']'.$t.";\n"; $cf .= '$pages[$page][\'files\']'.$t.";\n"; }else { $ci .= '$all'.$t.";\n"; } } /* we cannot optimize sorting, if sorted field is not name: we will have to call expensive stat() for every file, not only $perpage files. */ if($sort == 'name') { eval(' for($i = 0; $i < '.$l.'; $i++) { $page = floor($i / '.$perpage.') + 1; if( $page < '.$pagemin.' || $page > '.$pagemax.' ) continue; $n = $it[$i]; $s = stat($n); // is a directory? if(($s[\'mode\'] & 0x4000) == 0x4000) { '.$cd.' }else { '.$cf.' } } '); } if($sort!='name') { eval(' for($i = 0; $i < '.$l.'; $i++) { $n = $it[$i]; $s = stat($n); '.$ci.' } '); $code = 'array_multisort($all[\''.$sort.'\'], SORT_NUMERIC, SORT_'.strtoupper($order); foreach($fields as $v) { if($v != $sort) $code .= ', $all[\''.$v.'\']'; } $code .= ');'; /* code is evalled to prevent games with links to arrays */ eval($code); $pages = array(); $cf = $cd = ''; foreach($fields as $k => $v) { $cf .= '$pages[$page][\'files\'][\''.$v.'\'][] = $all[\''.$v.'\'][$i];'; $cd .= '$pages[$page][\'dirs\'][\''.$v.'\'][] = $all[\''.$v.'\'][$i];'; } eval(' for($i = 0; $i < $l; $i++) { $page = floor($i / '.$perpage.') + 1; if( $page < '.$pagemin.' || $page > '.$pagemax.' ) continue; if(($all[\'mode\'][$i] & 0x4000) == 0x4000) { '.$cd.' }else { '.$cf.' } } '); } if($res) $res['pages'] = $pages; chdir($old_dir); return $res; }else { extract($ftp_list); if($fields !== array('name', 'size') || $sort!='name') return d_error('Custom fields and sorting not by name are not currently supported in FTP mode'); $files = array_map('basename', $files); $dirs = array_map('basename', $dirs); $fl = sizeof($files); $dl = sizeof($dirs); if($filt) { $files_c = $dirs_c = array(); for($i=0; $i<$fl; $i++) if(strpos(strtolower($files[$i]),$filt)!==false) $files_c[]=$files[$i]; for($i=0; $i<$dl; $i++) if(strpos(strtolower($dirs[$i]),$filt)!==false) $dirs_c[]=$dirs[$i]; $dirs = $dirs_c; $files = $files_c; $fl = sizeof($files); $dl = sizeof($dirs); } if(!$split) $perpage = $fl + $dl; $pages = array(); for($i=0,$arr='files'; $arr=='files'||$i<$dl; $i++) { if($arr=='files' && $i>=$fl) { $arr='dirs'; $i=0; } $page = floor($i / $perpage) + 1; if( $page < $pagemin || $page > $pagemax ) continue; $pages[$page][$arr]['name'][] = ${$arr}[$i]; $pages[$page][$arr]['size'][] = @$fsizes[$dir.'/'.${$arr}[$i]]; } return array('items_num' => ($fl+$dl), 'pages_num' => ceil(($fl+$dl) / $perpage), 'pages' => $pages); } }
ããã©ãŒãã³ã¹åæïŒ
169ããªç§ã®çæ
13.48 Mbã¡ã¢ãª
2 kbããgzip
ãã©ãŠã¶ã§ã®ãªã¯ãšã¹ãããšã«7ããªç§
= 200ããªç§
+ã¯ã€ãã¯ã¹ã¿ãŒã
-倧éã®ã¡ã¢ãªãå¿ èŠ
-é·ããŠãªãœãŒã¹ã倧éã«æ¶è²»ããããŒã¿ã®èªã¿èŸŒã¿ïŒãã©ã«ããŒã®åã¹ãã£ã³
3.次ã®æé©åã®ã¢ã€ãã¢ã¯ãDBMSãæžãããšãã«é ã«æµ®ãã³ãŸãããDBMSã«ã€ããŠã¯ãHabréã§æ¢ã«èª¬æããŸããïŒã¯ããããã¯ç§ã§ã:)ïŒã åã®ã¡ã«ããºã ã¯åé¡ãããŸããã§ããããããŒãžããŒã·ã§ã³ãè¡ãå¿ èŠããããããŒãžããšã«ãã£ã¬ã¯ããªãå床ãã€ãã¹ããå¿ èŠããããŸããã ãããã£ãŠãããšãã°ããã¡ã€ã«ç¯å²ããã°ããéžæã§ããããã«ãã£ã¬ã¯ããªæ§é ããã£ãã·ã¥ããã³ãŒããäœæãã1000ãã1100ã®ãã¡ã€ã«ããã°ããååŸã§ããããã«ããããšã«ããŸããã
説æ
ããã©ãŒãã³ã¹åæïŒ
/* the cached version of filelist especially made for JS GGGR returns: array( 'items' => array( start: array( 'name' => ..., 'size' => ..., 'is_dir' => true|false, ), ... start+length-1: array( 'name' => ..., 'size' => ..., 'is_dir' => true|false, ), ), 'cnt' => N ) */ function d_filelist_cached($dir, $start, $length, $filter = '') { //sleep(1); $tmpdir = is_callable('get_tmp_dir') ? get_tmp_dir() : '/tmp'; $cache_prefix = $tmpdir.'/dolphin'.md5(__FILE__); $cache_dat = $cache_prefix.'.dat'; $cache_idx = $cache_prefix.'.idx'; $new = false; if(!file_exists($cache_dat) || filemtime($dir) > filemtime($cache_dat)) { $new = true; $fp = fopen($cache_dat, 'w+b'); $ifp = fopen($cache_idx, 'w+b'); }else { $fp = fopen($cache_dat, 'r+b'); $ifp = fopen($cache_idx, 'r+b'); list(, $l) = unpack('n', fread($fp, 2)); $cached_dir = fread($fp, $l); list(, $l) = unpack('n', fread($fp, 2)); $cached_filter = fread($fp, $l); if($cached_dir != $dir || $cached_filter != $filter) { ftruncate($fp, 0); ftruncate($ifp, 0); fseek($fp, 0, SEEK_SET); fseek($ifp, 0, SEEK_SET); $new = true; } } $items = array(); $cnt = 0; $old_cwd = getcwd(); try { if(!@chdir($dir)) throw new Exception('Could not chdir to the folder'); if($new) { fwrite($fp, pack('n', strlen($dir)).$dir); fwrite($fp, pack('n', strlen($filter)).$filter); $pos = ftell($fp); $dh = opendir('.'); if(!$dh) throw new Exception('Could not open directory for reading'); $filter = strtolower($filter); while( false !== ($f = readdir($dh)) ) { if($f == '.' || $f == '..') continue; if(strlen($filter) && !substr_count(strtolower($f), $filter)) continue; fwrite($ifp, pack('NN', $pos, strlen($f))); fwrite($fp, $f); $pos += strlen($f); // ftell is not as fast as it should be, sadly } fflush($ifp); fflush($fp); } fseek($ifp, $start * 8 /* length(pack('NN')) */); $first = true; $curr_idx = $start; while( $curr_idx < $start + $length ) { list(, $pos, $l) = unpack('N2', fread($ifp, 8)); if($first) { fseek($fp, $pos); $first = false; } $f = fread($fp, $l); if(!strlen($f)) break; if(strlen($f) != $l) { throw new Exception('Consistency error'); } $items[$curr_idx++] = array( 'name' => $f, 'size' => filesize($f), 'is_dir' => is_dir($f), ); } $cnt = filesize($cache_idx) / 8; }catch(Exception $e) { fclose($fp); fclose($ifp); unlink($cache_dat); unlink($cache_idx); @chdir($old_cwd); return is_callable('d_error') ? d_error($e->getMessage()) : false; } if($cnt < 500 && $length >= 500) { usort($items, 'd_filelist_cached_usort_cmp'); } @chdir($old_cwd); return array( 'items' => $items, 'cnt' => $cnt ); } function d_filelist_cached_usort_cmp($it1, $it2) { return strcmp( $it1['name'], $it2['name'] ); }
ããã©ãŒãã³ã¹åæïŒ
460ããªç§ã®çæ
1.18 Mbã¡ã¢ãª
2 kbããgzip
ãã©ãŠã¶ãŒã§ã®èŠæ±ããšã«8ããªç§
= 500ããªç§
+ç°¡åã§é«éãªããŒã
+ã¯å€ãã®ã¡ã¢ãªãå¿ èŠãšããŸãã
-ã¹ããŒã¹ã¿ãŒã
-ããªãã®ãµã€ãºã®äžéãã¡ã€ã«ã®ä¿åïŒãã£ã¬ã¯ããªãã¡ã€ã«ãµã€ãº1.6 MBã§50,000ãã¡ã€ã«ããã800 KBïŒ
4.äžèšã®ã³ãŒããèªããšãããããæåã¯ã³ãŒããéåžžã«åçŽã§ããããšã«æ°ã¥ãããã®åŸãéåžžã«è€éã«ãªãïŒä¿å®ãäžå¯èœãªã»ã©ïŒãç°¡åã«ãªããŸãã...ãããŠãã¡ãããæãåçŽãªã¢ã€ãã¢ãã©ããããããç§ã«äŒãããŸããåŸè ã®é ã«ïŒæéã®ã³ãŒãã¯ã§ããéãå°ãªãã³ãŒãã§ãããPHPã«ãšã£ãŠã¯éåžžã«éèŠã§ãã ã·ã³ãã«ã/ãããã¡ã€ã«ãšãã£ã¬ã¯ããªã®ååã«ååšããããšã¯æ±ºããŠãªãããšã«æ°ä»ããããããŸããããããã£ãŠããã¡ã€ã«ã®ãªã¹ãã¯æååãšããŠäœæã§ããŸãã
function d_filelist_simple($dir) { $dh = opendir($dir); if (!$dh) return d_error("Cannot open $dir"); // use as little memory as possible using strings $files = ''; // assuming that first two entries are always "." and ".." or (in case of root dir) it is only "." // we can read first two entries separately and skip check for "." and ".." in main cycle for // maximum possible performance for ($i = 0; $i < 2; $i++) { $f = readdir($dh); if ($f === false) return array('res' => '', 'cnt' => 0); if ($f === "." || $f === "..") continue; $files .= "$f/"; } while (false !== ($f = readdir($dh))) $files .= "$f/"; closedir($dh); return array('res' => $files, 'cnt' => substr_count($files, '/')); }
PHPã§ã¯é£çµãOïŒ1ïŒã§ããããããã®PHPã³ãŒãã¯ïŒãã®ç¶æ³ã§ïŒå¯èœãªéãé«éã§åäœããRAMã®æ¶è²»éãæå°éã«æããŸããã©ãããããããã¡ã€ã«åãåé¢ããŸãã
å®éããã®ãããªã³ãŒãã䜿çšãããšã50äžåã®ãã¡ã€ã«ã®ãã©ã«ããŒãéãããšãã§ãã32 MBæªæºããæ¶è²»ãããjson_encodeãèæ ®ãããŸãã éåžžã«åçŽãªããŒã¿æ§é ïŒåãªãæååïŒãæ§æãããããjson_encodeã©ã³ã¿ã€ã ãéåžžã«å°ãããªãããã©ãŠã¶ãŒããã®è§£æã®ã³ã¹ããå°ãããªããŸãã è¡ãåãåã£ãåŸãåå²ïŒ '/'ïŒãè¡ããããã©ã«ããŒå ã®ãã¡ã€ã«ã®å®å šãªãªã¹ããååŸãããŸãã ãã®åŸã2çªç®ã®AJAXãªã¯ãšã¹ãã§è¡šç€ºå¯èœãªãã¡ã€ã«ã®ã¿ã®æ å ±ãèŠæ±ã§ããŸãïŒæåã®æ°çŸã®ãã¡ã€ã«ãå¿çã«å«ããããšãã§ããŸãïŒã ãããã£ãŠã以åã®ãã¹ãŠã®åé¡ã解決ããŸãããã¡ã€ã«ã®ãªã¹ãã®é·ãçæãäžçµæžãªã¡ã¢ãªæ¶è²»ã倧ããªãªã¹ãã®ã¹ã¯ããŒã«ã®äžäŸ¿ãã
ãã®ã¹ããŒã ã®ããã©ãŒãã³ã¹åæïŒ50,000ãã¡ã€ã«ïŒ
48ããªç§ã®çæ
1.92 Mbã¡ã¢ãª
107 KbããgzipïŒããŠã³ããŒãããšã«+ 200ããªç§ïŒ
ãã©ãŠã¶ã§56ããªç§
= 300ããªç§
+ã¯ã€ãã¯ã¹ã¿ãŒã
+ãã¡ã€ã«åã®ããŒã¿ã¢ããããŒããªã
+äœCPUã³ã¹ã
-倧éã®ãã©ãã£ãã¯ãè²»ãã
-ãã©ãŠã¶ã§å€§éã®ã¡ã¢ãªãæ¶è²»ããŸã
1.92 Mbã¡ã¢ãª
107 KbããgzipïŒããŠã³ããŒãããšã«+ 200ããªç§ïŒ
ãã©ãŠã¶ã§56ããªç§
= 300ããªç§
+ã¯ã€ãã¯ã¹ã¿ãŒã
+ãã¡ã€ã«åã®ããŒã¿ã¢ããããŒããªã
+äœCPUã³ã¹ã
-倧éã®ãã©ãã£ãã¯ãè²»ãã
-ãã©ãŠã¶ã§å€§éã®ã¡ã¢ãªãæ¶è²»ããŸã
åç §è³æ
ãã¡ã€ã«ãããŒãžã£ãŒã®ææ°ããŒãžã§ã³ã®åäœã瀺ããããªïŒããŒãžã§ã³ã«åé¡ããªãããã§ã¯ãããŸããïŒïŒ www.youtube.com/watch?v=XSvY9joxQqI
ãœãŒã¹ïŒ github.com/YuriyNasretdinov/Dolphin.php
çŸåããå€ãããŒãžã§ã³ã®ãã©ãŒã©ã ã¹ã¬ããïŒ forum.dklab.ru/viewtopic.php?t=9504