是否有一种快速有效的方法来扫描目录并根据找到的文件生成标记?

发布于 2024-11-01 17:55:10 字数 3402 浏览 2 评论 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;
    }

I wrote this block of code and what it does is set path variables depending on information pulled from the database. Then it searches through directories and pulls out files that I want to insert into my page.

I use the Smarty template engine, my problem is that even though this works to the extent I want it to. It runs really slow and takes a while to scan through the directories pull the files and make the markup before the whole page is loaded.

// 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);
}

EDIT:

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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缱绻入梦 2024-11-08 17:55:10

如果您使用的是 PHP 5.3 或更高版本,我建议使用 SPL FilesystemIterator 作为一个优雅的解决方案。

这种方法的好处之一是,您可以通过将迭代器交换为 RecursiveIteratorIteratorRecursiveDirectoryIterator

您还可以使用 fileinfo 类而不是已弃用的 mime_content_type()

这是 奥利弗的回答

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 也可以完成大部分工作,但您需要使用 mime_content_type()

If you're on PHP 5.3 or later I'd suggest using the SPL FilesystemIterator as an elegant solution for this.

One of the nice things about this approach is that you can make this recursive by swapping the iterator to RecursiveIteratorIterator and RecursiveDirectoryIterator.

You can also use the fileinfo class instead of the deprecated mime_content_type().

Here's a drop-in replacement for 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 on PHP 5.2 or later will do most of this as well, though you'll need to use mime_content_type().

夏有森光若流苏 2024-11-08 17:55:10

使用这个函数,我自己编写了它并在几个项目中使用它

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; 
}

请注意我上面发布的函数...除此之外,请先加载要在数组中使用的任何数据,然后一次性处理所有标记收集完所有数据后。

use this function, I wrote it myself and use it in several projects

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; 
}

Please note the function I Posted above... other then that, do load first any data which you are going to use in arrays and then process the markup all in one go after you gathered all the data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文