Forum: PC-Programmierung PHP Foreach Loop sortieren


von Helge M. (helgemattig)


Lesenswert?

Hi,

Ich habe folgenden Code
1
foreach (glob("database/*.php") as $filename)
2
{
3
    include $filename;
4
//Here i'm doing stuff with the files content
5
}

Ich hätte gerne eine möglichkeit zu sortieren das entweder die ältesten 
oder neuesten Einträge/Datein als erstes angezeigt werden.

Kann mir jemand sagen wie ich das hinbekomme? (Am besten direkt
den codeschnippsel entsprechend anpassen.)

Edit:

In den Datein befindet sich immer folgendes
$item_id = "1"; (bzw. 2,3,4,5 etc.)
Danach könnte man ggf. auch sortieren.

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

Helge M. schrieb:
> Ich hätte gerne eine möglichkeit zu sortieren das entweder die ältesten
> oder neuesten Einträge/Datein als erstes angezeigt werden.

Zwei Schleifen. Einmal über alle Einträge laufen, einmal "stat" für 
jeden Dateinamen machen, das in ein Array speichern.
Das kannst du dann nach Größe, Datum, Besitzer, Inode-Nr oder sonstwas 
sortieren.
Zweite Schleife dann über das Sortierte Array.

von Herbert B. (Gast)


Lesenswert?

Du baust dir eine Hilfsfunktion sortByModTime( $einArray) die das 
sortierte Array zurückliefert. Als Parameter erhält die Funktion ein 
Array mit Dateinamen, also das was glob liefert.

Die Änderungszeit einer Datei kannt du mit
 https://www.php.net/manual/en/function.filemtime.php
rausbekommen. Nach der Zeit sortierst die files. Du baust dir einfach 
ein neues array als Assoziatives Array, mit der Zeit als Index, nach dem 
sortiert du wenn du das Array das als Paramter durchgelaufen bist.

statt glob(....)  rufst du dann sortByModTime(glob(...)) auf.

Wenn nach dieser id-Geschichte sorotert werden soll, schreibst du dir 
eine weitere Funktion dafür.

von Weingut P. (weinbauer)


Lesenswert?

Herbert B. schrieb:
> Du baust dir eine Hilfsfunktion sortByModTime( $einArray) die das
> sortierte Array zurückliefert. Als Parameter erhält die Funktion ein
> Array mit Dateinamen, also das was glob liefert.
>
> Die Änderungszeit einer Datei kannt du mit
>  https://www.php.net/manual/en/function.filemtime.php
> rausbekommen. Nach der Zeit sortierst die files. Du baust dir einfach
> ein neues array als Assoziatives Array, mit der Zeit als Index, nach dem
> sortiert du wenn du das Array das als Paramter durchgelaufen bist.
>
> statt glob(....)  rufst du dann sortByModTime(glob(...)) auf.
>
> Wenn nach dieser id-Geschichte sorotert werden soll, schreibst du dir
> eine weitere Funktion dafür.

naja, die Zeit als Index könnte doppelte Einträge haben die dann 
überschrieben würden.
Wenn, dann muss das n Array im Array werden ...

[12345]['file1','file2', ...]

von Εrnst B. (ernst)


Lesenswert?

Wobei die Anforderung schon ein wenig schräg ist.
Wenn ich alle Dateien in einem Verzeichnis include, und dabei eine 
bestimmte Reihenfolge brauche, dann vmtl. wegen Abhängigkeiten zwischen 
den Dateien. Und die Abhängigkeiten würde ich ungern dadurch definieren, 
wann ich das letzte Mal mit dem Editor an der Datei war.
Besser:

database/01_basis.php
database/10_erweiterung.php
database/99_ende.php
etc.

glob() sortiert direkt alphabetisch (solange man das nicht explizit 
anders haben will) und schon hat man das Problem erschlagen.

von Helge M. (helgemattig)


Lesenswert?

Danke für die Antworten, ich bin allerdings etwas überfordert damit.
Kann mir vllt. jemand den Codeschnippsel oben entsprechend anpassen?

> glob() sortiert direkt alphabetisch (solange man das nicht explizit
> anders haben will) und schon hat man das Problem erschlagen.

Ich habe derzeit

database/item1.php
database/item2.php
...

Die Sortierung scheint entsprechend zu funktionieren, allerdings würde 
ich gerne die Reihenfolge umkehren und das
scheint über glob nicht zu funktionieren oder?

