Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Artfiles.de
Bietet Serviceorientierte Internetdienstleistungen...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains und...
https://www.Hosterplus.de
 
 
 

Arrays mit von PHP zur verfügung gestellten Funktionen sortieren

Sie befinden sich: Home > Php > Arrays mit von PHP zur verfügung gestellten Funktionen sortieren

Arrays sortieren gehört zu den Aufgaben, die PHP einem weitgehend abnimmt: Für fast jeden Fall gibt es bereits eine passende Funktion. Der Unterschied liegt im Detail, denn manche Funktionen erhalten die Schlüssel, andere vergeben sie neu. Dieser Artikel ordnet die Sortierfunktionen, zeigt eigene Regeln mit usort und dem Spaceship-Operator und geht auf Sonderfälle wie Umlaute und mehrstufige Kriterien ein.

Unsortierter Kartenstapel neben der Größe nach geordneten Karten als Symbolbild für das Sortieren von Arrays
<?php
$array = $array2 = array("bild12.gif", "bild10.gif",
        "bild2.gif", "bild1.gif");
sort($array);
echo "<i>Ausgabe von \$array, Standard mit sort()</i><br>";
echo '<pre>',print_r($array,true),'</pre>';
natsort($array2);
echo "<br><i>Beispiel von \$array2, natürlich
        mit natsort()</i><br>";
echo '<pre>',print_r($array2,true),'</pre>';
?>

Dieses Programm liefert folgende Ausgabe :

Ausgabe von $array, Standard mit sort()
Array
(
[0] => bild1.gif
[1] => bild10.gif
[2] => bild12.gif
[3] => bild2.gif
)

Beispiel von $array2, natürlich mit natsort()
Array
(
[3] => bild1.gif
[2] => bild2.gif
[1] => bild10.gif
[0] => bild12.gif
)

Es ist einfach zu erkennen das die natürliche Sortierung einer im Alltag üblichen gleicht. Betriebsysteme sortieren gelegentlich Dateien nach der Standardmethode so das es Anfängern oft schwer füllt Dateien zu finden.

Um Arrays sortieren zu können die über Feldindizes verfügen findet die Funktion sort() anwendung. Im nachfolgenden Beispiel verwende ich eine foreach Schleife um das Array auszugeben.

Beispiel mit sort():

Sortierung von kleiner nach größer auf den Feldinhalten bezogen und Schlüsselassoziationen werden nicht beibehalten.

<?php
$text = array("Ich", "bin", "ein", "testtext");
sort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>
Das sortierte Array würde wie folgt ausgegeben.

Ausgabe mit sort():

text[0] = Ich
text[1] = bin
text[2] = ein
text[3] = testtext

Um in umgekehrter Reihenfolge (absteigend) zu sortieren, wird die PHP Funktion rsort() verwendet.

Beispiel für rsort():

Sortierung von größer nach kleiner auf den Feldinhalten bezogen und Schlüsselassoziationen werden nicht beibehalten.

<?php
$text = array("Ich", "bin", "ein", "testtext");
rsort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>
Für das rsort() Beispiel sähe die Ausgabe dann so aus.

Die Ausgabe mit rsort():

text[0] = testtext
text[1] = ein
text[2] = bin
text[3] = Ich

Da PHP die Möglichkeit bietet assoziative Feldindizes zu verwenden gibt es eine spezielle Funktion ( inclusive einer umgekehrt sortierenden Funktion ) um diese zu sortieren.

Beispiel mit ksort():

Array sortiert von kleiner nach größer auf die Feldindizes bezogen und Schlüsselassoziationen werden beibehalten.

<?php
$text = array("d"=>"Ich", "a"=>"bin",
            "c"=>"ein", "b"=>"testtext");
ksort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>

Sortiert ausgegeben mit ksort():

text[a] = bin
text[b] = testtext
text[c] = ein
text[d] = Ich

Beispiel mit krsort():

Array sortiert von größer nach kleiner auf die Feldindizes bezogen und Schlüsselassoziationen werden beibehalten.

<?php
$text = array("d"=>"Ich", "a"=>"bin",
            "c"=>"ein", "b"=>"testtext");
krsort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>

