PHP - 读取文件夹、所有子文件夹和子文件夹中的文件
PHP - reading folder, all subfolders, and files in subfolders
我有一个名为 "inspections" 的文件夹,其中包含许多名为 "location 1"、"location 2"、"location 3" 等的子文件夹,每个子文件夹大约有 10-20 个 .png里面有图片。
我想做的是读取 "inspections" 文件夹的目录,然后读取每个文件夹中的所有图像文件,然后 return 将它们作为画廊我的 index.php 网站。问题是我没有收到任何错误消息,但脚本没有 return 任何内容。我认为问题在于为每个子文件夹生成 $files 变量,因为我部署了相同的脚本以读取另一个站点上的文件夹内容。
也许有人能给我指出正确的方向?
<?php
$dir = './inspections/';
if ($handle = opendir($dir))
{
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle)))
{
if (!in_array($folder, $blacklist))
{
if (file_exists($dir . $folder . '/desc.txt'))
{
while (false !== ($file = readdir($handle)))
{
if (!in_array($file, $blacklist))
{
$chain = file_get_contents($dir . $folder . '/chain.txt');
$website = file_get_contents($dir . $folder . '/website.txt');
$location = file_get_contents($dir . $folder . '/location.txt');
$desc = file_get_contents($dir . $folder . '/desc.txt', NULL, NULL, 0, 250) . '...';
echo "
<!-- Post -->
<div class=\"post\">
<div class=\"user-block\">
<img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/logo_".$chain."\" alt=\"\">
<span class=\"username\">
<a href=\"".$website."\" target=\"_blank\">".$folder."</a>
</span>
<span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ". $date . "</span>
</div>
<!-- /.user-block -->
<p>".$desc."</p>
<div class=\"lightBoxGallery\">
<a href=\"".$dir . $folder . "/".$file."\" title=\"".$file."\" data-gallery=\"\"><img src=\"".$dir . $folder . "/".$file."\" style=\"height:100px; width:100px;\"></a>
</div>
";
}
}
}
}
}
closedir($handle);
}
?>
编辑:
按照@JazZ 的建议,我调整了代码并且现在运行良好,但是,假设一个人不想显示调整大小的图片本身,而是希望显示存储在子文件夹中的缩略图(例如 ./location1/thumbs/),我该怎么做?
<?php
$dir = './inspections/';
if ($handle = opendir($dir)) {
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle))) {
if (!in_array($folder, $blacklist)) {
echo "
<!-- Post -->
<div class=\"post\">
<div class=\"user-block\">
<img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/gallery_icon_".$chain.".jpg\" alt=\"\">
<span class=\"username\">
<a href=\"".$website."\" target=\"_blank\">".$hotel_name."</a>".$status."
</span>
<span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ".date('jS F, Y - H:m', strtotime($posted_on))."</span>
</div>
<!-- /.user-block -->
<p>".$desc."</p>
<div class=\"lightBoxGallery\">
";
foreach (glob($dir . $folder . "/*.jpg") as $filename) {
echo "
<a href=\"".$filename."\" title=\"\" data-gallery=\"\"><img src=\"".$filename."\" style=\"height:100px; width:100px;\"></a>";
}
echo "</div>
</div>
<!-- /. POST -->
";
}
}
closedir($handle);
}
?>
我认为你的问题来自这里:
while (false !== ($file = readdir($handle))) // it reads again the same directory as it did in the first while loop
尝试将其替换为
if ($sub_handle = opendir($dir . $folder)) {
while (false !== ($file = readdir($sub_handle))) {
...
}
closedir($sub_handle);
}
此外,在你的情况下,我会使用 php glob()
function
查看适用于您的案例的示例:
$dir = './inspections/';
if ($handle = opendir($dir)) {
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle))) {
if (!in_array($folder, $blacklist)) {
foreach (glob($dir . $folder . "/*.png") as $filename) {
echo "$filename was found !";
echo "\r\n";
}
}
}
closedir($handle);
}
输出:
./inspections/location_4/img_1.png was found !
./inspections/location_4/img_2.png was found !
./inspections/location_4/img_3.png was found !
./inspections/location_4/img_4.png was found !
./inspections/location_4/img_5.png was found !
./inspections/location_4/img_6.png was found !
./inspections/location_3/img_1.png was found !
./inspections/location_3/img_2.png was found !
./inspections/location_3/img_3.png was found !
./inspections/location_3/img_4.png was found !
./inspections/location_3/img_5.png was found !
./inspections/location_3/img_6.png was found !
./inspections/location_2/img_1.png was found !
./inspections/location_2/img_2.png was found !
./inspections/location_2/img_3.png was found !
./inspections/location_2/img_4.png was found !
./inspections/location_2/img_5.png was found !
./inspections/location_2/img_6.png was found !
./inspections/location_1/img_1.png was found !
./inspections/location_1/img_2.png was found !
./inspections/location_1/img_3.png was found !
./inspections/location_1/img_4.png was found !
./inspections/location_1/img_5.png was found !
./inspections/location_1/img_6.png was found !
编辑
要在 /inspections/location1/thumbs/ 目录中循环,这可行:
foreach (glob($dir . $folder . "/thumbs/*.png") as $filename) {
echo "$filename was found !";
echo "\r\n";
}
重新编辑
要使用 glob()
函数 glob 多个文件夹,您的代码应如下所示:
foreach (glob($dir.$folder."{/thumbs/*.png,/*.png}", GLOB_BRACE) as $filename) {
echo "$filename was found !";
echo "\r\n";
}
Perhaps the Function below helps. It is also somewhat commented. It scans a directory recursively (in this case, extracting image files from each directory/sub-directory).
<?php
$rootPath = './inspections/';
$regex = "#(\.png$)|(\.jpg$)|(\.jpeg$)|(\.tiff$)|(\.gif$)#";
/**
* @param string $directory => DIRECTORY TO SCAN
* @param string $regex => REGULAR EXPRESSION TO BE USED IN MATCHING FILE-NAMES
* @param string $get => WHAT DO YOU WANT TO GET? 'dir'= DIRECTORIES, 'file'= FILES, 'both'=BOTH FILES+DIRECTORIES
* @param bool $useFullPath => DO YOU WISH TO RETURN THE FULL PATH TO THE FOLDERS/FILES OR JUST THEIR BASE-NAMES?
* @param array $dirs => LEAVE AS IS: USED DURING RECURSIVE TRIPS
* @return array
*/
function scanDirRecursive($directory, $regex=null, $get="file", $useFullPath=false, &$dirs=[], &$files=[]) {
$iterator = new DirectoryIterator ($directory);
foreach($iterator as $info) {
$fileDirName = $info->getFilename();
if ($info->isFile () && !preg_match("#^\..*?#", $fileDirName)) {
if($get == 'file' || $get == 'both'){
if($regex) {
if(preg_match($regex, $fileDirName)) {
if ($useFullPath) {
$files[] = $directory . DIRECTORY_SEPARATOR . $fileDirName;
}
else {
$files[] = $fileDirName;
}
}
}else{
if($useFullPath){
$files[] = $directory . DIRECTORY_SEPARATOR . $fileDirName;
}else{
$files[] = $fileDirName;
}
}
}
}else if ($info->isDir() && !$info->isDot()) {
$fullPathName = $directory . DIRECTORY_SEPARATOR . $fileDirName;
if($get == 'dir' || $get == 'both') {
$dirs[] = ($useFullPath) ? $fullPathName : $fileDirName;
}
scanDirRecursive($fullPathName, $regex, $get, $useFullPath, $dirs, $files);
}
}
if($get == 'dir') {
return $dirs;
}else if($get == 'file'){
return $files;
}
return ['dirs' => $dirs, 'files' => $files];
}
$images = scanDirRecursive($rootPath, $regex, 'file', true);
var_dump($images);
我有一个名为 "inspections" 的文件夹,其中包含许多名为 "location 1"、"location 2"、"location 3" 等的子文件夹,每个子文件夹大约有 10-20 个 .png里面有图片。
我想做的是读取 "inspections" 文件夹的目录,然后读取每个文件夹中的所有图像文件,然后 return 将它们作为画廊我的 index.php 网站。问题是我没有收到任何错误消息,但脚本没有 return 任何内容。我认为问题在于为每个子文件夹生成 $files 变量,因为我部署了相同的脚本以读取另一个站点上的文件夹内容。
也许有人能给我指出正确的方向?
<?php
$dir = './inspections/';
if ($handle = opendir($dir))
{
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle)))
{
if (!in_array($folder, $blacklist))
{
if (file_exists($dir . $folder . '/desc.txt'))
{
while (false !== ($file = readdir($handle)))
{
if (!in_array($file, $blacklist))
{
$chain = file_get_contents($dir . $folder . '/chain.txt');
$website = file_get_contents($dir . $folder . '/website.txt');
$location = file_get_contents($dir . $folder . '/location.txt');
$desc = file_get_contents($dir . $folder . '/desc.txt', NULL, NULL, 0, 250) . '...';
echo "
<!-- Post -->
<div class=\"post\">
<div class=\"user-block\">
<img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/logo_".$chain."\" alt=\"\">
<span class=\"username\">
<a href=\"".$website."\" target=\"_blank\">".$folder."</a>
</span>
<span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ". $date . "</span>
</div>
<!-- /.user-block -->
<p>".$desc."</p>
<div class=\"lightBoxGallery\">
<a href=\"".$dir . $folder . "/".$file."\" title=\"".$file."\" data-gallery=\"\"><img src=\"".$dir . $folder . "/".$file."\" style=\"height:100px; width:100px;\"></a>
</div>
";
}
}
}
}
}
closedir($handle);
}
?>
编辑: 按照@JazZ 的建议,我调整了代码并且现在运行良好,但是,假设一个人不想显示调整大小的图片本身,而是希望显示存储在子文件夹中的缩略图(例如 ./location1/thumbs/),我该怎么做?
<?php
$dir = './inspections/';
if ($handle = opendir($dir)) {
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle))) {
if (!in_array($folder, $blacklist)) {
echo "
<!-- Post -->
<div class=\"post\">
<div class=\"user-block\">
<img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/gallery_icon_".$chain.".jpg\" alt=\"\">
<span class=\"username\">
<a href=\"".$website."\" target=\"_blank\">".$hotel_name."</a>".$status."
</span>
<span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ".date('jS F, Y - H:m', strtotime($posted_on))."</span>
</div>
<!-- /.user-block -->
<p>".$desc."</p>
<div class=\"lightBoxGallery\">
";
foreach (glob($dir . $folder . "/*.jpg") as $filename) {
echo "
<a href=\"".$filename."\" title=\"\" data-gallery=\"\"><img src=\"".$filename."\" style=\"height:100px; width:100px;\"></a>";
}
echo "</div>
</div>
<!-- /. POST -->
";
}
}
closedir($handle);
}
?>
我认为你的问题来自这里:
while (false !== ($file = readdir($handle))) // it reads again the same directory as it did in the first while loop
尝试将其替换为
if ($sub_handle = opendir($dir . $folder)) {
while (false !== ($file = readdir($sub_handle))) {
...
}
closedir($sub_handle);
}
此外,在你的情况下,我会使用 php glob()
function
查看适用于您的案例的示例:
$dir = './inspections/';
if ($handle = opendir($dir)) {
$blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
while (false !== ($folder = readdir($handle))) {
if (!in_array($folder, $blacklist)) {
foreach (glob($dir . $folder . "/*.png") as $filename) {
echo "$filename was found !";
echo "\r\n";
}
}
}
closedir($handle);
}
输出:
./inspections/location_4/img_1.png was found ! ./inspections/location_4/img_2.png was found ! ./inspections/location_4/img_3.png was found ! ./inspections/location_4/img_4.png was found ! ./inspections/location_4/img_5.png was found ! ./inspections/location_4/img_6.png was found ! ./inspections/location_3/img_1.png was found ! ./inspections/location_3/img_2.png was found ! ./inspections/location_3/img_3.png was found ! ./inspections/location_3/img_4.png was found ! ./inspections/location_3/img_5.png was found ! ./inspections/location_3/img_6.png was found ! ./inspections/location_2/img_1.png was found ! ./inspections/location_2/img_2.png was found ! ./inspections/location_2/img_3.png was found ! ./inspections/location_2/img_4.png was found ! ./inspections/location_2/img_5.png was found ! ./inspections/location_2/img_6.png was found ! ./inspections/location_1/img_1.png was found ! ./inspections/location_1/img_2.png was found ! ./inspections/location_1/img_3.png was found ! ./inspections/location_1/img_4.png was found ! ./inspections/location_1/img_5.png was found ! ./inspections/location_1/img_6.png was found !
编辑
要在 /inspections/location1/thumbs/ 目录中循环,这可行:
foreach (glob($dir . $folder . "/thumbs/*.png") as $filename) {
echo "$filename was found !";
echo "\r\n";
}
重新编辑
要使用 glob()
函数 glob 多个文件夹,您的代码应如下所示:
foreach (glob($dir.$folder."{/thumbs/*.png,/*.png}", GLOB_BRACE) as $filename) {
echo "$filename was found !";
echo "\r\n";
}
Perhaps the Function below helps. It is also somewhat commented. It scans a directory recursively (in this case, extracting image files from each directory/sub-directory).
<?php
$rootPath = './inspections/';
$regex = "#(\.png$)|(\.jpg$)|(\.jpeg$)|(\.tiff$)|(\.gif$)#";
/**
* @param string $directory => DIRECTORY TO SCAN
* @param string $regex => REGULAR EXPRESSION TO BE USED IN MATCHING FILE-NAMES
* @param string $get => WHAT DO YOU WANT TO GET? 'dir'= DIRECTORIES, 'file'= FILES, 'both'=BOTH FILES+DIRECTORIES
* @param bool $useFullPath => DO YOU WISH TO RETURN THE FULL PATH TO THE FOLDERS/FILES OR JUST THEIR BASE-NAMES?
* @param array $dirs => LEAVE AS IS: USED DURING RECURSIVE TRIPS
* @return array
*/
function scanDirRecursive($directory, $regex=null, $get="file", $useFullPath=false, &$dirs=[], &$files=[]) {
$iterator = new DirectoryIterator ($directory);
foreach($iterator as $info) {
$fileDirName = $info->getFilename();
if ($info->isFile () && !preg_match("#^\..*?#", $fileDirName)) {
if($get == 'file' || $get == 'both'){
if($regex) {
if(preg_match($regex, $fileDirName)) {
if ($useFullPath) {
$files[] = $directory . DIRECTORY_SEPARATOR . $fileDirName;
}
else {
$files[] = $fileDirName;
}
}
}else{
if($useFullPath){
$files[] = $directory . DIRECTORY_SEPARATOR . $fileDirName;
}else{
$files[] = $fileDirName;
}
}
}
}else if ($info->isDir() && !$info->isDot()) {
$fullPathName = $directory . DIRECTORY_SEPARATOR . $fileDirName;
if($get == 'dir' || $get == 'both') {
$dirs[] = ($useFullPath) ? $fullPathName : $fileDirName;
}
scanDirRecursive($fullPathName, $regex, $get, $useFullPath, $dirs, $files);
}
}
if($get == 'dir') {
return $dirs;
}else if($get == 'file'){
return $files;
}
return ['dirs' => $dirs, 'files' => $files];
}
$images = scanDirRecursive($rootPath, $regex, 'file', true);
var_dump($images);