2011-04-16 27 views
0

我寫了這段代碼,它所做的是根據從數據庫中提取的信息設置路徑變量。然後它搜索目錄並提取我想要插入到我的頁面的文件。是否有快速有效的方式來掃描目錄並根據找到的文件生成標記?

我使用Smarty模板引擎,我的問題是即使這在我想要的範圍內工作。它運行速度非常慢,需要一段時間才能掃描整個頁面,然後在整個頁面加載之前拉取文件並進行標記。

// Load variables based on if the user has a custom theme applied or a default one 
$theme_name = $default->get_theme('theme_dir_name', 'dash'); 
if($users->get_settings('theme_is_custom', $auth->session->get('user_id')) == 1) 
{ 
    $css_path = "/".$auth->session->get("user_name")."/css"; 
    $theme_dir = dirname(__FILE__) . "/assets/users/".$users->get_user_id($_GET['user'])."/themes/".$theme_name."/tpl/"; 
    $s->assign("css_dir", $css_path."/".$theme_name); 
    $s->assign("js_dir" , "/".$_GET['user']."/js/".$theme_name); 
}else{ 
    $css_path = "/css"; 
    $theme_dir = dirname(__FILE__) . "/assets/default/themes/".$theme_name."/tpl/"; 
    $s->assign("css_dir", $css_path."/".$theme_name); 
    $s->assign("js_dir" , "/js/".$theme_name); 
} 
// Load modules 
foreach($users->get_active_module($auth->session->get('user_id')) as $m) 
{ 
    if(@$m['module_is_custom'] == 1) 
    { 
     $path = "/".$auth->session->get("user_id")."/modules/".$m['module_folder_name']."/index.php"; 
     $dir = "/".$auth->session->get("user_id")."/modules/".$m['module_folder_name']; 
    }else{ 
     $path = dirname(__FILE__)."/assets/default/modules/".$m['module_folder_name']."/index.php"; 
     $dir = dirname(__FILE__)."/assets/default/modules/".$m['module_folder_name']; 
     $js = "/modules/default/".$m['module_folder_name']."/js/"; 
     $css = "/modules/default/".$m['module_folder_name']."/css/"; 
    } 
    $css_module = ""; 
    $js_module = ""; 
    $module = $s->fetch($path); 
    if($handle = opendir($dir."/css/")) 
    { 
     while(false !== ($file = readdir($handle))) 
     { 
      if($file != "." && $file != ".."){ 
       $css_module .= '<link rel="stylesheet" href="'.$css.$file.'" />'; 
      } 
     } 
     closedir($handle); 
    } 
    if($handle = opendir($dir."/js/")) 
    { 
     while(false !== ($file = readdir($handle))) 
     { 
      if($file != "." && $file != "..") 
      { 
       $js_module .= '<script type="text/javascript" src="'.$js.$file.'"></script>'; 
      } 
     } 
     closedir($handle); 
    } 
    $s->assign($m['module_folder_name']."_module", $css_module."\n".$js_module."\n".$module); 
} 

編輯:

function getFileList($dir) 
    { 
     $retval = array(); 
     if(substr($dir, -1) != "/") 
      $dir .= "/"; 
     $d = @dir($dir) or die("getFileList: Failed opening directory $dir for reading"); 
     while(false !== ($entry = $d->read())) 
     { 
      if($entry[0] == ".") 
       continue; 
      if(is_dir("$dir$entry")) 
      { 
       $retval[] = array("name" => "$dir$entry/", "type" => filetype("$dir$entry"), "size" => 0, "lastmod" => filemtime("$dir$entry")); 
      }elseif(is_readable("$dir$entry")){ 
       $retval[] = array("name" => "$dir$entry", "type" => mime_content_type("$dir$entry"), "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); 
      } 
      echo basename("$dir$entry")."<br />"; 
     } 
     $d->close(); return $retval; 
    } 

回答

-1

使用此功能,我自己寫的,並在多個項目中使用

function getFileList($dir) { 
    $retval = array(); 
    if(substr($dir, -1) != "/") $dir .= "/"; 
    $d = @dir($dir) or die("getFileList: Failed opening directory $dir for reading"); 
    while(false !== ($entry = $d->read())) { 
     if($entry[0] == ".") continue; 
     if(is_dir("$dir$entry")) { 
      $retval[] = array("name" => "$dir$entry/", "type" => filetype("$dir$entry"), "size" => 0, "lastmod" => filemtime("$dir$entry")); 
     } elseif(is_readable("$dir$entry")) { 
      $retval[] = array("name" => "$dir$entry", "type" => mime_content_type("$dir$entry"), "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); 
     } 
    } 
    $d->close(); 
    return $retval; 
} 

請注意我上面貼的功能...其他然後, ,首先加載你要在數組中使用的任何數據,然後在收集所有數據後一次處理標記。

+0

嗯,堅持讓我看看,如果我把它合在一起到我的應用程序 – Eli 2011-04-16 10:30:25

+0

我把它合成爲我工作;-)我還添加了一條線 – Eli 2011-04-16 10:45:44

0

如果你在PHP 5.3或更高版本,我建議使用SPL FilesystemIterator作爲一個優雅的解決方案。

這種方法的好處之一是,您可以通過將迭代器交換到RecursiveIteratorIteratorRecursiveDirectoryIterator來進行遞歸。

您也可以使用類代替已棄用的mime_content_type()

下面是一個Oliver's answer簡易替換:

function getFileList($dir, $recursive = false) 
{ 
    $finfo = new finfo(FILEINFO_MIME); 
    $retval = array(); 

    if ($recursive) 
    { 
     // Note: If RecursiveIteratorIterator::SELF_FIRST is removed it will use the default 
     //  RecursiveIteratorIterator::LEAVES_ONLY and therefore ignore directories. 
     $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), 
                RecursiveIteratorIterator::SELF_FIRST); 
    } 
    else 
    { 
     $iter = new FilesystemIterator($dir); 
    } 

    foreach ($iter as $path => $info) 
    { 
     $filename = $info->getFilename(); 

     if ("." === $filename[0]) 
     { 
      // ignore hidden files on unix for compatability with the Oliver's function 
      // note that the default constructor flag FilesystemIterator::SKIP_DOTS will have skipped the . and .. files anyway. 
      continue; 
     } 

     $val = array("name" => $path, 
        "type" => $info->getType(), 
        "size" => $info->getSize(), 
        "lastmod" => $info->getMTime()); 

     if ($info->isFile()) 
     { 
      $fulltype = $finfo->file($path); 
      // $finfo->file() returns something like "application/octet-stream; charset=binary" 
      // the first part matches what mime_content_type() returns, ignore the rest for compatability with Oliver's function 
      $ftypeparts = explode(";", $fulltype, 2); 
      $val ["type"] = $ftypeparts[0]; 
     } 

     $retval[] = $val; 
    } 

    return $retval; 
} 

SPL DirectoryIterator在PHP 5.2或更高版本將做最本爲好,雖然你將需要使用mime_content_type()

相關問題