• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Multidimensionales Array ausgeben: Undefined offset

cromafia007

Neues Mitglied
Hi Leute

Hab da n' Problem.
Ich hole aus einem Ordner Files, welche mit einem Datum benannt sind:

- 10-01-2012.pdf (= 10. Januar 2012)
- 02-03-2012.pdf (= 02. März 2012)
- usw.

Diese setze ich ein Array rein und will diese dann zum Download hierarchisch ausgeben.

Das Script ist so aufgebaut:
PHP:
$path = "dir/"; // in dem ordner sind die pdf's
if($handle = opendir($path)) {
    $posts = array(); // array vorbereiten, zum die pdfs dort einzutragen
    while(false !== ($file = readdir($handle))) {
        $parts = explode(".", $file); // damit die ausgabe schön aussieht, splitte ich hier das ".pdf" und nehme alle parts einzeln vor
        if(is_array($parts) && count($parts) > 1) {
            $extension = end($parts);
            if($extension == "pdf" OR $extension == "PDF") { // nur alle files nehmen mit der endung PDF oder pdf
                
                // explode date
                $date = explode("-", $file);
                $day = $date[0]; // tag als variable
                $mo = $date[1]; // monat als variable
                $month = $date[1]; // hier ersetze ich die monatszahlen durch strings
                $month = str_replace("01", "Januar", $month);
                $month = str_replace("02", "Februar", $month);
                $month = str_replace("03", "März", $month);
                $month = str_replace("04", "April", $month);
                $month = str_replace("05", "Mai", $month);
                $month = str_replace("06", "Juni", $month);
                $month = str_replace("07", "Juli", $month);
                $month = str_replace("08", "August", $month);
                $month = str_replace("09", "September", $month);
                $month = str_replace("10", "Oktober", $month);
                $month = str_replace("11", "November", $month);
                $month = str_replace("12", "Dezember", $month);
                $year = $date[2]; // das jahr
                
                $yearEx = explode(".", $year);
                $yearOut = $yearEx[0];
                
                // create array with downloadurl and filename
                $fileName = $day . ". " . $month . " " . $yearOut;
                $filePath = $path . '/' . $file;
                
                // hier setze ich das aktuelle file ($file) in ein array, um es danach in das oben gesetze array ($posts) zu stellen
                $tempArray =  array('fileName' => $fileName, 'filePath' => $filePath, 'file' => $file);
                
                if(!isset($posts[$yearOut][$mo])) { // abfragen, ob es schon ein file zu dem zugehörigen array gibt, wenn nein, erstellen.
                    $posts[$yearOut][$mo] = array();
                }
                // hier push ich das temporäre array in das eigendliche array. konstellation: jahr > monat > pdfs
                array_push($posts[$yearOut][$mo], $tempArray);
            }
        }
    }
    closedir($handle);
}

Das klappt soweit gut, die ausgabe kommt wie folgt raus:
Code:
Array
(
    [2012] => Array
        (
            [05] => Array
                (
                    [0] => Array
                        (
                            [file] => 26-05-2012.pdf
                            [fileName] => 26. Mai 2012
                            [filePath] => dir/26-05-2012.pdf
                        )

                    [1] => Array
                        (
                            [file] => 12-05-2012.pdf
                            [fileName] => 12. Mai 2012
                            [filePath] => dir/12-05-2012.pdf
                        )

                    [2] => Array
                        (
                            [file] => 19-05-2012.pdf
                            [fileName] => 19. Mai 2012
                            [filePath] => dir/19-05-2012.pdf
                        )

                )
        )
)
Anmerkung:
Da die hierarchische Auflistung schön der Reihe nach kommen soll, benutze ich das Datum als Key des Arrays. Hab vorhin jedes File in ein Array gespeichert und alles in ein zweistufiges Array gestopft. Nur ging das mit dem Sortieren nicht so gut. Und ja, ich habe auch schon array_multisort() ausprobiert.

Nun komm ich zur Ausgabe.

Hab vorher mal das Array sortiert durch:
PHP:
function deep_ksort(&$arr) {
    ksort($arr);
    foreach ($arr as &$a) {
        if (is_array($a) && !empty($a)) {
            deep_ksort($a);
        }
    }
} 
deep_ksort($posts);

