我在PHP中使用glob函数浏览目录并尝试仅匹配图像文件。这是有效的,但是当我尝试计算每个目录中的图像时,它会重复其他目录的第一个目录的计数。例如,目录1有6个图像,目录2有4个图像但是当我尝试显示每个目录的计数时,它显示目录2的6个图像,依此类推。
以下是我的代码:
public function viewphotoalbumsAction()
{
$identity = $this->identity();
$dirname = array();
$files = array();
foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
$dirname[] = basename($dir);
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images) {
$files[] = $images;
}
}
//var_dump($files); exit;
$data = array(
'albums' => array_values($dirname),
'files' => $files,
);
return new ViewModel(array('album' => $data['albums'], 'files' => $data['files']));
}
var_dump()的结果
array(9) { [0]=> string(96) "C:\xampp\htdocs/public/images/profile/fooboy/albums/bone mom's album_2017-07-03/massive snow.jpg"
[1]=> string(91) "C:\xampp\htdocs/public/images/profile/fooboy/albums/bone mom's album_2017-07-03/mom-jon.jpg"
[2]=> string(90) "C:\xampp\htdocs/public/images/profile/fooboy/albums/bone mom's album_2017-07-03/sunset.jpg"
[3]=> string(85) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/cref.jpg"
[4]=> string(88) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/diploma.jpg"
[5]=> string(86) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/eeyor.jpg"
[6]=> string(93) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/frother-jaws.jpg"
[7]=> string(88) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/frother.jpg"
[8]=> string(93) "C:\xampp\htdocs/public/images/profile/fooboy/albums/random photos_2017-07-02/goat_singing.jpg" }
它正在按预期获取每个目录中的所有图像,但我真正需要做的是分离图像,这样我就可以准确计算每个目录,而不仅仅是显示整个计数(9)
观看代码:
<div class="w3-col m7">
<div class="w3-row-padding">
<div class="w3-col m12">
<div class="w3-card-2 w3-round w3-white">
<div class="w3-container w3-padding" id="view-photo-albums">
<p class="w3-center">Current Albums</p>
<br>
<?php
foreach ($this->album as $albums):
?>
<p>
<?php echo $albums; ?> - Number of images: <?php echo $this->files; ?>
</p>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
任何帮助将不胜感激。
更新
我不能像array_values
那样使用$data['files']
,因为它会给出数组到字符串转换的警告。
答案 0 :(得分:5)
这段代码存在问题:
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images) {
$files[] = $images;
}
变量$dir
用于迭代第一次调用glob()
返回的数组:
foreach (glob(...) as $dir) {
...
}
第一个foreach
循环结束后的值是分配给foreach
循环的最后一个值。
最后,$data['albums']
包含所有目录名称,$data['files']
包含$data['albums']
中列出的最后一个目录中文件的名称。
我不能像$ data ['albums']那样使用$ data ['files']的array_values,因为它会给出数组到字符串转换的警告。
array_values()
不会为$dirname
和$files
生成任何新内容。如果它们被创建(!),则这两个变量包含以0
开头的序号索引的值;这正是array_values()
返回的内容。
您发布的代码的意图对我来说不是很清楚。我假设你想要显示专辑列表以及每张专辑包含多少张图片。
我就是这样做的:
public function viewphotoalbumsAction()
{
$identity = $this->identity();
// Always initialize the arrays before putting values into them.
// Without this, if the first glob() returns an empty array, the outer
// foreach loop never runs and both $dirname and $files end up being undefined
// and this produces trouble in the code that uses these variables later.
$dirname = array();
// This will be a two dimensional array. It is indexed by directory
// names and contains the lists of files for each directory.
$files = array();
// The outer loop enumerates the albums
foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
// The directory name is the album name
$albumName = basename($dir);
// Put the album name in $dirname[]
// This is not really needed as we also have the album name
// as key in $files but can be useful if you want to keep more
// information about each album
$dirname[] = $albumName;
// Initialize the list of images of this album
$files[$albumName] = array();
// The inner loop enumerates the images of this directory
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images) {
$files[] = $images;
}
}
// Prepare the data for display
$data = array(
'albums' => $dirname,
'files' => $files,
);
return new ViewModel($data);
}
视图(忽略了HTML包装器,它没问题):
<?php foreach ($this->files as $albumName => $listFiles): ?>
<p>
<?php echo $albumName; ?> - Number of images: <?php echo count($listFiles); ?>
</p>
<?php endforeach; ?>
作为评论,甚至不需要内部foreach
循环,因为它所做的只是将glob()
返回的数组中的值逐个复制到新数组中。
将glob()
返回的值存储到$files[$albumName]
中更快更容易阅读和理解。由于永远不会使用$dirname
中存储的值,因此可以完全省略此变量,并且函数会变短(注释省略):
public function viewphotoalbumsAction()
{
$identity = $this->identity();
$files = array();
foreach (glob(getcwd().'/public/images/profile/'.$identity.'/albums/*', GLOB_ONLYDIR) as $dir) {
$albumName = basename($dir);
$files[$albumName] = glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE);
}
return new ViewModel(array('files' => $files));
}
答案 1 :(得分:2)
我认为您还需要将foreach用于文件数组:
//its a demo
foreach(array_combine($a,$b) as $key=>$value) {
echo $key."<br/>".$value;
}//its a demo
试试这个:
<div class="w3-col m7">
<div class="w3-row-padding">
<div class="w3-col m12">
<div class="w3-card-2 w3-round w3-white">
<div class="w3-container w3-padding" id="view-photo-albums">
<p class="w3-center">Current Albums</p>
<br>
<?php
foreach(array_combine($this->album,$this->files) as $albums=>$files) :
?>
<p>
<?php echo $albums; ?> - Number of images: <?php echo files; ?>
</p>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
答案 2 :(得分:2)
我认为您需要明确声明变量类型数组,即
public function viewphotoalbumsAction()
{
$identity = $this->identity();
$dirname = array();
$files = array();
// continue ...
}
让我知道是否有效。感谢。
答案 3 :(得分:2)
可能你需要在第二个结束之前结束第一个foreach语句,而不是之前所以每个$ dir都有自己的$ images
public function viewphotoalbumsAction()
{
$identity = $this->identity();
foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
$dirname[] = basename($dir);
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images) {
$files[] = $images;
}
}
$data = array(
'albums' => array_values($dirname),
'files' => $files,
);
return new ViewModel(array('album' => $data['albums'], 'files' => count($data['files'])));
}
答案 4 :(得分:2)
在你的公共函数中,de last dir
将是你的第二个语句中使用的目录,这只会导致在这个文件夹中计算的文件。
改变这个:
foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
$dirname[] = basename($dir);
}
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images) {
$files[] = $images;
}
进入
foreach (glob(getcwd() . '/images/albums/*', GLOB_ONLYDIR) as $dir)
{
$dirname[] = basename($dir);
foreach (glob($dir . '/*.{jpg,png,gif}', GLOB_BRACE) as $images)
{
$files[] = $images;
}
}