Heim  >  Fragen und Antworten  >  Hauptteil

Arrays in PHP: Überraschende Ergebnisse beim Hinzufügen neuer Einträge

Also schreibe ich Code, der es mir ermöglicht, von der Instaloader-Python-Bibliothek gesammelte Bilder zu sammeln und sie in einer Galerie auf meiner Website abzulegen. Ich habe es ohne Probleme geschafft, diese zu sammeln und anzuzeigen. Allerdings habe ich jetzt damit begonnen, Header für jeden Beitrag zu implementieren, und es treten Probleme auf.

Die Art und Weise, wie die Bibliothek Fotos herunterlädt, besteht darin, dass, wenn mehr als ein Foto in der Sammlung vorhanden ist, dem Beitrag basierend auf der Position des Bildes in der Sammlung Suffixe _1, _2 usw. hinzugefügt werden und die TXT-Datei als bereitgestellt wird ein Titel.

Beispielordnerinhalte zur Sammlung:

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

Einzelne Beiträge funktionieren gut Beispiel:

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

Hauptcodeblock:

$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 gibt false zurück, wenn eine Sammlung für einen regulären Einzelbeitrag vorhanden ist.

Ich glaube, das hat mit der Dateireihenfolge zu tun, in der das Skript diese Dateien liest, da ich davon ausgehe, dass es (Datum).txt liest, bevor es (Datum)_(Sammlungsposition).jpg liest

Wenn der Array-Eintrag bereits erstellt wurde, wird der Header normalerweise zu den Array-Daten hinzugefügt. Wenn nicht (z. B. wenn _1, _2 usw. vorhanden sind), aktualisiert das Array nichts und es wird kein Fehler ausgegeben.

Bearbeiten: Die weitere Fehlerbehebung zeigt, dass die Art und Weise, wie ich die Array-Schlüssel basierend auf dem „Datum“-Wert aktualisiere/überprüfe, falsch ist. Hoffentlich kann die richtige Art und Weise gefunden werden, diese Vorgänge zu handhaben

Jede Anleitung, was ich beheben kann, damit es wie erwartet funktioniert, wäre dankbar, vielen Dank!

P粉893457026P粉893457026175 Tage vor396

Antworte allen(1)Ich werde antworten

  • 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)
        }
    }

    Antwort
    0
  • StornierenAntwort