1
0
mirror of https://github.com/php/doc-de.git synced 2026-03-24 07:12:15 +01:00
Files
archived-doc-de/language/types/array.xml
Martin Samesch 7ae9261232 Sync with EN
2025-10-09 21:31:17 +02:00

1628 lines
42 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 094816bd170e26abf0e057dae1cfb498dd6aad88 Maintainer: cmb Status: ready -->
<!-- Reviewed: yes -->
<!-- Rev-Revision: c140370c354496b38b97dfafe2e31f3f8df8bb44 Reviewer: samesch -->
<sect1 xml:id="language.types.array">
<title>Arrays</title>
<para>
Ein <type>Array</type> ist in PHP in Wirklichkeit eine geordnete Map
(Abbildung). Eine Map ist ein Typ, der <emphasis>Werte</emphasis> zu
<emphasis>Schlüsseln</emphasis> zuordnet. Dieser Typ ist für einige
verschiedene Nutzungsarten optimiert. Er kann als ein Array verwendet
werden, als Liste (Vektor), Hash-Tabelle (eine Implementierung einer Map),
Wörterbuch, Sammlung, Stack, Queue (Warteschlange) und wahrscheinlich noch
als vieles anderes. Da ein Wert eines <type>Array</type>s ein weiteres
<type>Array</type> sein kann, sind auch Bäume und mehrdimensionale
<type>Array</type>s möglich.
</para>
<para>
Die Erläuterung dieser Datenstrukturen liegt nicht im Rahmen dieses
Handbuchs, aber wenigstens ein Beispiel für jede ist hier angegeben. Um
weitere Informationen zu erhalten wird auf die immense Literatur zu diesem
weiten Feld verwiesen.
</para>
<sect2 xml:id="language.types.array.syntax">
<title>Syntax</title>
<sect3 xml:id="language.types.array.syntax.array-func">
<title>Spezifizierung mittels <function>array</function></title>
<para>
Ein <type>Array</type> kann durch das Sprachkonstrukt
<function>array</function> erzeugt werden. Dies nimmt eine beliebige
Anzahl kommaseparierter <literal><replaceable>Schlüssel</replaceable>
=&gt; <replaceable>Wert</replaceable></literal>-Paare als Parameter
entgegen.
</para>
<synopsis>
array(
<optional><replaceable>Schlüssel</replaceable> =&gt; </optional><replaceable>Wert</replaceable>,
<optional><replaceable>Schlüssel2</replaceable> =&gt; </optional><replaceable>Wert2</replaceable>,
<optional><replaceable>Schlüssel3</replaceable> =&gt; </optional><replaceable>Wert3</replaceable>,
...
)</synopsis>
<!-- Do not fix the whitespace for the synopsis end element. A limitation of PhD prevents proper trimming -->
<para>
Das Komma nach dem letzten Array-Element ist optional und kann weggelassen
werden. Dies wird üblicherweise in einzeiligen Arrays getan, &dh;.
<literal>array(1, 2)</literal> wird der Schreibweise <literal>array(1, 2,
)</literal> vorgezogen. Andererseits wird bei mehrzeiligen Arrays das
Komma am Ende üblicherweise genutzt, da dies ein einfaches Hinzufügen
weiterer Elemente am Ende erlaubt.
</para>
<note>
<para>
Es gibt eine Kurzform der Array-Syntax, die <literal>array()</literal>
durch <literal>[]</literal> ersetzt.
</para>
</note>
<example>
<title>Ein einfaches Array</title>
<programlisting role="php">
<![CDATA[
<?php
$array1 = array(
"foo" => "bar",
"bar" => "foo",
);
// Verwendung der verkürzten Array-Syntax
$array2 = [
"foo" => "bar",
"bar" => "foo",
];
var_dump($array1, $array2);
?>
]]>
</programlisting>
</example>
<para>
Der <replaceable>Schlüssel</replaceable> kann entweder ein
<type>&integer;</type> oder ein <type>&string;</type> sein. Der
<replaceable>Wert</replaceable> kann beliebige Datentypen annehmen.
</para>
<para xml:id="language.types.array.key-casts">
Zusätzlich werden die folgenden Typkonvertierungen auf den
<replaceable>Schlüssel</replaceable> angewendet:
<itemizedlist>
<listitem>
<simpara>
<type>String</type>s, die einen gültigen dezimalen <type>Int</type>
enthalten, werden zum entsprechenden <type>Int</type> umgewandelt, es
sei denn, der Zahl ist ein <literal>+</literal>-Zeichen vorangestellt.
Beispielsweise wird der Schlüssel <literal>"8"</literal> tatsächlich
unter <literal>8</literal> gespeichert. Andererseits wird
<literal>"08"</literal> nicht umgewandelt, da dies kein gültiger
Ganzzahlwert ist.
</simpara>
</listitem>
<listitem>
<simpara>
<type>Float</type>s werden ebenfalls zu <type>Int</type> umgewandelt,
was ein Abschneiden des Dezimalbruchs zur Folge hat. Beispielsweise
wird der Schlüssel <literal>8.7</literal> als <literal>8</literal>
gespeichert.
</simpara>
</listitem>
<listitem>
<simpara>
<type>Bool</type>s werden ebenfalls zu <type>Int</type> umgewandelt,
&dh; der Schlüssel &true; wird unter <literal>1</literal> gespeichert
und der Schlüssel &false; unter <literal>0</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
<type>Null</type> wird zu einem leeren String umgewandelt, &dh; der
Schlüssel <literal>null</literal> wird tatsächlich unter
<literal>""</literal> gespeichert.
</simpara>
</listitem>
<listitem>
<simpara>
Werte vom Typ <type>Array</type> oder <type>&object;</type>
<emphasis>können nicht</emphasis> als Schlüssel verwendet werden. Ein
Versuch, dies zu tun, wird die Warnung <literal>Illegal offset
type</literal> zur Folge haben.
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Wenn mehrere Elemente in einer Array-Deklaration den gleichen Schlüssel
verwenden, dann wird nur der letzte verwendet und alle weiteren werden
überschrieben.
</para>
<example>
<title>Beispiel für Typumwandlung und Überschreibung</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(1) {
[1]=>
string(1) "d"
}
]]>
</screen>
<para>
Da alle Schlüssel im obigen Beispiel zu <literal>1</literal> umgewandelt
werden, wird der Wert dieses Elements durch jeden angegebenen Wert
überschrieben und nur der letzte zugewiesene Wert <literal>"d"</literal>
bleibt übrig.
</para>
</example>
<para>
Arrays können in PHP gleichzeitig Schlüssel der Typen <type>Int</type> und
<type>String</type> enthalten, da PHP nicht zwischen indizierten und
assoziativen Arrays unterscheidet.
</para>
<example>
<title>Gemischte <type>Int</type>- und <type>String</type>-Schlüssel</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
]]>
</screen>
</example>
<para>
Die Angabe des <replaceable>Schlüssel</replaceable>s ist optional. Ist
keiner angegeben, so wird PHP den bisher größten angegebenen
<type>Int</type>-Schlüssel erhöhen und das Ergebnis als Schlüssel
verwenden.
</para>
<example>
<title>Indizierte Arrays ohne Schlüssel</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(5) "hello"
[3]=>
string(5) "world"
}
]]>
</screen>
</example>
<para>
Es ist auch möglich, den Schlüssel nur bei einigen Elementen anzugeben und
bei anderen auszulassen:
</para>
<example>
<title>Schlüssel nicht bei allen Elementen</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
]]>
</screen>
<para>
Hier ist zu erkennen, dass dem letzten Wert <literal>"d"</literal> der
Schlüssel <literal>7</literal> zugewiesen wurde. Dies erfolgte, da der
größte vorherige ganzzahlige Schlüssel <literal>6</literal> war.
</para>
</example>
<example>
<title>Beispiel für komplexe Typumwandlung und Überschreibung</title>
<para>
Dieses Beispiel enthält alle Variationen der Typumwandlung von Schlüsseln
und des Überschreibens von Elementen.
</para>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => 'a',
'1' => 'b', // der Wert "a" wird mit "b" überschrieben
1.5 => 'c', // der Wert "b" wird mit "c" überschrieben
-1 => 'd',
'01' => 'e', // da dies kein Integer-String ist, wird der Schlüssel
// für 1 NICHT überschrieben
'1.5' => 'f', // da dies kein Integer-String ist, wird der Schlüssel
// für 1 NICHT überschrieben
true => 'g', // der Wert "c" wird mit "g" überschrieben
false => 'h',
'' => 'i',
null => 'j', // der Wert "i" wird mit "j" überschrieben
'k', // dem Wert "k" wird der Schlüssel 2 zugewiesen. Das liegt daran,
// dass der größte ganzzahlige Schlüssel davor 1 war
2 => 'l', // der Wert "k" wird mit "l" überschrieben
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(7) {
[1]=>
string(1) "g"
[-1]=>
string(1) "d"
["01"]=>
string(1) "e"
["1.5"]=>
string(1) "f"
[0]=>
string(1) "h"
[""]=>
string(1) "j"
[2]=>
string(1) "l"
}
]]>
</screen>
</example>
<example>
<title>Beispiel mit negativem Index</title>
<simpara>
Wenn ein negativer ganzzahliger Schlüssel <literal>n</literal> zugewiesen
wird, stellt PHP sicher, dass als nächstes der Schlüssel
<literal>n+1</literal> zugewiesen wird.
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$array = [];
$array[-5] = 1;
$array[] = 2;
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(2) {
[-5]=>
int(1)
[-4]=>
int(2)
}
]]>
</screen>
<warning>
<simpara>
Vor PHP 8.3.0 würde die Zuweisung eines negativen ganzzahligen Schlüssels
<literal>n</literal> dazu führen, dass als nächstes der Schlüssel
<literal>0</literal> zugewiesen wird, sodass das obige Beispiel zu diesem
Ergebnis führen würde:
</simpara>
<informalexample>
<screen>
<![CDATA[
array(2) {
[-5]=>
int(1)
[0]=>
int(2)
}
]]>
</screen>
</informalexample>
</warning>
</example>
</sect3>
<sect3 xml:id="language.types.array.syntax.accessing">
<title>Zugriff auf Elemente mit eckigen Klammern</title>
<para>
Auf Elemente eines Arrays kann durch Verwendung der Syntax
<literal>array[Schlüssel]</literal> zugegriffen werden.
</para>
<example>
<title>Zugriff auf Array-Elemente</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(3) "bar"
int(24)
string(3) "foo"
]]>
</screen>
</example>
<note>
<para>
Vor PHP 8.0.0 konnten sowohl eckige als auch geschweifte Klammern
verwendet werden, um auf die Elemente eines Arrays zuzugreifen (&zb;
werden im obigen Beispiel <literal>$array[42]</literal> und
<literal>array{42}</literal> auf das gleiche Element zugreifen). Die
Syntax für geschweifte Klammern ist seit PHP 7.4.0 veraltet und wird seit
PHP 8.0.0 nicht mehr unterstützt.
</para>
</note>
<example>
<title>Array-Dereferenzierung</title>
<programlisting role="php">
<![CDATA[
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
var_dump($secondElement);
?>
]]>
</programlisting>
</example>
<note>
<para>
Der Versuch, auf einen nicht definierten Arrayschlüssel zuzugreifen,
entspricht dem Zugriff auf jede andere undefinierte Variable: ein Fehler
der Stufe <constant>E_WARNING</constant> (der Stufe
<constant>E_NOTICE</constant> vor PHP 8.0.0) wird ausgegeben und das
Ergebnis ist &null;.
</para>
</note>
<note>
<para>
Die Array-Dereferenzierung eines skalaren Werts, der kein
<type>String</type> ist, ergibt &null;. Vor PHP 7.4.0 verursachte dies
keine Fehlermeldung. Seit PHP 7.4.0 wird ein Fehler der Stufe
<constant>E_NOTICE</constant> ausgegeben; seit PHP 8.0.0 ein Fehler der
Stufe <constant>E_WARNING</constant>.
</para>
</note>
</sect3>
<sect3 xml:id="language.types.array.syntax.modifying">
<title>Anlegen/Ändern mit eckigen Klammern</title>
<para>
Ein bestehendes <type>Array</type> kann verändert werden, indem man
explizit Werte darin setzt.
</para>
<para>
Dies wird getan, indem man dem <type>Array</type> Werte zuweist und dabei
den Schlüssel in eckigen Klammern angibt. Der Schlüssel kann dabei
weggelassen werden, was ein leeres Klammernpaar (<literal>[]</literal>)
ergibt.
</para>
<synopsis>
$arr[<replaceable>Schlüssel</replaceable>] = <replaceable>Wert</replaceable>;
$arr[] = <replaceable>Wert</replaceable>;
// <replaceable>Schlüssel</replaceable> kann ein <type>Int</type> oder <type>String</type> sein
// <replaceable>Wert</replaceable> kann einen beliebigen Typen haben</synopsis>
<para>
Falls <varname>$arr</varname> noch nicht existiert oder auf &null; oder
&false; gesetzt ist, wird es erzeugt; dies ist also eine alternative
Methode, um ein <type>Array</type> zu erzeugen. Dieses Vorgehen wird
jedoch nicht empfohlen, da, falls <varname>$arr</varname> bereits einen
Wert enthält (&zb; ein <type>String</type> aus einer Requestvariable),
dieser Wert bestehen bleibt und <literal>[]</literal> tatsächlich für den
<link linkend="language.types.string.substr">String-Zugriffs-Operator</link>
stehen kann. Es ist immer besser, eine Variable durch direkte Zuweisung zu
initialisieren.
</para>
<note>
<simpara>
Seit PHP 7.1.0 löst die Anwendung des leeren Index-Operators auf eine
Zeichenkette einen fatalen Fehler aus. Zuvor wurde die Zeichenkette
stillschweigend in ein Array umgewandelt.
</simpara>
</note>
<note>
<simpara>
Seit PHP 8.1.0 ist das Erstellen eines neuen Arrays aus &false;-Werten
veraltet. Es ist weiterhin erlaubt, ein neues Array aus &null;- und
undefinierten Werten zu erstellen.
</simpara>
</note>
<para>
Um einen bestimmten Wert zu ändern, kann man dem Element anhand seines
Schlüssels einen Wert zuweisen. Um ein Schlüssel-Wert-Paar zu entfernen,
kann man die Funktion <function>unset</function> darauf anwenden.
</para>
<example>
<title>Verwenden von eckigen Klammern bei Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // Dies ist dasselbe wie $arr[13] = 56;
// an dieser Stelle im Programmablauf
$arr["x"] = 42; // Dies fügt ein neues Element zum Array
// mit dem Schlüssel "x" hinzu
unset($arr[5]); // Dies entfernt das Element aus dem Array
var_dump($arr);
unset($arr); // Dies löscht das gesamte Array
var_dump($arr);
?>
]]>
</programlisting>
</example>
<note>
<para>
Wie vorher bereits erwähnt, wird, wenn kein Schlüssel angegeben ist, das
Maximum der bestehenden Schlüssel vom Typ <type>Int</type> verwendet und
der neue Schlüssel wird das Maximum plus 1 sein (aber mindestens 0). Wenn
noch kein <type>Int</type>-Schlüssel existiert wird der Schlüssel
<literal>0</literal> (Null) verwendet.
</para>
<para>
Zu beachten ist, dass der Maximalwert der Integer-Schlüssel dafür
<emphasis>aktuell nicht im <type>Array</type> existieren muss</emphasis>.
Er muss nur zu irgendeinem Zeitpunkt im <type>Array</type> existiert
haben, seitdem das <type>Array</type> zuletzt neu indiziert wurde. Das
folgende Beispiel erläutert dies:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Create a simple array.
$array = array(1, 2, 3, 4, 5);
print_r($array);
// Nun wird jeder Wert gelöscht, aber das Array selbst bleibt bestehen
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// Ein Element wird hinzugefügt
// (Beachten Sie, dass der neue Schlüssel 5 ist statt 0)
$array[] = 6;
print_r($array);
// Neue Indizierung
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
]]>
</screen>
</informalexample>
</note>
</sect3>
<sect3 xml:id="language.types.array.syntax.destructuring">
<title>Destrukturierung (Zerlegung) von Arrays</title>
<para>
Arrays können mit den Sprachkonstrukten <literal>[]</literal> (seit
PHP 7.1.0) oder <function>list</function> destrukuriert werden. Diese
Konstrukte können verwendet werden, um ein Array in einzelne Variablen zu
zerlegen.
</para>
<example>
<title>Destrukturieren eines Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];
[$foo, $bar, $baz] = $source_array;
echo $foo, PHP_EOL; // gibt "foo" aus
echo $bar, PHP_EOL; // gibt "bar" aus
echo $baz, PHP_EOL; // gibt "baz" aus
?>
]]>
</programlisting>
</example>
<para>
Die Destrukturierung von Arrays kann in &foreach; verwendet werden, um
ein mehrdimensionales Array zu zerlegen, während darüber iteriert wird.
</para>
<example>
<title>Destrukturieren eines Arrays in foreach</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = [
[1, 'John'],
[2, 'Jane'],
];
foreach ($source_array as [$id, $name]) {
echo "{$id}: '{$name}'\n";
}
?>
]]>
</programlisting>
</example>
<para>
Array-Elemente werden ignoriert, wenn die Variable nicht angegeben wird.
Die Destrukturierung von Arrays beginnt immer beim Index
<literal>0</literal>.
</para>
<example>
<title>Ignoren von Elementen</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];
// Zuweisen des Elements bei Index 2 an die Variable $baz
[, , $baz] = $source_array;
echo $baz; // gibt "baz" aus
?>
]]>
</programlisting>
</example>
<para>
Seit PHP 7.1.0 können auch assoziative Arrays destrukturiert werden. Da
der Index explizit angegeben werden kann, ermöglicht dies auch in
numerisch indizierten Arrays eine einfachere Auswahl des richtigen
Elements.
</para>
<example>
<title>Destrukturieren von assoziativen Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];
// Zuweisen des Elements bei Index 'baz' an die Variable $three
['baz' => $three] = $source_array;
echo $three, PHP_EOL; // gibt 3 aus
$source_array = ['foo', 'bar', 'baz'];
// Zuweisen des Elements bei Index 2 an die Variable $baz
[2 => $baz] = $source_array;
echo $baz, PHP_EOL; // gibt "baz" aus
?>
]]>
</programlisting>
</example>
<para>
Array-Destrukturierung kann verwendet werden, um auf einfache Weise zwei
Variablen zu vertauschen.
</para>
<example>
<title>Vertauschen von zwei Variablen</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
[$b, $a] = [$a, $b];
echo $a, PHP_EOL; // gibt 2 aus
echo $b, PHP_EOL; // gibt 1 aus
?>
]]>
</programlisting>
</example>
<note>
<para>
Der Spread-Operator (<literal>...</literal>) wird bei Zuweisungen
nicht unterstützt.
</para>
</note>
<note>
<para>
Wird versucht, auf einen nicht definierten Array-Schlüssel zuzugreifen,
so ist dies dasselbe wie der Zugriff auf eine andere undefinierte
Variable: Eine Fehlermeldung der Stufe <constant>E_WARNING</constant>
(der Stufe <constant>E_NOTICE</constant> vor PHP 8.0.0) wird ausgegeben
und das Ergebnis ist &null;.
</para>
</note>
<note>
<para>
Bei der Destrukturierung eines skalaren Werts wird allen Variablen &null;
zugewiesen.
</para>
</note>
</sect3>
</sect2><!-- end syntax -->
<sect2 xml:id="language.types.array.useful-funcs">
<title>Nützliche Funktionen</title>
<para>
Es gibt einige nützliche Funktionen für die Arbeit mit Arrays, die im
Abschnitt <link linkend="ref.array">Array-Funktionen</link> nachgeschlagen
werden können.
</para>
<note>
<para>
Die Funktion <function>unset</function> erlaubt es, Schlüssel aus einem
<type>Array</type> zu entfernen. Zu beachten ist dabei, dass das Array
<emphasis>nicht</emphasis> neu indiziert wird. Falls ein echtes Verhalten
von "Entfernen und Verschieben" gewünscht ist, dann kann das
<type>Array</type> mittels <function>array_values</function> neu indiziert
werden.
</para>
<example>
<title>Entfernen von Zwischenelementen</title>
<programlisting role="php">
<![CDATA[
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
/* dies wird ein Array erzeugen, das wie folgt definiert worden wäre
$a = array(1 => 'one', 3 => 'three');
und NICHT so
$a = array(1 => 'one', 2 =>'three');
*/
unset($a[2]);
var_dump($a);
$b = array_values($a);
// Nun ist $b array(0 => 'one', 1 =>'three')
var_dump($b);
?>
]]>
</programlisting>
</example>
</note>
<para>
Die Kontrollstruktur &foreach; existiert speziell für <type>Array</type>s.
Sie bietet eine einfache Möglichkeit, ein <type>Array</type> zu
durchlaufen.
</para>
</sect2>
<sect2 xml:id="language.types.array.donts">
<title>Dos und Dont's für Arrays (was man tun sollte und was nicht)</title>
<sect3 xml:id="language.types.array.foo-bar">
<title>Wieso ist <literal>$foo[bar]</literal> falsch?</title>
<para>
Verwenden Sie immer Anführungszeichen um ein
Arrayindex-Zeichenkettenliteral. Beispielsweise ist
<literal>$foo['bar']</literal> richtig, <literal>$foo[bar]</literal>
hingegen nicht. Aber wieso? Es ist üblich, die folgende Schreibweise in
alten Skripten zu finden:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
]]>
</programlisting>
</informalexample>
<para>
Dies ist falsch, funktioniert aber. Der Grund dafür ist, dass dieser Code
eine undefinierte Konstante (<literal>bar</literal>) anstatt eines
<type>String</type>s verwendet (<literal>'bar'</literal> - beachten Sie
die Anführungszeichen). Dies funktioniert, da PHP einen
<emphasis>nackten String</emphasis> (ein <type>String</type> ohne
Anführungszeichen, der keinem bekannten Symbol entspricht) automatisch in
einen <type>String</type> umwandelt, welcher den nackten
<type>String</type> enthält. Beispielsweise wird PHP, wenn keine Konstante
namens <constant>bar</constant> definiert ist, diese automatisch durch den
<type>String</type> <literal>'bar'</literal> ersetzen und verwenden.
</para>
<warning>
<simpara>
Das Rückfallverhalten, eine nicht definierte Konstante als nackte
Zeichenkette zu interpretieren, löst einen Fehler der Stufe
<constant>E_NOTICE</constant> aus. Dies ist seit PHP 7.2.0 missbilligt
und löst einen Fehler der Stufe <constant>E_WARNING</constant> aus. Mit
PHP 8.0.0 wurde es entfernt und löst eine
<classname>Error</classname>-Exception aus.
</simpara>
</warning>
<simpara>
Dies bedeutet nicht, dass man den Schlüssel <emphasis>immer</emphasis> in
Anführungszeichen setzen muss. Setzen Sie keine Schlüssel in
Anführungszeichen, welche
<link linkend="language.constants">Konstanten</link> oder
<link linkend="language.variables">Variablen</link> sind, da dies PHP
daran hindern wird, diese zu interpretieren.
</simpara>
<example>
<title>Anführungszeichen bei Schlüsseln</title>
<programlisting role="php">
<![CDATA[
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Ein simples Array:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nPrüfe $i: \n";
echo "Schlecht: " . $array['$i'] . "\n";
echo "Gut: " . $array[$i] . "\n";
echo "Schlecht: {$array['$i']}\n";
echo "Gut: {$array[$i]}\n";
}
?>
]]>
</programlisting>
</example>
&example.outputs;
<screen>
<![CDATA[
Prüfe 0:
Notice: Undefined index: $i in /path/to/script.html on line 9
Schlecht:
Gut: 1
Notice: Undefined index: $i in /path/to/script.html on line 11
Schlecht:
Gut: 1
Prüfe 1:
Notice: Undefined index: $i in /path/to/script.html on line 9
Schlecht:
Gut: 2
Notice: Undefined index: $i in /path/to/script.html on line 11
Schlecht:
Gut: 2
]]>
</screen>
<para>
Weitere Beispiele zur Erläuterung dieses Verhaltens:
</para>
<example>
<title>Weitere Beispiele</title>
<programlisting role="php">
<![CDATA[
<?php
// Alle Fehler anzeigen
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Korrekt
echo $arr['fruit'], PHP_EOL; // apple
echo $arr['veggie'], PHP_EOL; // carrot
// Inkorrekt. Dies Funktioniert nicht und PHP löst löst einen Error aus,
// da eine undefinierte Konstante namens fruit verwendet wird
//
// Error: Undefined constant "fruit"
try {
echo $arr[fruit];
} catch (Error $e) {
echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
}
// Dies definiert eine Konstante, um darzustellen, was hier passiert. Der Wert
// 'veggie' wird einer Konstanten namens fruit zugewiesen
define('fruit', 'veggie');
// Beachten Sie nun den Unterschied
echo $arr['fruit'], PHP_EOL; // apple
echo $arr[fruit], PHP_EOL; // carrot
// Hier ist es in Ordnung, da dies innerhalb eines Strings ist. Innerhalb eines
// Strings wird nicht nach Konstanten gesucht, weshalb kein Fehler auftritt
echo "Hello $arr[fruit]", PHP_EOL; // Hello apple
// Mit einer Ausnahme: Klammern um ein Array sorgen dafür, dass Konstanten
// interpretiert werden
echo "Hello {$arr[fruit]}", PHP_EOL; // Hello carrot
echo "Hello {$arr['fruit']}", PHP_EOL; // Hello apple
// Konkatenation (Verkettung) ist eine weitere Möglichkeit
echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
?>
]]>
</programlisting>
</example>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Dies wird nicht funktionieren und zu einem Parse-Fehler führen:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Dies gilt natürlich ebenso für superglobale Werte innerhalb von Strings
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
?>
]]>
</programlisting>
</informalexample>
<para>
Wie im Abschnitt zur
<link linkend="language.types.array.syntax">Syntax</link> gezeigt, muss
der Inhalt der eckigen Klammern '<literal>[</literal>' und
'<literal>]</literal>') ein Ausdruck sein. Das bedeutet, dass folgendes
funktioniert:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo $arr[somefunc($bar)];
?>
]]>
</programlisting>
</informalexample>
<para>
Dieses Beispiel zeigt, wie der Rückgabewert einer Funktion als Arrayindex
verwendet wird. PHP kann auch Konstanten auflösen:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$error_descriptions[E_ERROR] = "Ein fataler Fehler ist aufgetreten";
$error_descriptions[E_WARNING] = "PHP hat eine Warnung ausgegeben";
$error_descriptions[E_NOTICE] = "Dies ist nur ein informeller Hinweis";
?>
]]>
</programlisting>
</informalexample>
<para>
Es ist zu beachten, dass <constant>E_ERROR</constant> ein gültiger
Bezeichner ist, genau wie <literal>bar</literal> im ersten Beispiel. Das
vorherige Beispiel ist gleichbedeutend mit:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$error_descriptions[1] = "Ein fataler Fehler ist aufgetreten";
$error_descriptions[2] = "PHP hat eine Warnung ausgegeben";
$error_descriptions[8] = "Dies ist nur ein informeller Hinweis";
?>
]]>
</programlisting>
</informalexample>
<para>
da <constant>E_ERROR</constant> gleich <literal>1</literal> ist usw.
</para>
<sect4 xml:id="language.types.array.foo-bar.why">
<title>Wieso ist es also schlecht?</title>
<para>
Irgendwann in der Zukunft könnte das PHP-Team eine weitere Konstante oder
ein Schlüsselwort hinzufügen oder eine Konstante in anderem Code könnte
Einfluss nehmen. Es ist beispielsweise bereits falsch, die Wörter
<literal>empty</literal> oder <literal>default</literal> so zu schreiben,
da dies <link linkend="reserved">reservierte Schlüsselwörter</link> sind.
</para>
<note>
<simpara>
Zur Wiederholung: innerhalb eines <type>String</type>s in doppelten
Anführungszeichen ist es korrekt, einen Arrayschlüssel ohne
Anführungszeichen zu schreiben, weswegen <literal>"$foo[bar]"</literal>
zulässig ist. Die obigen Beispiele erklären dies ebenso, wie der
Abschnitt zum
<link linkend="language.types.string.parsing">Parsen von Variablen in Strings</link>.
</simpara>
</note>
</sect4>
</sect3>
</sect2>
<sect2 xml:id="language.types.array.casting">
<title>Konvertierung in ein Array</title>
<para>
Für jeden der Typen <type>&integer;</type>, <type>&float;</type>,
<type>&string;</type>, <type>&boolean;</type> und <type>&resource;</type>
führt eine Konvertierung eines Wertes in ein <type>Array</type> zu einem
Array mit einem einzigen Wert mit dem Index Null und dem Wert des Skalaren,
der konvertiert wurde. Anders ausgedrückt ist
<literal>(array) $scalarValue</literal> exakt identisch mit
<literal>array($scalarValue)</literal>.
</para>
<para>
Wenn ein <type>&object;</type> in ein <type>Array</type> konvertiert wird,
so ist das Ergebnis ein <type>Array</type>, dessen Werte die Eigenschaften
des <type>Objekt</type>s sind. Die Schlüssel sind die Namen der
Eigenschaften des Objektes mit ein paar nennenswerten Ausnahmen:
Eigenschaften mit Ganzzahl-Namen sind nicht zugreifbar, privaten Variablen
wird der Name der Klasse vorangestellt und protected Variablen wird dem
Variablennamen ein '*' vorangestellt. Diese vorangestellten Werte haben
<literal>NUL</literal>-Bytes auf beiden Seiten. Nicht-initialisierte
<link linkend="language.oop5.properties.typed-properties">typisierte Eigenschaften</link>
werden stillschweigend verworfen.
</para>
<example>
<title>Konvertierung in ein Array</title>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $B;
protected $C;
public $D;
function __construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array (
'' . "\0" . 'A' . "\0" . 'B' => NULL,
'' . "\0" . '*' . "\0" . 'C' => NULL,
'D' => NULL,
1 => NULL,
)
]]>
</screen>
</example>
<para>
Diese <literal>NUL</literal>-Bytes können zu einem unerwarteten Verhalten
führen:
</para>
<example>
<title>Umwandeln eines Objekts in ein Array</title>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $A; // Dies wird zu '\0A\0A'
}
class B extends A {
private $A; // Dies wird zu '\0B\0A'
public $AA; // Dies wird zu 'AA'
}
var_dump((array) new B());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(3) {
["BA"]=>
NULL
["AA"]=>
NULL
["AA"]=>
NULL
}
]]>
</screen>
</example>
<para>
Im obigen Beispiel scheint es zwei Schlüssel namens 'AA' zu geben, obwohl
einer davon eigentlich '\0A\0A' ist.
</para>
<para>
Die Konvertierung von &null; in ein <type>Array</type> führt zu einem
leeren <type>Array</type>.
</para>
</sect2>
<sect2 xml:id="language.types.array.comparing">
<title>Vergleiche</title>
<para>
Mit der Funktion <function>array_diff</function> und mit
<link linkend="language.operators.array">Array-Operatoren</link> ist es
möglich, Arrays zu vergleichen.
</para>
</sect2>
<sect2 xml:id="language.types.array.unpacking">
<title>Entpacken von Arrays</title>
<para>
Ein Array, dem ein <code>...</code> vorangestellt ist, wird bei der
Definition des Arrays an Ort und Stelle expandiert (entpackt). Nur Arrays
und Objekte, die <interfacename>Traversable</interfacename> implementieren,
können entpackt werden. Das Entpacken von Arrays mit <code>...</code> ist
seit PHP 7.4.0 verfügbar. Dies wird auch als Spread-Operator bezeichnet.
</para>
<para>
Es ist möglich, ein Array mehrmals zu entpacken und normale Elemente vor
oder nach dem Operator <code>...</code> hinzuzufügen:
<example>
<title>Einfaches Entpacken von Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
// Verwendung der kurzen Array-Syntax.
// Funktioniert auch mit der array()-Syntax.
$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; // [1, 2, 3]
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]
function getArr() {
return ['a', 'b'];
}
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']
var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
?>
]]>
</programlisting>
</example>
</para>
<para>
Das Entpacken eines Arrays mit dem Operator <code>...</code> folgt der
Syntax der Funktion <function>array_merge</function>. Das heißt,
nachfolgende Zeichenketten-Schlüssel überschreiben vorherige und
Integer-Schlüssel werden neu nummeriert:
<example>
<title>Entpacken eines Arrays mit doppeltem Schlüssel</title>
<programlisting role="php">
<![CDATA[
<?php
// Zeichenketten-Schlüssel
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]
// Integer-Schlüssel
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Das ergibt [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// wobei die ursprünglichen Integer-Schlüssel nicht beibehalten wurden.
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Schlüssel, die weder Integer noch Zeichenketten sind, lösen einen
<classname>TypeError</classname> aus. Solche Schlüssel können nur von
einem <interfacename>Traversable</interfacename>-Objekt erzeugt werden.
</para>
</note>
<note>
<para>
Vor PHP 8.1 wird das Entpacken eines Arrays, das einen String-Schlüssel
enthält, nicht unterstützt:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr1 = [1, 2, 3];
$arr2 = ['a' => 4];
$arr3 = [...$arr1, ...$arr2];
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5
$arr4 = [1, 2, 3];
$arr5 = [4, 5];
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
?>
]]>
</programlisting>
</informalexample>
</note>
</sect2>
<sect2 xml:id="language.types.array.examples">
<title>Beispiele</title>
<para>
Der Array-Typ in PHP ist sehr vielseitig. Hier sind einige Beispiele:
</para>
<example>
<title>Vielseitigkeit von Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
// Dies:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // der Schlüssel wird 0 sein
);
$b = array('a', 'b', 'c');
var_dump($a, $b);
// . . .ist komplett gleichbedeutend mit:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // der Schlüssel wird 0 sein
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// Nachdem der obige Code ausgeführt wurde, wird $a das Array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4) sein und $b wird das Array
// array(0 => 'a', 1 => 'b', 2 => 'c') oder einfach array('a', 'b', 'c')
// sein
var_dump($a, $b);
?>
]]>
</programlisting>
</example>
<example>
<title>Verwendung von array()</title>
<programlisting role="php">
<![CDATA[
<?php
// Array als Zuordnung von Eigenschaften
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'englisch',
'short_tags' => true
);
var_dump($map);
// Streng numerische Schlüssel
// Das ist gleichbedeutend mit array(0 => 7, 1 => 8, ...)
$array = array( 7,
8,
0,
156,
-10
);
var_dump($array);
$switching = array( 10, // Schlüssel = 0
5 => 6,
3 => 7,
'a' => 4,
11, // Schlüssel = 6 (das Maximum der Integer-Schlüssel war 5)
'8' => 2, // Schlüssel = 8 (Integer!)
'02' => 77, // Schlüssel = '02'
0 => 12 // Der Wert 10 wird mit 12 überschrieben
);
var_dump($switching);
// Leeres array
$empty = array();
var_dump($empty);
?>
]]>
<!-- TODO example of
- overwriting keys
- using vars/functions as key/values
- warning about references
-->
</programlisting>
</example>
<example xml:id="language.types.array.examples.loop">
<title>Sammlung</title>
<programlisting role="php">
<![CDATA[
<?php
$farben = array('rot', 'blau', 'grün', 'gelb');
foreach ($farben as $farbe) {
echo "Mögen sie $farbe?\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Mögen sie rot?
Mögen sie blau?
Mögen sie grün?
Mögen sie gelb?
]]>
</screen>
</example>
<para>
Die Veränderung der Werte eines <type>Array</type>s ist mit der Übergabe
als Referenz direkt möglich.
</para>
<example xml:id="language.types.array.examples.changeloop">
<title>Elemente in der Schleife verändern</title>
<programlisting role="php">
<![CDATA[
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as &$color) {
$color = mb_strtoupper($color);
}
unset($color); /* Sicherstellen, dass nachfolgende
Zugriffe auf $color nicht das letzte Element ändern */
print_r($colors);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => ROT
[1] => BLAU
[2] => GRÜN
[3] => GELB
)
]]>
</screen>
</example>
<para>
Dieses Beispiel erzeugt ein Array mit erstem Schlüssel 1.
</para>
<example>
<title>1-basierte Indizes</title>
<programlisting role="php">
<![CDATA[
<?php
$firstquarter = array(1 => 'Januar', 'Februar', 'März');
print_r($firstquarter);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[1] => Januar
[2] => Februar
[3] => März
)
]]>
</screen>
</example>
<example>
<title>Füllen eines Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
// Dies füllt ein Array mit allen Einträgen eines Verzeichnisses
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
var_dump($files);
?>
]]>
</programlisting>
</example>
<para>
<type>Array</type>s sind geordnet. Die Reihenfolge kann durch verschiedene
Sortierfunktionen verändert werden. Siehe
<link linkend="ref.array">Array-Funktionen</link> für mehr Informationen.
Die Funktion <function>count</function> kann verwendet werden, um die
Anzahl der Elemente eines <type>Array</type>s zu ermitteln.
</para>
<example>
<title>Ein Array sortieren</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
sort($files);
print_r($files);
?>
]]>
</programlisting>
</example>
<para>
Da die Werte eines <type>Array</type>s beliebig sein können, können diese
auch andere <type>Array</type>s sein. Dies ermöglicht die Erzeugung von
rekursiven und mehrdimensionalen <type>Array</type>s.
</para>
<example>
<title>Rekursive und mehrdimensionale Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
var_dump($fruits);
// Einige Beispiele für den Zugriff auf die Werte in den obigen Beispielen
echo $fruits["holes"][5]; // gibt "second" aus
echo $fruits["fruits"]["a"]; // gibt "orange" aus
unset($fruits["holes"][0]); // entfernt "first"
// Ein neues mehrdimensionales Array erzeugen
$juices["apple"]["green"] = "good";
var_dump($juices);
?>
]]>
</programlisting>
</example>
<para>
Die Zuweisung eines <type>Array</type>s beinhaltet immer eine Kopie der
Werte. Verwenden Sie den
<link linkend="language.operators">Referenz-Operator</link>, um ein Array
per Referenz zu kopieren.
</para>
<example>
<title>Kopieren eines Arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 wurde geändert,
// $arr1 ist weiterhin array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // nun sind $arr1 und $arr3 identisch
var_dump($arr1, $arr2, $arr3);
?>
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->