Und nun die Ausgabe als ul - li html:
PHP:
$newestPdf = date("d-m-Y", time());
$currentYear = date("Y", time());

echo '<ul>';
for ($year = $currentYear; $year > 2010; $year--){ // hier zähle ich das aktuelle jahr bis 2010 zurück. das älteste pdf ist im 2011 erstellt worden, also reicht das hier.
    
    if (isset($posts[$year])){
        
        echo "<li>";
        echo $year; // jahr ausgeben, falls im array vorhanden
        echo "</li>";
            
        echo "<ul>";
        for($month = 12; $month > 0; $month--) { // hier das problem: erläuterung unten
            if (isset($posts[$year][$month])){
                
                $actualMonth = date("m", time());
                if($actualMonth == $month) { // wenn der monat der aktuelle monat ist, dann soll es schon offen sein beim seitenaufruf. wenn älter, dann verstecken. wird später per jQuery klickbar gemacht.
                    echo "<li class=\"active\">";
                } else {
                    echo "<li class=\"hidden\">";
                }
                $moOut = $month; // monats-key ersetzen durch monatsnamen
                $moOut = str_replace("10", "Oktober", $moOut);
                $moOut = str_replace("11", "November", $moOut);
                $moOut = str_replace("12", "Dezember", $moOut);
                $moOut = str_replace("1", "Januar", $moOut);
                $moOut = str_replace("2", "Februar", $moOut);
                $moOut = str_replace("3", "März", $moOut);
                $moOut = str_replace("4", "April", $moOut);
                $moOut = str_replace("5", "Mai", $moOut);
                $moOut = str_replace("6", "Juni", $moOut);
                $moOut = str_replace("7", "Juli", $moOut);
                $moOut = str_replace("8", "August", $moOut);
                $moOut = str_replace("9", "September", $moOut);
                
                echo $moOut;
                echo "</li>";
                echo "<ul>";
                    foreach($posts[$year][$month] as $post){ // hier kommt der post raus
                        $thisPdf = explode(".", $post['file']);
                        $thisPdf = $thisPdf[0];
                        $thisPdf = strtotime($thisPdf); // hier noch ein vergleich: wenn das pdf neuer ist als das aktuelle datum, dann noch nicht ausgeben. erst wenn das datum dasselbe ist oder älter.
                        if(strtotime($newestPdf) >= $thisPdf) {
                            echo "<li>";
                            echo '<a href="'.$post['filePath'].'">'.$post['fileName'].'</a>'; // das effektive list-element mit der verlinkung zum pdf
                            echo "</li>";
                        }
                    }
                echo "</ul>";
            }
        }
        echo "</ul>";
    }
}
echo '</ul>';

Das Problem ist nun:
Er gibt mit nur die PDF's vom Monat Oktober und November aus. Im Array sind alle drin, welche auch im Ordner selbst sind. Nur bei der Ausgabe des Array happerts:


  • 2012
    • Oktober
      • 27. Oktober 2012
      • 06. Oktober 2012
    • November
      • 03. November 2012
      • 10. November 2012