Umgekehrt sortierte Ausgabe mit krsort():

text[d] = Ich
text[c] = ein
text[b] = testtext
text[a] = bin

Grade bei Verwendung von assoziativen Arrays kommt es häufiger vor das nicht nach Indizes sortiert werden soll, sondern nach den Feldinhalten selber. Um dies zu erreichen verwendet man asort() oder umgekehrt sortierend arsort()

Beispiel mit asort():

Sortierung von kleiner nach größer auf den Feldinhalten bezogen und Schlüsselassoziationen werden beibehalten.

<?php
$text = array("d"=>"Ich", "a"=>"bin",
                "c"=>"ein", "b"=>"testtext");
asort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>

Sortiert ausgegeben mit asort():

text[d] = Ich
text[a] = bin
text[c] = ein
text[b] = testtext

Beispiel mit arsort():

Sortierung von größer nach kleiner auf den Feldinhalten bezogen und Schlüsselassoziationen werden beibehalten.

<?php
$text = array("d"=>"Ich", "a"=>"bin",
                "c"=>"ein", "b"=>"testtext");
arsort($text);
foreach ($text as $key => $val) {
    echo "text[" . $key . "] = " . $val.'<br>';
}
?>

Umgekehrt sortierte Ausgabe mit arsort():

text[b] = testtext
text[c] = ein
text[a] = bin
text[d] = Ich

Eine Beschreibung der Funktionen uksort() und uasort(), die ebenfalls von PHP bereit gestellt werden, bei denen man eigene Algorithmen angeben kann nach denen die Arrays sortiert werden sollen, würden den Rahmen dieser Abhandlung sprengen, zumal hierfür Vergleichsfunktionen geschrieben werden müssten.

Man kann ein Array auch über einen so genannten Bubblesort sortieren. Dieser verbraucht aber Ressourcen und man sollte lieber die von PHP zur Verfügung gestellten Funktionen verwenden. Wenn Sie noch weitere Fragen zu der Sortierung von einen Array haben, so können Sie direkt in unserem Forum Ihre Frage stellen.

Auf der nachfolgenden Seite wird Ihnen erklärt, wie Sie ein mehrdimensionales Array sortieren können. Es wird hierzu die PHP Function array_multisort() verwendet.

Arrays sortieren: die Funktionen im Überblick

PHP bringt eine ganze Familie von Sortierfunktionen mit, und auf den ersten Blick sehen viele davon austauschbar aus. Sie unterscheiden sich aber in drei wichtigen Punkten: ob sie nach Wert oder Schlüssel sortieren, ob sie die Schlüssel-Wert-Beziehung erhalten und in welcher Richtung sie arbeiten. Wenn Sie diese drei Achsen einmal verinnerlicht haben, wissen Sie bei jedem Problem sofort, zu welcher Funktion Sie greifen müssen. Es lohnt sich also, einen Moment Zeit in eine kleine Übersichtstabelle zu investieren, bevor Sie im Code blind eine Funktion auswählen.

FunktionSortiert nachRichtungSchlüssel erhalten
sort()Wertaufsteigendnein (neu durchnummeriert)
rsort()Wertabsteigendnein
asort()Wertaufsteigendja
arsort()Wertabsteigendja
ksort()Schlüsselaufsteigendja
krsort()Schlüsselabsteigendja
usort()Callbackfreinein
uasort()Callbackfreija
uksort()Callback (Schlüssel)freija
natsort()Wert (natürlich)aufsteigendja
natcasesort()Wert (case-insensitive)aufsteigendja

Die Eselsbrücke ist einfach. Ein vorangestelltes a steht für "associative", die Schlüssel bleiben also intakt. Ein k sortiert nach den Keys statt nach den Werten. Ein r dreht die Richtung um, und ein u übergibt die Entscheidung an Ihre eigene Callback-Funktion. Sobald sich diese vier Buchstaben in Fleisch und Blut übergegangen sind, müssen Sie die Tabelle nicht mehr nachschlagen.

Stable Sort seit PHP 8.0

