重复两个目录的图像计数

时间:2017-07-03 20:38:42

标签: php

我在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'],因为它会给出数组到字符串转换的警告。

5 个答案:

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