Zum debuggen habe ich innerhalb der for() Schleife mal folgendes ausgegeben:
PHP:
for($month = 12; $month > 0; $month--) {
           echo $posts[$year][$month];
            if (isset($posts[$year][$month])){

Dann gibt es mir folgendes aus:

Code:
[LIST]
[*]2012
[LIST]
[*]Notice: Undefined offset: 12 in /var/www/htdocs/pdf_archive.php on line 80 
Array 
[*]November
[LIST]
[*]03. November 2012 
[*]10. November 2012 
[/LIST]
Array 
[*]Oktober
[LIST]
[*]27. Oktober 2012 
[*]06. Oktober 2012 
[/LIST]
 Notice: Undefined offset: 9 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 8 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 7 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 6 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 5 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 4 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 3 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 2 in /var/www/htdocs/pdf_archive.php on line 80 
Notice: Undefined offset: 1 in /var/www/htdocs/pdf_archive.php on line 80    
[/LIST]
    
[/LIST]
Also scheint es mir, als findet er, dass die anderen Arrays innerhalb vom Array '2012' nicht als Arrays erkennt.

Hat irgendwer eine Ahnung, was das Problem sein könnte?

Bin mit meinem Latein am Ende. Hab überall debuggt und alles mehrmals neu aufgebaut und auf verschiedene Weise, aber nichts.
Änderungen bei der for()-Schleife, wie die Monate raufrechnen statt runterrechnen usw. ging nicht.


Bin für jede Hilfe dankbar.


Gruss
cromafia007
 
Zuletzt bearbeitet:
Hi.

Hilft das hier?

PHP:
<?php

function generateRandomData($amount = 1000)
{
    $data = array();

    for ($i = 0; $i < $amount; $i++) {
        $year = sprintf('%s', 2012 - rand(0, 5));
        $moOut = sprintf('%02s', 12 - rand(0, 11));
        $day = sprintf('%02s', 28 - rand(0, 27));

        $file = $day . '-' . $moOut . '-' . $year . '.pdf';
        $filePath = 'dir/' . $file;

        $moOut = str_replace("10", "Oktober", $moOut);
        $moOut = str_replace("11", "November", $moOut);
        $moOut = str_replace("12", "Dezember", $moOut);
        $moOut = str_replace("01", "Januar", $moOut);
        $moOut = str_replace("02", "Februar", $moOut);
        $moOut = str_replace("03", "März", $moOut);
        $moOut = str_replace("04", "April", $moOut);
        $moOut = str_replace("05", "Mai", $moOut);
        $moOut = str_replace("06", "Juni", $moOut);
        $moOut = str_replace("07", "Juli", $moOut);
        $moOut = str_replace("08", "August", $moOut);
        $moOut = str_replace("09", "September", $moOut);

        $fileName = $day . '. ' . $moOut . ' ' . $year;

        $data[] = array(
            'file' => $file,
            'fileName' => $fileName,
            'filePath' => $filePath
        );
    }

    return $data;
}

function sortAndGroupData(array $data)
{
    $dataNew = array();

    // Sort

    usort($data, function ($a, $b) {
        list($da, $ma, $ya) = explode('-', substr($a['file'], 0, 10));
        list($db, $mb, $yb) = explode('-', substr($b['file'], 0, 10));
        return (-1) * strcmp($ya.$ma.$da, $yb.$mb.$db);
    });

    // Group

    foreach ($data as $entry) {
        $year  = (int) substr($entry['file'], 6, 4);
        $month = (int) substr($entry['file'], 3, 2);

        if (!array_key_exists($year, $dataNew)) {
            $dataNew[$year] = array();
        }

        if (!array_key_exists($month, $dataNew[$year])) {
            $dataNew[$year][$month] = array();
        }

        $dataNew[$year][$month][] = $entry;
    }

    return $dataNew;
}

function e($s)
{
    return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

$data = sortAndGroupData(generateRandomData());

?><!DOCTYPE html>

<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>title</title>
    </head>

    <body>



<ul>
<?php foreach ($data as $year => $yearData) : ?>
    <li>
        <?php echo e($year) ?>
        <ul>
        <?php foreach ($yearData as $month => $entries) : ?>
            <li>
                <?php echo e($month) ?>
                <ul>
                <?php foreach ($entries as $entry) : ?>
                    <li><?php echo e($entry['fileName']) ?></li>
                <?php endforeach; ?>
                </ul>
            </li>
        <?php endforeach; ?>
        </ul>
    </li>
<?php endforeach ; ?>
</ul>




    </body>

</html>
 
Hi.
Hilft das hier?
PHP:
<ul>
<?php foreach ($data as $year => $yearData) : ?>
    <li>
        <?php echo e($year) ?>
        <ul>
        <?php foreach ($yearData as $month => $entries) : ?>
            <li>
                <?php echo e($month) ?>
                <ul>
                <?php foreach ($entries as $entry) : ?>
                    <li><?php echo e($entry['fileName']) ?></li>
                <?php endforeach; ?>
                </ul>
            </li>
        <?php endforeach; ?>
        </ul>
    </li>
<?php endforeach ; ?>
</ul>

Der Part mit der Ausgabe hat mir schon geholfen.
Da hats wohl beim Ausgeben des Arrays gehappert.

Vielen Dank!
 
Zurück
Oben