please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
Ein Array ist in PHP in Wirklichkeit eine geordnete Map (Abbildung). Eine Map ist ein Typ, der Werte zu Schlüsseln 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 Arrays ein weiteres Array sein kann, sind auch Bäume und mehrdimensionale Arrays möglich.
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.
Ein Array kann durch das Sprachkonstrukt
array() erzeugt werden. Dies nimmt eine beliebige
Anzahl kommaseparierter Schlüssel
=> Wert
-Paare als Parameter
entgegen.
array( Schlüssel => Wert, Schlüssel2 => Wert2, Schlüssel3 => Wert3, ... )
Das Komma nach dem letzten Array-Element ist optional und kann weggelassen
werden. Dies wird üblicherweise in einzeiligen Arrays getan, d. h..
array(1, 2)
wird der Schreibweise array(1, 2,
)
vorgezogen. Andererseits wird bei mehrzeiligen Arrays das
Komma am Ende üblicherweise genutzt, da dies ein einfaches Hinzufügen
weiterer Elemente am Ende erlaubt.
Hinweis:
Es gibt eine Kurzform der Array-Syntax, die
array()
durch[]
ersetzt.
Beispiel #1 Ein einfaches Array
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// Verwendung der verkürzten Array-Syntax
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
Der Schlüssel kann entweder ein Integer oder ein String sein. Der Wert kann beliebige Datentypen annehmen.
Zusätzlich werden die folgenden Typkonvertierungen auf den Schlüssel angewendet:
+
-Zeichen vorangestellt.
Beispielsweise wird der Schlüssel "8"
tatsächlich
unter 8
gespeichert. Andererseits wird
"08"
nicht umgewandelt, da dies kein gültiger
Ganzzahlwert ist.
8.7
als 8
gespeichert.
true
wird unter 1
gespeichert
und der Schlüssel false
unter 0
.
null
wird tatsächlich unter
""
gespeichert.
Illegal offset
type
zur Folge haben.
Wenn mehrere Elemente in einer Array-Deklaration den gleichen Schlüssel verwenden, dann wird nur der letzte verwendet und alle weiteren werden überschrieben.
Beispiel #2 Beispiel für Typumwandlung und Überschreibung
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(1) { [1]=> string(1) "d" }
Da alle Schlüssel im obigen Beispiel zu 1
umgewandelt
werden, wird der Wert dieses Elements durch jeden angegebenen Wert
überschrieben und nur der letzte zugewiesene Wert "d"
bleibt übrig.
Arrays können in PHP gleichzeitig Schlüssel der Typen Int und String enthalten, da PHP nicht zwischen indizierten und assoziativen Arrays unterscheidet.
Beispiel #3 Gemischte Int- und String-Schlüssel
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(4) { ["foo"]=> string(3) "bar" ["bar"]=> string(3) "foo" [100]=> int(-100) [-100]=> int(100) }
Die Angabe des Schlüssels ist optional. Ist keiner angegeben, so wird PHP den bisher größten angegebenen Int-Schlüssel erhöhen und das Ergebnis als Schlüssel verwenden.
Beispiel #4 Indizierte Arrays ohne Schlüssel
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(4) { [0]=> string(3) "foo" [1]=> string(3) "bar" [2]=> string(5) "hello" [3]=> string(5) "world" }
Es ist auch möglich, den Schlüssel nur bei einigen Elementen anzugeben und bei anderen auszulassen:
Beispiel #5 Schlüssel nicht bei allen Elementen
<?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(4) { [0]=> string(1) "a" [1]=> string(1) "b" [6]=> string(1) "c" [7]=> string(1) "d" }
Hier ist zu erkennen, dass dem letzten Wert "d"
der
Schlüssel 7
zugewiesen wurde. Dies erfolgte, da der
größte vorherige ganzzahlige Schlüssel 6
war.
Beispiel #6 Beispiel für komplexe Typumwandlung und Überschreibung
Dieses Beispiel enthält alle Variationen der Typumwandlung von Schlüsseln und des Überschreibens von Elementen.
<?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);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
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" }
Auf Elemente eines Arrays kann durch Verwendung der Syntax
array[Schlüssel]
zugegriffen werden.
Beispiel #7 Zugriff auf Array-Elemente
<?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"]);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
string(3) "bar" int(24) string(3) "foo"
Hinweis:
Vor PHP 8.0.0 konnten sowohl eckige als auch geschweifte Klammern verwendet werden, um auf die Elemente eines Arrays zuzugreifen (z. B. werden im obigen Beispiel
$array[42]
undarray{42}
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.
Beispiel #8 Array-Dereferenzierung
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
?>
Hinweis:
Der Versuch, auf einen nicht definierten Arrayschlüssel zuzugreifen, entspricht dem Zugriff auf jede andere undefinierte Variable: ein Fehler der Stufe
E_WARNING
(der StufeE_NOTICE
vor PHP 8.0.0) wird ausgegeben und das Ergebnis istnull
.
Hinweis:
Die Array-Dereferenzierung eines skalaren Werts, der kein String ist, ergibt
null
. Vor PHP 7.4.0 verursachte dies keine Fehlermeldung. Seit PHP 7.4.0 wird ein Fehler der StufeE_NOTICE
ausgegeben; seit PHP 8.0.0 ein Fehler der StufeE_WARNING
.
Ein bestehendes Array kann verändert werden, indem man explizit Werte darin setzt.
Dies wird getan, indem man dem Array Werte zuweist und dabei
den Schlüssel in eckigen Klammern angibt. Der Schlüssel kann dabei
weggelassen werden, was ein leeres Klammernpaar ([]
)
ergibt.
$arr[Schlüssel] = Wert; $arr[] = Wert; // Schlüssel kann ein Int oder String sein // Wert kann einen beliebigen Typen haben
Falls $arr noch nicht existiert oder auf null
oder
false
gesetzt ist, wird es erzeugt; dies ist also eine alternative
Methode, um ein Array zu erzeugen. Dieses Vorgehen wird
jedoch nicht empfohlen, da, falls $arr bereits einen
Wert enthält (z. B. ein String aus einer Requestvariable),
dieser Wert bestehen bleibt und []
tatsächlich für den
String-Zugriffs-Operator
stehen kann. Es ist immer besser, eine Variable durch direkte Zuweisung zu
initialisieren.
Hinweis: 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.
Hinweis: Seit PHP 8.1.0 ist das Erstellen eines neuen Arrays aus
false
-Werten veraltet. Es ist weiterhin erlaubt, ein neues Array ausnull
- und undefinierten Werten zu erstellen.
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 unset() darauf anwenden.
<?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
unset($arr); // Dies löscht das gesamte Array
?>
Hinweis:
Wie vorher bereits erwähnt, wird, wenn kein Schlüssel angegeben ist, das Maximum der bestehenden Schlüssel vom Typ Int verwendet und der neue Schlüssel wird das Maximum plus 1 sein (aber mindestens 0). Wenn noch kein Int-Schlüssel existiert wird der Schlüssel
0
(Null) verwendet.Zu beachten ist, dass der Maximalwert der Integer-Schlüssel dafür aktuell nicht im Array existieren muss. Er muss nur zu irgendeinem Zeitpunkt im Array existiert haben, seitdem das Array zuletzt neu indiziert wurde. Das folgende Beispiel erläutert dies:
<?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);
?>Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) Array ( ) Array ( [5] => 6 ) Array ( [0] => 6 [1] => 7 )
Arrays können mit den Sprachkonstrukten []
(seit
PHP 7.1.0) oder list() destrukuriert werden. Diese
Konstrukte können verwendet werden, um ein Array in einzelne Variablen zu
zerlegen.
<?php
$source_array = ['foo', 'bar', 'baz'];
[$foo, $bar, $baz] = $source_array;
echo $foo; // gibt "foo" aus
echo $bar; // gibt "bar" aus
echo $baz; // gibt "baz" aus
?>
Die Destrukturierung von Arrays kann in foreach verwendet werden, um ein mehrdimensionales Array zu zerlegen, während darüber iteriert wird.
<?php
$source_array = [
[1, 'John'],
[2, 'Jane'],
];
foreach ($source_array as [$id, $name]) {
// der Code mit $id und $name
}
?>
Array-Elemente werden ignoriert, wenn die Variable nicht angegeben wird.
Die Destrukturierung von Arrays beginnt immer beim Index
0
.
<?php
$source_array = ['foo', 'bar', 'baz'];
// Zuweisen des Elements bei Index 2 an die Variable $baz
[, , $baz] = $source_array;
echo $baz; // gibt "baz" aus
?>
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.
<?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; // gibt 3 aus
$source_array = ['foo', 'bar', 'baz'];
// Zuweisen des Elements bei Index 2 an die Variable $baz
[2 => $baz] = $source_array;
echo $baz; // gibt "baz" aus
?>
Array-Destrukturierung kann verwendet werden, um auf einfache Weise zwei Variablen zu vertauschen.
<?php
$a = 1;
$b = 2;
[$b, $a] = [$a, $b];
echo $a; // gibt 2 aus
echo $b; // gibt 1 aus
?>
Hinweis:
Der Spread-Operator (
...
) wird bei Zuweisungen nicht unterstützt.
Hinweis:
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
E_WARNING
(der StufeE_NOTICE
vor PHP 8.0.0) wird ausgegeben und das Ergebnis istnull
.
Es gibt einige nützliche Funktionen für die Arbeit mit Arrays, die im Abschnitt Array-Funktionen nachgeschlagen werden können.
Hinweis:
Die Funktion unset() erlaubt es, Schlüssel aus einem Array zu entfernen. Zu beachten ist dabei, dass das Array nicht neu indiziert wird. Falls ein echtes Verhalten von "Entfernen und Verschieben" gewünscht ist, dann kann das Array mittels array_values() neu indiziert werden.
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* 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');
*/
$b = array_values($a);
// Nun ist $b array(0 => 'one', 1 =>'three')
?>
Die Kontrollstruktur foreach existiert speziell für Arrays. Sie bietet eine einfache Möglichkeit, ein Array zu durchlaufen.
$foo[bar]
falsch?
Verwenden Sie immer Anführungszeichen um ein
Arrayindex-Zeichenkettenliteral. Beispielsweise ist
$foo['bar']
richtig, $foo[bar]
hingegen nicht. Aber wieso? Es ist üblich, die folgende Schreibweise in
alten Skripten zu finden:
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
Dies ist falsch, funktioniert aber. Der Grund dafür ist, dass dieser Code
eine undefinierte Konstante (bar
) anstatt eines
Strings verwendet ('bar'
- beachten Sie
die Anführungszeichen). Dies funktioniert, da PHP einen
nackten String (ein String ohne
Anführungszeichen, der keinem bekannten Symbol entspricht) automatisch in
einen String umwandelt, welcher den nackten
String enthält. Beispielsweise wird PHP, wenn keine Konstante
namens bar
definiert ist, diese automatisch durch den
String 'bar'
ersetzen und verwenden.
Das Rückfallverhalten, eine nicht definierte Konstante als nackte
Zeichenkette zu interpretieren, löst einen Fehler der Stufe
E_NOTICE
aus. Dies ist seit PHP 7.2.0 missbilligt
und löst einen Fehler der Stufe E_WARNING
aus. Mit
PHP 8.0.0 wurde es entfernt und löst eine
Error-Exception aus.
Hinweis: Dies bedeutet nicht, dass man den Schlüssel immer in Anführungszeichen setzen muss. Setzen Sie keine Schlüssel in Anführungszeichen, welche Konstanten oder Variablen sind, da dies PHP daran hindern wird, diese zu interpretieren.
<?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";
}
?>Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
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
Weitere Beispiele zur Erläuterung dieses Verhaltens:
<?php
// Alle Fehler anzeigen
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Korrekt
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Inkorrekt. Dies Funktioniert, aber PHP wirft einen Fehler der Stufe
// E_NOTICE, da eine undefinierte Konstante namens fruit verwendet wird
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// 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
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// Hier ist es in Ordnung, da dies innerhalb eines Strings ist. Innerhalb eines
// Strings wird nicht nach Konstanten gesucht, weshalb kein E_NOTICE auftritt
print "Hello $arr[fruit]"; // Hello apple
// Mit einer Ausnahme: Klammern um ein Array sorgen dafür, dass Konstanten
// interpretiert werden
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// 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']";
// Konkatenation (Verkettung) ist eine weitere Möglichkeit
print "Hello " . $arr['fruit']; // Hello apple
?>
Wenn error_reporting so
eingestellt wird, dass Fehler der Stufe E_NOTICE
angezeigt werden (indem man es beispielsweise auf
E_ALL
stellt), werden solche Fehler sofort sichtbar.
Standardmäßig zeigt
error_reporting keine Hinweise.
Wie im Abschnitt zur
Syntax gezeigt, muss
der Inhalt der eckigen Klammern '[
' und
']
') ein Ausdruck sein. Das bedeutet, dass folgendes
funktioniert:
<?php
echo $arr[somefunc($bar)];
?>
Dieses Beispiel zeigt, wie der Rückgabewert einer Funktion als Arrayindex verwendet wird. PHP kann auch Konstanten auflösen:
<?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";
?>
Es ist zu beachten, dass E_ERROR
ein gültiger
Bezeichner ist, genau wie bar
im ersten Beispiel. Das
vorherige Beispiel ist gleichbedeutend mit:
<?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";
?>
da E_ERROR
gleich 1
ist usw.
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
empty
oder default
so zu schreiben,
da dies reservierte Schlüsselwörter sind.
Hinweis: Zur Wiederholung: innerhalb eines Strings in doppelten Anführungszeichen ist es korrekt, einen Arrayschlüssel ohne Anführungszeichen zu schreiben, weswegen
"$foo[bar]"
zulässig ist. Die obigen Beispiele erklären dies ebenso, wie der Abschnitt zum Parsen von Variablen in Strings.
Für jeden der Typen Integer, Float,
String, Boolean und Ressource
führt eine Konvertierung eines Wertes in ein Array zu einem
Array mit einem einzigen Wert mit dem Index Null und dem Wert des Skalaren,
der konvertiert wurde. Anders ausgedrückt ist
(array)$scalarValue
exakt identisch mit
array($scalarValue)
.
Wenn ein Objekt in ein Array konvertiert wird,
so ist das Ergebnis ein Array, dessen Werte die Eigenschaften
des Objekts 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
NUL
-Bytes auf beiden Seiten. Nicht-initialisierte
typisierte Eigenschaften
werden stillschweigend verworfen.
<?php
class A {
private $B;
protected $C;
public $D;
function __construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array ( '' . "\0" . 'A' . "\0" . 'B' => NULL, '' . "\0" . '*' . "\0" . 'C' => NULL, 'D' => NULL, 1 => NULL, )
Diese NUL
-Bytes können zu einem unerwarteten Verhalten
führen:
<?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());
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(3) { ["BA"]=> NULL ["AA"]=> NULL ["AA"]=> NULL }
Im obigen Beispiel scheint es zwei Schlüssel namens 'AA' zu geben, obwohl einer davon eigentlich '\0A\0A' ist.
Die Konvertierung von null
in ein Array führt zu einem
leeren Array.
Mit der Funktion array_diff() und mit Array-Operatoren ist es möglich, Arrays zu vergleichen.
Ein Array, dem ein ...
vorangestellt ist, wird bei der
Definition des Arrays an Ort und Stelle expandiert (entpackt). Nur Arrays
und Objekte, die Traversable implementieren,
können entpackt werden. Das Entpacken von Arrays mit ...
ist
seit PHP 7.4.0 verfügbar.
Es ist möglich, ein Array mehrmals zu entpacken und normale Elemente vor
oder nach dem Operator ...
hinzuzufügen:
Beispiel #9 Einfaches Entpacken von Arrays
<?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']
?>
Das Entpacken eines Arrays mit dem Operator ...
folgt der
Syntax der Funktion array_merge(). Das heißt,
nachfolgende Zeichenketten-Schlüssel überschreiben vorherige und
Integer-Schlüssel werden neu nummeriert:
Beispiel #10 Entpacken eines Arrays mit doppeltem Schlüssel
<?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.
?>
Hinweis:
Schlüssel, die weder Integer noch Zeichenketten sind, lösen einen TypeError aus. Solche Schlüssel können nur von einem Traversable-Objekt erzeugt werden.
Hinweis:
Vor PHP 8.1 wird das Entpacken eines Arrays, das einen String-Schlüssel enthält, nicht unterstützt:
<?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]
?>
Der Array-Typ in PHP ist sehr vielseitig. Hier sind einige Beispiele:
<?php
// Dies:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // der Schlüssel wird 0 sein
);
$b = array('a', 'b', 'c');
// . . .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
?>
Beispiel #11 Verwendung von array()
<?php
// Array als Zuordnung von Eigenschaften
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'englisch',
'short_tags' => true
);
// Streng numerische Schlüssel
$array = array( 7,
8,
0,
156,
-10
);
// das ist gleichbedeutend mit array(0 => 7, 1 => 8, ...)
$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
);
// Leeres array
$empty = array();
?>
Beispiel #12 Sammlung
<?php
$farben = array('rot', 'blau', 'grün', 'gelb');
foreach ($farben as $farbe) {
echo "Mögen sie $farbe?\n";
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Mögen sie rot? Mögen sie blau? Mögen sie grün? Mögen sie gelb?
Die Veränderung der Werte eines Arrays ist mit der Übergabe als Referenz direkt möglich.
Beispiel #13 Elemente in der Schleife verändern
<?php
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* Sicherstellen, dass nachfolgende
Zugriffe auf $color nicht das letzte Element ändern */
print_r($colors);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => ROT [1] => BLAU [2] => GRÜN [3] => GELB )
Dieses Beispiel erzeugt ein Array mit erstem Schlüssel 1.
Beispiel #14 1-basierte Indizes
<?php
$firstquarter = array(1 => 'Januar', 'Februar', 'März');
print_r($firstquarter);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [1] => 'Januar' [2] => 'Februar' [3] => 'März' )
Beispiel #15 Füllen eines Arrays
<?php
// Dies füllt ein Array mit allen Einträgen eines Verzeichnisses
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
Arrays sind geordnet. Die Reihenfolge kann durch verschiedene Sortierfunktionen verändert werden. Siehe Array-Funktionen für mehr Informationen. Die Funktion count() kann verwendet werden, um die Anzahl der Elemente eines Arrays zu ermitteln.
Beispiel #16 Ein Array sortieren
<?php
sort($files);
print_r($files);
?>
Da die Werte eines Arrays beliebig sein können, können diese auch andere Arrays sein. Dies ermöglicht die Erzeugung von rekursiven und mehrdimensionalen Arrays.
Beispiel #17 Rekursive und mehrdimensionale Arrays
<?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"
)
);
// 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";
?>
Die Zuweisung eines Arrays beinhaltet immer eine Kopie der Werte. Verwenden Sie den Referenz-Operator, um ein Array per Referenz zu kopieren.
<?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
?>
please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
I think your first, main example is needlessly confusing, very confusing to newbies:
$array = array(
"foo" => "bar",
"bar" => "foo",
);
It should be removed.
For newbies:
An array index can be any string value, even a value that is also a value in the array.
The value of array["foo"] is "bar".
The value of array["bar"] is "foo"
The following expressions are both true:
$array["foo"] == "bar"
$array["bar"] == "foo"
Since PHP 7.1, the string will not be converted to array automatically.
Below codes will fail:
$a=array();
$a['a']='';
$a['a']['b']='';
//Warning: Illegal string offset 'b'
//Warning: Cannot assign an empty string to a string offset
You have to change to as below:
$a=array();
$a['a']=array(); // Declare it is an array first
$a['a']['b']='';
Beware that if you're using strings as indices in the $_POST array, that periods are transformed into underscores:
<html>
<body>
<?php
printf("POST: "); print_r($_POST); printf("<br/>");
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="Windows3.1" value="Sux">
<input type="submit" value="Click" />
</form>
</body>
</html>
Once you click on the button, the page displays the following:
POST: Array ( [Windows3_1] => Sux )
"If you convert a NULL value to an array, you get an empty array."
This turns out to be a useful property. Say you have a search function that returns an array of values on success or NULL if nothing found.
<?php $values = search(...); ?>
Now you want to merge the array with another array. What do we do if $values is NULL? No problem:
<?php $combined = array_merge((array)$values, $other); ?>
Voila.
--- quote ---
Note:
Both square brackets and curly braces can be used interchangeably for accessing array elements
--- quote end ---
At least for php 5.4 and 5.6; if function returns an array, the curly brackets does not work directly accessing function result, eg. WillReturnArray(){1} . This will give "syntax error, unexpected '{' in...".
Personally I use only square brackets, expect for accessing single char in string. Old habits...
Note that array value buckets are reference-safe, even through serialization.
<?php
$x='initial';
$test=array('A'=>&$x,'B'=>&$x);
$test=unserialize(serialize($test));
$test['A']='changed';
echo $test['B']; // Outputs "changed"
?>
This can be useful in some cases, for example saving RAM within complex structures.
Regarding the previous comment, beware of the fact that reference to the last value of the array remains stored in $value after the foreach:
<?php
foreach ( $arr as $key => &$value )
{
$value = 1;
}
// without next line you can get bad results...
//unset( $value );
$value = 159;
?>
Now the last element of $arr has the value of '159'. If we remove the comment in the unset() line, everything works as expected ($arr has all values of '1').
Bad results can also appear in nested foreach loops (the same reason as above).
So either unset $value after each foreach or better use the longer form:
<?php
foreach ( $arr as $key => $value )
{
$arr[ $key ] = 1;
}
?>
//array keys are always integer and string data type and array values are all data type
//type casting and overwriting(data type of array key)
//----------------------------------------------------
$arr = array(
1=>"a",//int(1)
"3"=>"b",//int(3)
"08"=>"c",//string(2)"08"
"80"=>"d",//int(80)
"0"=>"e",//int(0)
"Hellow"=>"f",//string(6)"Hellow"
"10Hellow"=>"h",//string(8)"10Hellow"
1.5=>"j",//int(1.5)
"1.5"=>"k",//string(3)"1.5"
0.0=>"l",//int(0)
false=>"m",//int(false)
true=>"n",//int(true)
"true"=>"o",//string(4)"true"
"false"=>"p",//string(5)"false"
null=>"q",//string(0)""
NULL=>"r",//string(0)"" note null and NULL are same
"NULL"=>"s",//string(4)"NULL" ,,,In last element of multiline array,comma is better to used.
);
//check the data type name of key
foreach ($arr as $key => $value) {
var_dump($key);
echo "<br>";
}
//NOte :array and object data type in keys are Illegal ofset.......
Used to creating arrays like this in Perl?
@array = ("All", "A".."Z");
Looks like we need the range() function in PHP:
<?php
$array = array_merge(array('All'), range('A', 'Z'));
?>
You don't need to array_merge if it's just one range:
<?php
$array = range('A', 'Z');
?>
[Editor's note: You can achieve what you're looking for by referencing $single, rather than copying it by value in your foreach statement. See http://php.net/foreach for more details.]
Don't know if this is known or not, but it did eat some of my time and maybe it won't eat your time now...
I tried to add something to a multidimensional array, but that didn't work at first, look at the code below to see what I mean:
<?php
$a1 = array( "a" => 0, "b" => 1 );
$a2 = array( "aa" => 00, "bb" => 11 );
$together = array( $a1, $a2 );
foreach( $together as $single ) {
$single[ "c" ] = 3 ;
}
print_r( $together );
/* nothing changed result is:
Array
(
[0] => Array
(
[a] => 0
[b] => 1
)
[1] => Array
(
[aa] => 0
[bb] => 11
)
) */
foreach( $together as $key => $value ) {
$together[$key]["c"] = 3 ;
}
print_r( $together );
/* now it works, this prints
Array
(
[0] => Array
(
[a] => 0
[b] => 1
[c] => 3
)
[1] => Array
(
[aa] => 0
[bb] => 11
[c] => 3
)
)
*/
?>
In array(key=>value) construct key is also an expression.
This works fine:
$a = array(
1 =>0,
1+1 =>1,
$k =>2,
$x.'4'=>3
);
// Before php 5.4
$array = array(1,2,3);
// since php 5.4 , short syntax
$array = [1,2,3];
// I recommend using the short syntax if you have php version >= 5.4
There is another kind of array (php>= 5.3.0) produced by
$array = new SplFixedArray(5);
Standard arrays, as documented here, are marvellously flexible and, due to the underlying hashtable, extremely fast for certain kinds of lookup operation.
Supposing a large string-keyed array
$arr=['string1'=>$data1, 'string2'=>$data2 etc....]
when getting the keyed data with
$data=$arr['string1'];
php does *not* have to search through the array comparing each key string to the given key ('string1') one by one, which could take a long time with a large array. Instead the hashtable means that php takes the given key string and computes from it the memory location of the keyed data, and then instantly retrieves the data. Marvellous! And so quick. And no need to know anything about hashtables as it's all hidden away.
However, there is a lot of overhead in that. It uses lots of memory, as hashtables tend to (also nearly doubling on a 64bit server), and should be significantly slower for integer keyed arrays than old-fashioned (non-hashtable) integer-keyed arrays. For that see more on SplFixedArray :
http://uk3.php.net/SplFixedArray
Unlike a standard php (hashtabled) array, if you lookup by integer then the integer itself denotes the memory location of the data, no hashtable computation on the integer key needed. This is much quicker. It's also quicker to build the array compared to the complex operations needed for hashtables. And it uses a lot less memory as there is no hashtable data structure. This is really an optimisation decision, but in some cases of large integer keyed arrays it may significantly reduce server memory and increase performance (including the avoiding of expensive memory deallocation of hashtable arrays at the exiting of the script).
to know the depth (dimension) of a ARRAY, you can use this:
function Dim_Ar($A, $i){
if(!is_array($A))return 0;
$t[] = 1;
foreach($A AS $e)if(is_array($e))$t[] = Dim_Ar($e, ++ $i) + 1;
return max($t);
}
and use with:
$Q = ARRAY(ARRAY(ARRAY()), ARRAY(ARRAY()));// here depth/dimension is three
echo Dim_Ar($Q, 0);
Function unset can delete array's element by reference only when you specify source array. See example:
<?php
$array = [1, 2, 3, 4, 5];
foreach ($array as $k => &$v){
if ($k >= 3){
unset($v);
}
}
echo count($array); // 5
?>
In this case unset delete only reference, however original array didn't change.
Or different example:
<?php
$arr = [1, 2];
$a = &$arr[0];
unset($a);
count($arr); // 2
?>
So for deleting element from first example need use key and array.
<?php
// ...
unset($array[$k]);
// ...
?>
When creating arrays , if we have an element with the same value as another element from the same array, we would expect PHP instead of creating new zval container to increase the refcount and point the duplicate symbol to the same zval. This is true except for value type integer.
Example:
$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => 23 ];
xdebug_debug_zval( 'arr' );
Output:
arr:
(refcount=2, is_ref=0)
array (size=3)
'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
'age' => (refcount=0, is_ref=0)int 23
'too' => (refcount=0, is_ref=0)int 23
but :
$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => '23' ];
xdebug_debug_zval( 'arr' );
will produce:
arr:
(refcount=2, is_ref=0)
array (size=3)
'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
'age' => (refcount=0, is_ref=0)int 23
'too' => (refcount=1, is_ref=0)string '23' (length=2)
or :
$arr = ['bebe' => 'Bob', 'age' => [1,2], 'too' => [1,2] ];
xdebug_debug_zval( 'arr' );
Output:
arr:
(refcount=2, is_ref=0)
array (size=3)
'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
'age' => (refcount=2, is_ref=0)
array (size=2)
0 => (refcount=0, is_ref=0)int 1
1 => (refcount=0, is_ref=0)int 2
'too' => (refcount=2, is_ref=0)
array (size=2)
0 => (refcount=0, is_ref=0)int 1
1 => (refcount=0, is_ref=0)int 2
Wrappers for (array), returns array with normalize keys (without prefix):
<?php
function to_array_recursive($value): array
{
if (! is_object($value)) {
return (array) $value;
}
$class = get_class($value);
$arr = [];
foreact ((array) $value as $key => $val) {
$key = str_replace(["\0*\0", "\0{$class}\0"], '', $key);
$arr[$key] = is_object($val) ? to_array_recursive($val) : $val;
}
return $arr;
}
function to_array($value): array
{
$arr = (array) $value;
if (! is_object($value)) {
return $arr;
}
$class = get_class($value);
$keys = str_replace(["\0*\0", "\0{$class}\0"], '', array_keys($arr));
return array_combine($keys, $arr);
}
?>
Demo:
<?php
class Test
{
protected $var = 1;
protected $var2;
private $TestVar = 3;
public function __construct($isParent = true)
{
if ($isParent) {
$this->var2 = new self(! $isParent);
}
}
}
$obj = new Test();
var_dump((array) $obj, to_array_recursive($obj));
?>
Note that objects of classes extending ArrayObject SPL class are treated as arrays, and not as objects when converting to array.
<?php
class ArrayObjectExtended extends ArrayObject
{
private $private = 'private';
public $hello = 'world';
}
$object = new ArrayObjectExtended();
$array = (array) $object;
// This will not expose $private and $hello properties of $object,
// but return an empty array instead.
var_export($array);
?>
It is true that "array assignment always involves value copying", but the copy is a "lazy copy". This means that the data of the two variables occupy the same memory as long as no array element changes.
E.g., if you have to pass an array to a function that only needs to read it, there is no advantage at all in passing it by reference.