Ein Detail, das vor PHP 8.0 viele Entwicklerinnen und Entwickler in den Wahnsinn getrieben hat, ist die Stabilität des Sortier-Algorithmus. Eine Sortierung gilt als stabil, wenn zwei Elemente mit gleichem Sortierwert nach dem Sortieren noch in der gleichen Reihenfolge stehen wie davor. Bis PHP 7.4 war das nicht garantiert. Seit PHP 8.0 sind alle eingebauten Sortierfunktionen stabil, was Ihren Code auf einen Schlag deutlich vorhersehbarer macht.

<?php
declare(strict_types=1);

$leute = [
    ['name' => 'Anna',  'team' => 'A'],
    ['name' => 'Bernd', 'team' => 'B'],
    ['name' => 'Clara', 'team' => 'A'],
    ['name' => 'Dirk',  'team' => 'B'],
];

/* Sortieren nach Team. Innerhalb eines Teams bleibt die
   Original-Reihenfolge erhalten, weil PHP 8 stabil sortiert. */
usort($leute, fn($a, $b) => $a['team'] <=> $b['team']);

foreach ($leute as $l) {
    echo $l['team'] . ': ' . $l['name'] . "
";
}
/* A: Anna
   A: Clara
   B: Bernd
   B: Dirk */

Was bedeutet das konkret für sich? Sie können jetzt mehrstufig sortieren, indem Sie erst nach dem zweitwichtigsten Kriterium und dann nach dem wichtigsten sortieren. Vor PHP 8 war das ein Glücksspiel und brauchte Tricks wie eine zusammengesetzene Vergleichsfunktion. Heute reicht oft ein zweimaliges usort, und Sie bekommen genau das Ergebnis, das Sie erwartest.

Spaceship-Operator: das Schweizer Taschenmesser für usort

Wenn Sie eigene Sortierlogik mit usort umsetzen, führt kein Weg am Drei-Wege-Vergleichsoperator vorbei. Der Spaceship-Operator <=> liefert genau das, was eine Vergleichsfunktion braucht: -1, 0 oder 1. Damit ist Schluss mit umständlichen if-Anweisungen und manuellen Subtraktionen. Eine Zeile reicht für den Standardfall.

<?php
declare(strict_types=1);

$zahlen = [42, 7, 100, 23, 1];

/* Aufsteigend sortieren mit Spaceship-Operator. */
usort($zahlen, fn(int $a, int $b): int => $a <=> $b);

print_r($zahlen);
/* Array ( [0] => 1 [1] => 7 [2] => 23 [3] => 42 [4] => 100 ) */

/* Absteigend? Einfach die Operanden tauschen. */
usort($zahlen, fn(int $a, int $b): int => $b <=> $a);

Der große Vorteil gegenüber der alten Subtraktionsschreibweise $a - $b ist die Sicherheit. Bei sehr großen Zahlen oder Floats konnte die Subtraktion Überläufe und Genauigkeitsfehler produzieren. Der Spaceship-Operator umgeht das komplett, weil PHP intern mit den richtigen Vergleichsregeln arbeitet. Auch für Strings, Datumswerte und Arrays liefert <=> sinnvolle Ergebnisse.

Objekte nach Property sortieren

Sobald Ihre Daten in Objekte gewandert sind, brauchen Sie eine Vergleichsfunktion, die in das Objekt hineinschaut. Genau dafür ist usort da. Sie greifen auf die gewünschte Property zu und geben das Ergebnis des Spaceship-Vergleichs zurück. Mit kurzen Pfeilfunktionen wird das richtig elegant.

<?php
declare(strict_types=1);

class Produkt
{
    public function __construct(
        public readonly string $name,
        public readonly float $preis,
    ) {}
}

$katalog = [
    new Produkt('Tastatur', 79.90),
    new Produkt('Maus',     19.50),
    new Produkt('Monitor',  299.00),
    new Produkt('Webcam',   59.00),
];

/* Sortieren nach Preis aufsteigend. */
usort($katalog, fn(Produkt $a, Produkt $b): int => $a->preis <=> $b->preis);

foreach ($katalog as $p) {
    echo $p->name . ': ' . number_format($p->preis, 2, ',', '.') . " €
";
}

