搜索

首页  >  问答  >  正文

PHP 中的数组:添加新条目时的令人惊讶的结果

所以我正在编写代码,允许我收集 Instaloader python 库收集的图像,并将它们放入我网站上的图库中。我已经设法毫无问题地收集和显示这些内容,但是我现在已经开始为每篇文章实现标题,但我遇到了问题。

图书馆下载照片的方式是,如果集合中有多于一张照片,它将根据集合中图像的位置为帖子添加 _1、_2 等后缀,并提供 .txt 文件作为标题。

集合的示例文件夹内容:

2022-12-26_14-14-01_UTC.txt
2022-12-26_14-14-01_UTC_1.jpg
2022-12-26_14-14-01_UTC_2.jpg
2022-12-26_14-14-01_UTC_3.jpg

单个帖子的帖子效果很好 示例:

2022-12-31_18-13-43_UTC.txt
2022-12-31_18-13-43_UTC.jpg

主要代码块:

$array = []; 
$account_name = "everton";
$file_directory = "images/instagram";
$count = 0;

$hasvideo = 0;
$hasCaption = 0;

$handle = opendir(dirname(realpath(__DIR__)).'/'.$file_directory.'/');
while($file = readdir($handle)){
    $date = substr($file, 0, strpos($file, "_UTC"));
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // Using strtolower to overcome case sensitive
    if($ext === 'jpg'){
        $count++;

        $collectionSize = (int)str_replace("_", "", str_replace(".jpg", "", explode("UTC",$file)[1]));
        if(!is_numeric($collectionSize)){
            $collectionSize = 0;
        }

        $arrayKey = array_search($date, array_column($array, 'date'));

        if($arrayKey){
            $amount = intval($array[$arrayKey]['collection-size']);
            
            if($collectionSize > $amount){
                $array[$arrayKey]['collection-size'] = (int)$collectionSize;
            }
        }else{
            array_push($array, array ("date" => $date, "collection-size" => (int)$collectionSize, "has-video" => false));
        }
    }
    
    if ($ext === "txt"){
        $file_location = dirname(realpath(__DIR__)).'/'.$file_directory.'/'. $file;
        $myfile = fopen( $file_location, "r") or die("Unable to open file!");
        $caption = fread( $myfile, filesize($file_location));
        $arrayKey = array_search($date, array_column($array, 'date'));

        //$arrayKey returns false when there is a collection. 
        if($array[$arrayKey]){
            $array[$arrayKey]['caption'] = $caption;
        }else{
            array_push($array, array ("date" => $date, "caption" => $caption));
        }
        fclose($myfile);
    }
}

当常规单个帖子上存在集合时,$arrayKey 返回 false。

我相信这与脚本读取这些文件的文件顺序有关,因为我假设它会在读取 (date)_(collectionposition).jpg 之前读取 (date).txt

如果数组条目已经创建,则标题通常会添加到数组数据中,如果没有(例如当存在 _1、_2 等时),则数组不会更新任何内容,也不会引发任何错误。

编辑: 进一步的故障排除表明我根据“日期”值更新/检查数组键的方式是错误的,希望找到处理这些操作的正确方法

任何有关我可以修复哪些问题以使这项工作按预期进行的指导都将受到赞赏,谢谢!

P粉893457026P粉893457026240 天前515

全部回复(1)我来回复

  • P粉739942405

    P粉7399424052024-04-01 00:29:12

    让我们先研究一下你的代码。你提到的问题,即。以下行:

    $arrayKey = array_search($date, array_column($array, 'date'));

    ...返回 false,因为处理 .txt 文件时尚未创建带有日期的 $array 条目。 (使用 array_push 创建数组成员的逻辑位于代码的下方。)

    简单修复以继续移动到 if/else 逻辑的相关部分尚未定义

    if($arrayKey !== false && $array[$arrayKey]){
    ...

    也就是说,如果$arrayKey不是false,则继续将值添加到现有数组成员中。否则,创建数组成员。

    此外,处理图像时存在问题,第一次发生时会生成警告:

    $amount = intval($array[$arrayKey]['collection-size']);

    这将失败,未定义的数组键“collection-size”,因为 collection-size 键尚不存在。修复例如在尝试对数组键进行操作之前,使用空合并运算符设置“默认零”:

    $array[$arrayKey]['collection-size'] ??= 0;

    这些注释修复了错误,但是最好将 txt 或 jpg 的第一个实例中的“条目创建”分开 - 使用带有预期键的空数组成员,在执行任何 txt/jpg 特定逻辑之前。我将简单地使用 $date 本身作为分组,这样您也可以摆脱 array_search。例如,提取日期后,使用:

    $array[$date] ??= [
        'date' => $date,
        'caption' => '',
        'collection-size' => 0,
        'has-video' => false,
    ];

    然后修改其余代码以匹配。 您的代码不应依赖于文件读取的顺序。不保证该顺序。否则,您始终可以先将文件列表读入常规数组,然后对它们进行排序,并在应用特定逻辑时再次迭代。

    简化的代码

    实际需要的代码量比您拥有的少得多。这里我已经为你修剪了。我没有您的文件,所以这里有一些虚拟数据:

    $files = <<
    

    您也可以将 glob 文件放入数组中(= 文件路径列表):

    $file_directory = "images/instagram";
    $files = glob(dirname(realpath(__DIR__)).'/'.$file_directory.'/*');

    然后迭代如下:

    foreach($files as $filepath) {
        $filename = basename($filepath);
        $date = strstr($filename, '_UTC', true);
        
        $array[$date] ??= [
            'date' => $date,
            'caption' => '',
            'collection-size' => 0,
            'has-video' => false,
        ];
        
        $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        
        if($ext === 'jpg'){
            // Each JPG increments collection size:
            $array[$date]['collection-size']++;
        }
        
        elseif ($ext === "txt"){
            // We use a dummy here:
            $caption = '---';
            // $caption = file_get_contents($filepath);
    
            $array[$date]['caption'] = $caption;
        }
    }

    注意它缩小了多少。发生了什么?

    • 我们使用 $date 作为数组的分组索引。不再有 array_search
    • 我们为每个日期初始化一个默认条目。无需进一步检查或条件!
    • 我们忽略文件名中的 _3 等“集合大小”:只需为每个 JPG 添加 1。
    • 我们使用 nglobfile_get_contents 而不是 readdirfopen
    • 文件的顺序并不重要。 (随意测试和 shuffle($files)!)

    结果:

    array(3) {
        ["2022-12-26_14-14-01"] · array(4) {
            ["date"] · string(19) "2022-12-26_14-14-01"
            ["caption"] · string(3) "---"
            ["collection-size"] · int(3)
            ["has-video"] · bool(false)
        }
        ["2022-12-27_14-14-01"] · array(4) {
            ["date"] · string(19) "2022-12-27_14-14-01"
            ["caption"] · string(3) "---"
            ["collection-size"] · int(2)
            ["has-video"] · bool(false)
        }
        ["2022-12-31_18-13-43"] · array(4) {
            ["date"] · string(19) "2022-12-31_18-13-43"
            ["caption"] · string(3) "---"
            ["collection-size"] · int(1)
            ["has-video"] · bool(false)
        }
    }

    回复
    0
  • 取消回复