> Wenn nach dieser id-Geschichte sorotert werden soll, schreibst du dir
> eine weitere Funktion dafür.

> naja, die Zeit als Index könnte doppelte Einträge haben die dann
> überschrieben würden.
> Wenn, dann muss das n Array im Array werden ...

Vllt sollte man dann doch besser hier nach sortieren?

> In den Datein befindet sich immer folgendes
> $item_id = "1"; (bzw. 2,3,4,5 etc.)

: Bearbeitet durch User
von Helge M. (helgemattig)


Lesenswert?

Okay ich hab es jetzt doch hinbekommen.
1
//Grab and sort Items
2
if($display_latest_on_top == FALSE)
3
{
4
//Oldest First
5
$myarray = glob("database/*.php");
6
usort($myarray, function($a,$b){
7
$results = filemtime($a) - filemtime($b); 
8
return $results;
9
});
10
}
11
if($display_latest_on_top == TRUE)
12
{
13
//Latest First
14
$myarray = glob("database/*.php");
15
usort($myarray, function($a,$b){
16
$results = filemtime($b) - filemtime($a); 
17
return $results;
18
});
19
}
20
//Display Items
21
foreach ($myarray as $filename)
22
{
23
include $filename;
24
//Here i'm doing stuff with the files content
25
}

Edit:

Sehr hilfreich war hierbei
https://stackoverflow.com/questions/20930122/sort-glob-by-creation-date

: Bearbeitet durch User
von Helge M. (helgemattig)


Lesenswert?

Eigentlich funktioniert das gut, nur leider handelt es sich um das 
letzte Änderungsdatum und nicht um das Erstellungsdatum der Datei. Eine 
kurze recherche ergab das es unter unix/linux wohl kein Erstellungsdatum 
gibt.

Daher würde ich dann doch lieber hiernach sortieren:

> In den Datein befindet sich immer folgendes
> $item_id = "1"; (bzw. 2,3,4,5 etc.)

Eigentlich kann das ja wirklich nur eine Kleinigkeit sein aber ich weiß 
grad nicht wie. Kann mir jemand den Code aus meinem letzten post 
entsprechend anpassen? :)

von Helge M. (helgemattig)


Lesenswert?

Problem solved!
1
<?php
2
//Sort Method "Item Id"
3
if($sort_method == "item_id")
4
{
5
//Grab and Sort Items
6
$myarray = glob("database/*.php");
7
foreach ($myarray as $filename)
8
{
9
include $filename;
10
$item_id_string .= "$item_id,";
11
}
12
$item_id_string = substr($item_id_string, 0, -1);
13
$item_id_string = explode(',', $item_id_string);
14
15
if($display_latest_on_top == FALSE)
16
{
17
//Oldest First
18
usort($item_id_string, function($a,$b){
19
return $a - $b; 
20
});
21
}
22
if($display_latest_on_top == TRUE)
23
{
24
//Latest First
25
usort($item_id_string, function($a,$b){
26
return $b - $a; 
27
});
28
}
29
30
//Display Items
31
foreach ($item_id_string as $item_id) 
32
{
33
include ("database/item$item_id.php");
34
//Here i'm doing stuff with the files content
35
}
36
}
37
38
if($sort_method == "last_edited")
39
{
40
//Grab and sort Items
41
if($display_latest_on_top == FALSE)
42
{
43
//Oldest First
44
$myarray = glob("database/*.php");
45
usort($myarray, function($a,$b){
46
$results = filemtime($a) - filemtime($b); 
47
return $results;
48
});
49
}
50
if($display_latest_on_top == TRUE)
51
{
52
//Latest First
53
$myarray = glob("database/*.php");
54
usort($myarray, function($a,$b){
55
$results = filemtime($b) - filemtime($a); 
56
return $results;
57
});
58
}
59
//Display Items
60
foreach ($myarray as $filename)
61
{
62
include $filename;
63
//Here i'm doing stuff with the files content
64
}
65
}
66
?>

von Εrnst B. (ernst)


Lesenswert?

Helge M. schrieb:
> Die Sortierung scheint entsprechend zu funktionieren, allerdings würde
> ich gerne die Reihenfolge umkehren und das
> scheint über glob nicht zu funktionieren oder?

Reihenfolge umkehren geht mit "array_reverse".
Wenn dir das reicht, bleibt's beim Dreizeiler:
1
foreach (array_reverse(glob("database/*.php")) as $filename) {
2
  include $filename;
3
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.