Der gleiche Trick funktioniert mit jeder öffentlichen Property und mit Methoden, die einen vergleichbaren Wert zurückgeben. Ein $a->getCreatedAt() <=> $b->getCreatedAt() ist genauso erlaubt. Achten Sie nur darauf, dass die Methode pure ist und keine Seiteneffekte hat, denn sie wird während des Sortierens sehr oft aufgerufen.

Arrays sortieren nach mehreren Kriterien

In der echten Welt wollen Sie selten nur nach einem Kriterium sortieren. Eine Liste von Mitarbeitenden soll zum Beispiel zuerst nach Abteilung und innerhalb jeder Abteilung nach Nachname sortiert werden. Mit dem Spaceship-Operator und dem Null-Coalescing-Operator ?? wird daraus ein lesbarer Einzeiler.

<?php
declare(strict_types=1);

$mitarbeitende = [
    ['abteilung' => 'IT',     'nachname' => 'Schmidt'],
    ['abteilung' => 'HR',     'nachname' => 'Mueller'],
    ['abteilung' => 'IT',     'nachname' => 'Becker'],
    ['abteilung' => 'HR',     'nachname' => 'Anders'],
    ['abteilung' => 'Sales',  'nachname' => 'Krause'],
];

usort($mitarbeitende, function (array $a, array $b): int {
    return ($a['abteilung'] <=> $b['abteilung'])
        ?: ($a['nachname']  <=> $b['nachname']);
});

foreach ($mitarbeitende as $m) {
    echo $m['abteilung'] . ' / ' . $m['nachname'] . "
";
}

Das Muster $primaer ?: $sekundaer nutzen die Tatsache aus, dass der Spaceship-Operator bei Gleichheit eine Null liefert. Eine Null ist falsy, also greift der zweite Operand. Genauso können Sie auch ein drittes oder viertes Sortierkriterium dranhängen.

Parallele Sortierung mit array_multisort

Manchmal haben Sie nicht eine Liste von Datensätzen, sondern mehrere parallele Arrays, die zusammen einen Datensatz bilden. Klassischer Fall: Eine Spalte mit Namen, eine mit Punkten, beide gleich lang. Wenn Sie jetzt nach den Punkten sortieren, soll die Reihenfolge der Namen mitwandern. Genau dafür ist array_multisort gemacht.

<?php
declare(strict_types=1);

$namen   = ['Anna', 'Bernd', 'Clara', 'Dirk'];
$punkte  = [78, 92, 65, 88];

/* Sortiere nach Punkten absteigend, Namen wandern mit. */
array_multisort($punkte, SORT_DESC, SORT_NUMERIC, $namen);

foreach ($namen as $i => $name) {
    echo $name . ': ' . $punkte[$i] . " Punkte
";
}

Sie können auch mehrere Sortierachsen kombinieren, indem Sie jeweils das nächste Array, gefolgt von einem Richtungs-Flag, an array_multisort übergeben. Die Reihenfolge entscheidet über die Priorität. Erst wird nach dem ersten Array sortiert, bei Gleichstand nach dem zweiten und so weiter. In der Praxis ist usort mit dem Multi-Key-Pattern aus dem vorherigen Abschnitt aber meistens lesbarer, weil dort der Bezug zwischen den Feldern eines Datensatzes klarer bleibt.

Locale-aware sortieren mit dem Collator

Sobald deutsche Umlaute, französische Akzente oder spanische Sonderzeichen ins Spiel kommen, stößt die Standard-Sortierung an ihre Grenzen. sort arbeitet byte-weise und sortiert Ä dann irgendwo hinter Z. Für korrekte sprachabhängige Reihenfolgen brauchen Sie die Collator-Klasse aus der intl-Erweiterung.

<?php
declare(strict_types=1);

$staedte = ['Zwickau', 'Ängelholm', 'Augsburg', 'Oerlinghausen', 'Aachen'];

$collator = new Collator('de_DE');
$collator->sort($staedte);

print_r($staedte);
/* Aachen, Aengelholm, Augsburg, Oerlinghausen, Zwickau */

Achten Sie darauf, dass die intl-Erweiterung auf Ihrem Server installiert ist. Auf den meisten modernen Hostings ist sie Standard, auf manchen Shared-Hosting-Paketen aber leider nicht. Prüfen können Sie das schnell mit extension_loaded('intl').

