vixus
vixus

Reputation: 57

Directory listing echo with array filtering

This piece of code works:

<?php
header('Access-Control-Allow-Origin: *');
$imagesDir = '';
$images = glob($imagesDir . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
echo json_encode($images, JSON_UNESCAPED_UNICODE);
?>

I get correct echo of all jpg's in folder which looks like this:

[
    "20180515_xxxxxxx.jpg",
    "20180517_yyyyyyy.jpg",
    "20180519_zzzzzzzz.jpg"
]

But I want to make certain filtering per date (only images which name starts with date >= than today) because all jpg filenames begin with yyyymmdd in their name.

I am trying something like this:

<?php
header('Access-Control-Allow-Origin: *');
$imagesDir = '';
$images = glob($imagesDir . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);

foreach($images as $image) {
    $current_date = date("Ymd");
    $file_date = substr($image, 0, 8);
    if (strcmp($current_date, $file_date)>=0)
    echo json_encode($image, JSON_UNESCAPED_UNICODE);
    }
?>

but I get echo like one huge name made of all images names. I just can't get echo in the same format.

Upvotes: 0

Views: 60

Answers (2)

k0pernikus
k0pernikus

Reputation: 66727

You have an array and you want to filter that.

There's an inbuilt function called array_filter, that takes in an array and you can provide a callback function.

I furthermore recommend transforming the date into an actual DateTime object. Benefit is that you can compare DateTimes in if statements with all the compare operators:

<?php

function parseDate(string $date, $format = "Ymd")
{
    return DateTime::createFromFormat($format, $date)
        ->setTime(0, 0, 0);
}

$today = (new DateTime())->setTime(0, 0);
$filterCallback = function (string $file) use ($today): bool {
    $rawDate = explode("_", $file)[0]; // assumes all your date in the filename are followed up by at least one underscore
    $date = parseDate($rawDate);

    return $date >= $today;
};

$files = [
    "20180515_xxxxxxx.jpg",
    "20180517_yyyyyyy.jpg",
    "20180519_zzzzzzzz.jpg",
    "20250519_zzzzzzzz.jpg",
];

$filteredFiles = array_filter($files, $filterCallback);

foreach ($filteredFiles as $file) {
    echo "$file\n";
}

Will output:

20180519_zzzzzzzz.jpg
20250519_zzzzzzzz.jpg

Upvotes: 0

Zoe Edwards
Zoe Edwards

Reputation: 13687

You’re echoing out a JSON string for each image.

Instead of this:

foreach($images as $image) {
    $current_date = date("Ymd");
    $file_date = substr($image, 0, 8);
    if (strcmp($current_date, $file_date)>=0)
        echo json_encode($image, JSON_UNESCAPED_UNICODE);
}

Try adding an array and collecting them.

$filteredImages = [];
foreach($images as $image) {
    $current_date = date("Ymd");
    $file_date = substr($image, 0, 8);
    if (strcmp($current_date, $file_date)>=0)
        $filteredImages[] = $image
}
echo json_encode($filteredImages, JSON_UNESCAPED_UNICODE);

You could instead of using * in the filter, use today’s date as part of the file name to avoid having to loop through this.

Upvotes: 1

Related Questions