0

不太了解在数组中的每个项目上运行函数,这对 PHP 来说还是很新的,下面$pic_loc是来自 MySQL 的数据数组,其中包含与执行的任何搜索条件匹配的图像的路径和文件名。

试图让该unlink功能在它找到的每个人上运行。没有错误返回。我认为这不是foreach正确的方法,有人能指出我正确的方向吗?

 $pic_loc = $cell_pictures['pic_loc']; //gathers an array from the database of files locations

    $pics_to_delete .= "../../".$pic_loc; //corrects the directory

    foreach($pics_to_delete as $pics_being_deleted) //deletes all pictures found
    {

    unlink($pics_being_deleted);

    }

编辑:我对这两个答案都做了很多修改,我知道我可以删除 2 层以上的文件,因为我可以毫无问题地对单个文件执行此操作。这就是我目前正在做的事情,我摆脱了while()循环,认为这可能导致 foreach 运行出现问题:

$data_array2 = mysql_query("SELECT * FROM pictures WHERE user_id = '".$id."'");
$cell_pictures = mysql_fetch_array($data_array2);


foreach($cell_pictures['pic_loc'] as $pics_being_deleted) //deletes all pictures found
{

unlink("../../".$pics_being_deleted);

}

这是它现在返回的错误:

Warning: Invalid argument supplied for foreach() // on the line that the foreach is on

编辑:好的,这很糟糕,但我明白了!!!你会认为来自查询的数据是一个数组,但实际上你必须将它设置为一个数组。我是这样做的:

$data_array2 = mysql_query("SELECT pic_loc FROM pictures WHERE user_id = '".$id."'");


while($cell_pictures = mysql_fetch_array($data_array2))
{
$the_pics = $cell_pictures['pic_loc'];
$pics_as_array = array($the_pics);
}

foreach($pics_as_array as $pics_being_deleted) 
{

unlink("../../".$pics_being_deleted);


}

这很好用。非常感谢您花时间阅读本文!-麦克风

4

3 回答 3

2

实际上foreach对于您想要做的事情完全没问题。

但是,您需要将一些逻辑放在迭代中。让我们来看看:

$directory = realpath("../../"); // the directory where files are placed
foreach ($pics_to_delete as $basename) //deletes all pictures found
{
    $path = sprtinf('%s/%s', $directory, $basename);
    unlink($path);
}

更好的选择是反其道而行之。首先获取目录和其中的所有文件,然后根据要删除的文件过滤该列表。仅当名称匹配时,继续:

$dir = new  DirectoryIterator($path);
$toDelete = new DeleteFilter($dir, $pics_to_delete);
foreach ($toDelete as $file)
{
    printf("Delete: %s\n", $file->getPathname());
    unlink($file->getPathname());
}

DirectoryIterator随 PHP 一起提供的,是DeleteFilter一个FilterIterator确保只$pics_to_delete返回真正匹配的文件和来自数组的条目的小文件:

class DeleteFilter extends FilterIterator
{
    private $filenames;

    public function __construct(Iterator $iterator, array $filenames)
    {
        $this->filenames = $filenames;
        parent::__construct($iterator);
    }

    public function accept()
    {
        $current = $this->getInnerIterator()->current();
        if (!($current instanceof SplFileInfo)) {
            return FALSE;
        }
        if (!$current->isFile()) {
            return FALSE;
        }
        return in_array($current->getBasename(), $this->filenames);
    }
}

您不需要那个过滤器迭代器,而是可以在内部编写该逻辑foreach,但是我认为这个更流畅。

于 2012-04-16T10:08:36.890 回答
1

如果 $cell_pictures['pic_loc'] 是要删除的文件数组,那么

foreach($cell_pictures['pic_loc'] as $pics_being_deleted) //deletes all pictures found
{

unlink("../../".$pics_being_deleted);

}
于 2012-04-16T10:07:40.797 回答
0

有时,网络主机设置是您无权删除或访问任何高于您的文件夹的文件。在你的情况下,你要向上两个文件夹。

您可能需要重组您的程序,以便将图片存储在试图删除它们的文件下方。

此外,请确保您传递正确的文件名字符串以取消链接。如果不确定,可以回显文件名进行测试。

于 2012-04-16T10:16:46.323 回答