Arrays sortieren: welche Funktion für welchen Fall?

Wenn Sie jetzt vor einem konkreten Problem stehst, hilft sich vielleicht ein kleiner Entscheidungsbaum. Er fragt sich genau die drei Achsen ab, die wir am Anfang besprochen haben, und führt sich zur passenden Funktion.

flowchart TD
    A[Was sortieren?] --> B{Eigene Logik?}
    B -->|Ja| C[usort/uasort/uksort]
    B -->|Nein| D{Schluessel oder Wert?}
    D -->|Schluessel| E[ksort/krsort]
    D -->|Wert| F{Schluessel erhalten?}
    F -->|Ja| G[asort/arsort]
    F -->|Nein| H[sort/rsort]

Drei Fragen, fünf Endpunkte, und in 90 Prozent der Fälle haben Sie genau die richtige Funktion.

Praxisbeispiel: User-Liste nach Alter und Name

Zum Abschluss bringen wir alles zusammen. Stell sich eine User-Tabelle vor, die Sie in einem Backend ausgeben. Die Anforderung: zuerst die jüngsten zuerst, und bei gleichem Alter alphabetisch nach Vorname.

<?php
declare(strict_types=1);

final class User
{
    public function __construct(
        public readonly string $vorname,
        public readonly int $alter,
    ) {}
}

$users = [
    new User('Tarek', 34),
    new User('Anna',  28),
    new User('Bernd', 28),
    new User('Clara', 41),
    new User('Dirk',  28),
];

/* Erst nach Alter, dann nach Vorname (alphabetisch). */
$collator = new Collator('de_DE');

usort($users, function (User $a, User $b) use ($collator): int {
    return ($a->alter <=> $b->alter)
        ?: $collator->compare($a->vorname, $b->vorname);
});

foreach ($users as $u) {
    printf("%2d Jahre - %s
", $u->alter, $u->vorname);
}

Was hier alles drinsteckt: typsichere Klassen mit Constructor-Promotion, eine kombinierte Sortierung mit ?:, ein Collator für korrekte Umlaut-Behandlung und das stabile Sortierverhalten von PHP 8. Wenn die Daten aus einer Datenbank kommen, würden Sie die Sortierung natürlich besser über ORDER BY ans DBMS auslagern. Sobald Sie aber im PHP-Speicher arbeiten, etwa mit gefilterten Sammlungen, Service-Antworten oder Cached-Daten, ist genau dieses Muster Ihr Werkzeug der Wahl.

Häufige Fragen zum Sortieren von Arrays

Wer Arrays sortieren will, stößt auf vier wiederkehrende Fragen.

1Warum sind nach dem Sortieren meine Schlüssel weg?

Weil sort() die Schlüssel neu vergibt. Wollen Sie die Zuordnung behalten, nehmen Sie asort() für Werte oder ksort() für Schlüssel.

2Wie sortiere ich nach einem Feld in einem Datensatz?

Mit usort() und einer eigenen Vergleichsfunktion. Der Spaceship-Operator <=> liefert dabei genau die drei Werte, die die Funktion erwartet.

3Warum landen Umlaute am Ende der Liste?

Weil die Standardsortierung byteweise vergleicht. Für sprachlich korrekte Reihenfolgen brauchen Sie Collator aus der intl-Erweiterung.

4Bleibt die Reihenfolge gleicher Werte erhalten?

Seit PHP 8.0 ja. Davor war die Sortierung nicht stabil, gleich bewertete Elemente konnten also ihre Position tauschen. Wer ältere Versionen bedient, sollte ein zweites Kriterium ergänzen.

5Kann ich mehrdimensionale Arrays sortieren?

Ja. Beim Arrays sortieren mit usort() vergleichen Sie einfach das gewünschte Feld der Teil-Arrays. Für mehrere Kriterien verketten Sie zwei Vergleiche mit dem Spaceship-Operator.

Wer Arrays sortieren kann, ohne die Schlüssel zu verlieren, hat den größten Stolperstein hinter sich. Jetzt weiter zu den Array-Grundlagen oder die Sortierfunktionen im PHP-Handbuch vergleichen.




weiter zum nächsten Kapitel: if Anweisung in PHP