【发布时间】:2021-07-14 18:56:52
【问题描述】:
概览
我们正在构建一个基于 PHP 的模板引擎(我知道是原创的)。核心功能之一是模板列表页面,用户可以在其中查看其用户定义的模板并使用它们创建页面对象。这些文件存储在 html 文件或 SQL 存储系统中。
我们已经完成了模板引擎中文件的加载,SQL 轻而易举,现在我们正在尝试自己加载 html 文件以供用户解析和列出。
代码
我们正在使用以下代码来获取目录中所有文件及其子文件的列表,然后将它们添加到数组中。
function get_directory_contents($directory, $hide_index_files = TRUE, $limit_to_html_files = TRUE) {
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS));
$files = array();
foreach ($rii as $file) {
if ($file->isDir()){
$files['directories'][] = $file;
} else {
if ($hide_index_files) {
if ($file->getFilename() == "index.html") {
continue;
}
}
if ($limit_to_html_files) {
if (substr($file->getFilename(), -5) != ".html") {
continue;
}
}
$count_to_filename = strlen($directory . "/");
$count_from_filename = strlen($file->getFilename());
$count_from_filename_plus_one = strlen($file->getFilename()) + 1;
$file_path_full = substr($file->getPathname(), $count_to_filename);
$remove_name = -1 * abs($count_from_filename_plus_one);
$file_path = substr($file_path_full, 0, $remove_name);
if (!$file_path) {
$file_path = "base_directory";
}
$files['files'][] = array("fullpath" => $file_path_full, "justPath" => $file_path, "filename" => $file->getFilename());
}
}
return $files;
}
路径指向模板中名为 templates/user-defined 的子文件夹,启用 RecursiveDirectoryIterator::SKIP_DOTS 标志后,files[directories] 字段返回空 - 当前代码返回以下数组:
Array
(
[files] => Array
(
[0] => Array
(
[fullpath] => hello_world.html
[justPath] => base_directory
[filename] => hello_world.html
)
[1] => Array
(
[fullpath] => another_folder/file.html
[justPath] => another_folder
[filename] => file.html
)
[2] => Array
(
[fullpath] => second_folder/alpha_file.html
[justPath] => second_folder
[filename] => alpha_file.html
)
[3] => Array
(
[fullpath] => second_folder/bravo_file.html
[justPath] => second_folder
[filename] => bravo_file.html
)
)
)
所需输出
我们希望看到按字母顺序输出的数组列表,并保持文件夹结构完整。目前,我们使用的 RecursiveDirectoryIterator 按文件上次编辑时间对条目进行排序,然后我们调用 asort() 尝试按字母顺序对项目进行排序,但它也不保留目录架构。
理想情况下,我们希望支持空文件夹并在其下列出其子文件夹,同时返回如下所示的数组:
Array
(
[files] => Array
(
[another_folder] => Array
(
[0] => Array
(
[fullpath] => another_folder/file.html
[filename] => file.html
)
)
[empty_folder] => Array
(
)
[second_folder] => Array
(
[0] => Array
(
[fullpath] => second_folder/file.html
[filename] => file.html
)
[1] => Array
(
[fullpath] => second_folder/bravo_file.html
[filename] => file.html
)
)
[base_directory] => Array
(
[0] => Array
(
[fullpath] => hello_world.html
[filename] => hello_world.html
)
)
)
)
这将允许我们像这样列出它们:
/another_folder/
-> file.html
/empty_folder/
/second_folder/
-> alpha_file.html
-> bravo_file.html
/
-> hello_world.html
我们正在使用 RecursiveDirectoryIterator() 和 RecursiveIterator() 函数,因为它们被认为比简单的 scandir 更快,并且它们具有我们更喜欢的良好对象方法。
我们如何在保持快速加载的同时实现这一点?
【问题讨论】: