mitmario.dev

Zuordnungen

PHP Sandbox 3 Min Lesezeit 4 BeispieleLektion 2 von 7

Bis hierher hatten die Einträge einer Liste Nummern. Das ist praktisch, solange die Reihenfolge die Information ist, also bei einer Einkaufsliste oder einer Obstkiste. Sobald es um die Angaben zu einer Sache geht, ist eine Nummer aber eine Zumutung: Was war noch mal $person[2]?

Schlüssel und Wert

Ein Name statt einer Nummer
<?php

$person = [
    "name" => "Mia",
    "alter" => 34,
    "beruf" => "Tischlerin",
];

echo $person["name"], " ist ", $person["alter"], "\n";

foreach ($person as $feld => $wert) {
    echo "$feld: $wert\n";
}

// Nachtragen geht wie bei einer Liste, nur mit Namen:
$person["stadt"] = "Bremen";
echo "Neu dazu: ", $person["stadt"], "\n";

Deshalb darf statt der Nummer ein Name stehen. Die Schreibweise dafür ist der Doppelpfeil =>, links der Schlüssel, rechts der Wert. Beim Zugriff schreibst du den Schlüssel in die eckigen Klammern, so wie vorher die Nummer.

Aus Lektion 4.5 ist dir die Form schon begegnet, dort waren es Warennamen und Preise. Neu ist hier nur, dass sie einen Namen bekommt und dass wir sie ernst nehmen: In PHP ist das die Standard-Datenstruktur. Was in anderen Sprachen ein Objekt, ein Dictionary oder eine Map wäre, ist hier ein Array mit Textschlüsseln.

foreach mit Doppelpfeil geht darüber genauso wie über eine nummerierte Liste, und das Nachtragen eines Feldes sieht aus wie das Anhängen an eine Liste, nur mit Namen statt leeren Klammern.

Und noch etwas, das dir später auffallen wird: die Reihenfolge bleibt. Ein Array behält in PHP immer die Reihenfolge, in der die Einträge hineingekommen sind, auch mit Textschlüsseln. In manchen anderen Sprachen ist das nicht so, dort ist eine solche Sammlung ausdrücklich ungeordnet.

Ein Schlüssel ist nicht immer, was er scheint

Schlüssel, die zusammenfallen
<?php

$seltsam = [
    "1" => "erster",
    1 => "zweiter",
    "01" => "dritter",
    true => "vierter",
];

// Vier Zeilen hingeschrieben. Wie viele kommen an?
var_dump($seltsam);
echo "Es sind ", count($seltsam), ".\n";

Jetzt eine Eigenheit, über die man einmal gestolpert sein muss. PHP kennt als Schlüssel nur zwei Sorten: ganze Zahlen und Text. Alles andere wird stillschweigend umgewandelt.

Im Beispiel stehen vier Zeilen da, und übrig bleiben zwei Einträge. Der Text "1", die Zahl 1 und true landen alle drei auf demselben Schlüssel, nämlich der Zahl 1, und der letzte gewinnt. Deshalb steht dort am Ende vierter. Nur "01" überlebt als eigener Textschlüssel, weil eine führende Null aus dem Text keine saubere Zahl macht.

Im Alltag begegnet dir das selten, aber wenn, dann in der unangenehmen Form: Werte aus einem Formular kommen als Text an, und ein Feld, das "1" heißt, sitzt danach auf einem Zahlenschlüssel. Merk dir einfach: Zahlenschlüssel und Textschlüssel sind nicht zwei Welten, PHP schiebt zwischen ihnen hin und her.

Zwei Fragen, die verschieden sind

isset schweigt bei null
<?php

$formular = [
    "name" => "Mia",
    "newsletter" => null,
];

echo "Frage 1: liegt unter newsletter ein Wert?\n";
var_dump(isset($formular["newsletter"]));

echo "Frage 2: gibt es den Schluessel newsletter ueberhaupt?\n";
var_dump(array_key_exists("newsletter", $formular));

echo "Und bei einem Schluessel, den es wirklich nicht gibt:\n";
var_dump(isset($formular["telefon"]));
var_dump(array_key_exists("telefon", $formular));

isset() und array_key_exists() sehen aus, als täten sie dasselbe, und in neun von zehn Fällen kommt auch dasselbe heraus. Der zehnte Fall ist der interessante.

isset() fragt: liegt hier ein Wert, der nicht null ist? array_key_exists() fragt: gibt es den Schlüssel? Bei einem Feld, das ausdrücklich auf null gesetzt wurde, sagt das erste false und das zweite true.

Das ist keine Erbsenzählerei. In Abschnitt 14 kommen Datenbankzeilen genau so zurück: eine Spalte ohne Eintrag wird zu null, der Schlüssel ist trotzdem da. Wer dann mit isset() prüft, kann „Feld nicht ausgefüllt” nicht von „Feld gibt es gar nicht” unterscheiden.

Faustregel: Willst du wissen, ob du mit dem Wert arbeiten kannst, nimm isset(). Willst du wissen, ob das Feld existiert, nimm array_key_exists().

Der Ersatzwert

Der Ersatzwert
<?php

$person = ["name" => "Mia"];

echo "Ohne Absicherung:\n";
echo "Stadt: ", $person["stadt"], "\n";

echo "\nMit Absicherung:\n";
echo "Stadt: ", $person["stadt"] ?? "(unbekannt)", "\n";

// ?? greift auch, wenn der Wert null ist:
$leer = ["stadt" => null];
echo "Stadt: ", $leer["stadt"] ?? "(unbekannt)", "\n";

Aus Lektion 5.1 weißt du schon, was ein Zugriff auf einen Schlüssel anrichtet, den es nicht gibt: eine Warnung auf dem Fehlerkanal, null als Wert, und das Programm läuft munter weiter. Sieh dir im Beispiel den ersten Block an, dort passiert genau das.

Der kurze Weg heraus ist das Fragezeichenpaar ?? aus Lektion 3.6. Es liefert den Wert, wenn einer da ist, und sonst deinen Ersatz, ohne ein Wort auf dem Fehlerkanal. Wichtig dabei: ?? reagiert nicht nur auf einen fehlenden Schlüssel, sondern auch auf null. Es stellt also dieselbe Frage wie isset(), nur dass es gleich einen Wert zurückgibt.

Ab Abschnitt 11 wirst du das in fast jeder Zeile schreiben. Denn welche Felder ein Formular mitschickt, entscheidet nicht dein Code, sondern der Besucher, und ein Häkchen, das niemand angeklickt hat, kommt schlicht nicht an.

Zum Mitnehmen

Eine Nummer sagt dir nichts darüber, was an dieser Stelle liegt. Ein Name schon. Genau das ist ein assoziatives Array, und es ist die Form, in der ab Abschnitt 11 jede Formulareingabe und ab Abschnitt 14 jede Datenbankzeile bei dir ankommt.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.