PHP
Tablice
Szukaj…
Wprowadzenie
Tablica jest strukturą danych, która przechowuje dowolną liczbę wartości w jednej wartości. Tablica w PHP jest właściwie uporządkowaną mapą, gdzie map jest typem, który wiąże wartości z kluczami.
Składnia
- $ tablica = tablica („Wartość1”, „Wartość2”, „Wartość3”); // Klucze domyślnie to 0, 1, 2, ...,
- $ tablica = tablica („Wartość1”, „Wartość2”,); // Opcjonalny przecinek końcowy
- $ array = array ('key1' => 'Value1', 'key2' => 'Value2',); // Jawne klucze
- $ array = array ('key1' => 'Value1', 'Value2',); // Array (['key1'] => Value1 [1] => 'Value2')
- $ array = ['key1' => 'Value1', 'key2' => 'Value2',]; // Stenografia PHP 5.4+
- $ array [] = 'ValueX'; // Dołącz „ValueX” na końcu tablicy
- $ array ['keyX'] = 'ValueX'; // Przypisz „wartość X” do klucza „klucz X”
- $ array + = ['keyX' => 'valueX', 'keyY' => 'valueY']; // Dodawanie / zastępowanie elementów w istniejącej tablicy
Parametry
Parametr | Szczegół |
---|---|
Klucz | Klucz jest unikalnym identyfikatorem i indeksem tablicy. Może to być string lub integer . Dlatego poprawne klucze to 'foo', '5', 10, 'a2b', ... |
Wartość | Dla każdego key istnieje odpowiednia wartość (w przeciwnym razie null i przy dostępie jest emitowane powiadomienie ). Wartość nie ma ograniczeń dotyczących typu danych wejściowych. |
Uwagi
Inicjowanie tablicy
Tablicę można zainicjować pustą:
// An empty array
$foo = array();
// Shorthand notation available since PHP 5.4
$foo = [];
Tablicę można zainicjować i ustawić na wartości:
// Creates a simple array with three strings
$fruit = array('apples', 'pears', 'oranges');
// Shorthand notation available since PHP 5.4
$fruit = ['apples', 'pears', 'oranges'];
Tablicę można również zainicjować za pomocą niestandardowych indeksów (zwanych również tablicą asocjacyjną) :
// A simple associative array
$fruit = array(
'first' => 'apples',
'second' => 'pears',
'third' => 'oranges'
);
// Key and value can also be set as follows
$fruit['first'] = 'apples';
// Shorthand notation available since PHP 5.4
$fruit = [
'first' => 'apples',
'second' => 'pears',
'third' => 'oranges'
];
Jeśli zmienna nie była wcześniej używana, PHP utworzy ją automatycznie. Chociaż jest to wygodne, może to utrudnić odczytanie kodu:
$foo[] = 1; // Array( [0] => 1 )
$bar[][] = 2; // Array( [0] => Array( [0] => 2 ) )
Indeks zwykle będzie kontynuowany od momentu przerwania. PHP spróbuje użyć ciągów liczbowych jako liczb całkowitych:
$foo = [2 => 'apple', 'melon']; // Array( [2] => apple, [3] => melon )
$foo = ['2' => 'apple', 'melon']; // same as above
$foo = [2 => 'apple', 'this is index 3 temporarily', '3' => 'melon']; // same as above! The last entry will overwrite the second!
Aby zainicjować tablicę o ustalonym rozmiarze, możesz użyć SplFixedArray
:
$array = new SplFixedArray(3);
$array[0] = 1;
$array[1] = 2;
$array[2] = 3;
$array[3] = 4; // RuntimeException
// Increase the size of the array to 10
$array->setSize(10);
Uwaga: Tablica utworzona za pomocą SplFixedArray
ma zmniejszoną pamięć dla dużych zestawów danych, ale klucze muszą być liczbami całkowitymi.
Aby zainicjować tablicę o dynamicznym rozmiarze, ale z n
niepustymi elementami (np. Symbolem zastępczym), możesz użyć pętli w następujący sposób:
$myArray = array();
$sizeOfMyArray = 5;
$fill = 'placeholder';
for ($i = 0; $i < $sizeOfMyArray; $i++) {
$myArray[] = $fill;
}
// print_r($myArray); results in the following:
// Array ( [0] => placeholder [1] => placeholder [2] => placeholder [3] => placeholder [4] => placeholder )
Jeśli wszystkie symbole zastępcze są takie same, możesz je również utworzyć za pomocą funkcji array_fill()
:
tablica wypełnienie tablicy (int $ start_index, int $ num, mixed $ value)
To tworzy i zwraca tablicę z num
wpisów value
, klucze rozpoczynające się start_index
.
Uwaga: Jeśli start_index
jest ujemny, zacznie się od indeksu ujemnego i będzie kontynuował od 0 dla następujących elementów.
$a = array_fill(5, 6, 'banana'); // Array ( [5] => banana, [6] => banana, ..., [10] => banana)
$b = array_fill(-2, 4, 'pear'); // Array ( [-2] => pear, [0] => pear, ..., [2] => pear)
Wniosek: dzięki array_fill()
masz większe ograniczenia co do tego, co możesz zrobić. Pętla jest bardziej elastyczna i otwiera szerszy zakres możliwości.
Ilekroć chcesz, aby tablica była wypełniona zakresem liczb (np. 1-4), możesz albo dołączyć każdy pojedynczy element do tablicy, albo użyć funkcji range()
:
zakres tablicy (mieszany $ początek, mieszany $ koniec [, liczba $ krok = 1])
Ta funkcja tworzy tablicę zawierającą zakres elementów. Wymagane są dwa pierwsze parametry, w których określają punkt początkowy i końcowy zakresu (włącznie). Trzeci parametr jest opcjonalny i określa rozmiar podejmowanych kroków. Po utworzeniu range
od 0
do 4
z stepsize
1
, wynikowa tablica składałaby się z następujących elementów: 0
, 1
, 2
, 3
i 4
. Jeśli rozmiar kroku zostanie zwiększony do 2
(tj. range(0, 4, 2)
), wówczas wynikowa tablica będzie wynosić: 0
, 2
i 4
.
$array = [];
$array_with_range = range(1, 4);
for ($i = 1; $i <= 4; $i++) {
$array[] = $i;
}
print_r($array); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
print_r($array_with_range); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
range
może pracować z liczbami całkowitymi, zmiennoprzecinkowymi, logicznymi (które są rzutowane na liczby całkowite) i ciągami znaków. Należy jednak zachować ostrożność, używając argumentów zmiennoprzecinkowych ze względu na problem z precyzją zmiennoprzecinkową.
Sprawdź, czy klucz istnieje
Użyj array_key_exists()
lub isset()
lub !empty()
:
$map = [
'foo' => 1,
'bar' => null,
'foobar' => '',
];
array_key_exists('foo', $map); // true
isset($map['foo']); // true
!empty($map['foo']); // true
array_key_exists('bar', $map); // true
isset($map['bar']); // false
!empty($map['bar']); // false
Zauważ, że isset()
traktuje element o wartości null
jako nieistniejący. Natomiast !empty()
robi to samo dla każdego elementu, który jest równy false
(używając słabego porównania; na przykład null
, ''
i 0
są traktowane jako false przez !empty()
). While isset($map['foobar']);
jest true
!empty($map['foobar'])
jest false
. Może to prowadzić do błędów (na przykład łatwo zapomnieć, że łańcuch '0'
jest traktowany jako fałsz), więc używanie !empty()
jest często marne.
Zauważ też, że isset()
i !empty()
będą działać (i zwrócą false), jeśli $map
nie zostanie w ogóle zdefiniowane. To sprawia, że są nieco podatni na błędy:
// Note "long" vs "lang", a tiny typo in the variable name.
$my_array_with_a_long_name = ['foo' => true];
array_key_exists('foo', $my_array_with_a_lang_name); // shows a warning
isset($my_array_with_a_lang_name['foo']); // returns false
Możesz także sprawdzić tablice porządkowe:
$ord = ['a', 'b']; // equivalent to [0 => 'a', 1 => 'b']
array_key_exists(0, $ord); // true
array_key_exists(2, $ord); // false
Zauważ, że isset()
ma lepszą wydajność niż array_key_exists()
ponieważ ta ostatnia jest funkcją, a druga konstrukcją językową.
Możesz także użyć key_exists()
, który jest aliasem dla array_key_exists()
.
Sprawdzanie, czy wartość istnieje w tablicy
Funkcja in_array()
zwraca wartość true, jeśli element istnieje w tablicy.
$fruits = ['banana', 'apple'];
$foo = in_array('banana', $fruits);
// $foo value is true
$bar = in_array('orange', $fruits);
// $bar value is false
Możesz także użyć funkcji array_search()
aby uzyskać klucz określonego elementu w tablicy.
$userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael'];
$pos = array_search('Stefanie Mcmohn', $userdb);
if ($pos !== false) {
echo "Stefanie Mcmohn found at $pos";
}
W PHP 5.5 i nowszych można używać array_column()
w połączeniu z array_search()
.
Jest to szczególnie przydatne do sprawdzania, czy wartość istnieje w tablicy asocjacyjnej :
$userdb = [
[
"uid" => '100',
"name" => 'Sandra Shush',
"url" => 'urlof100',
],
[
"uid" => '5465',
"name" => 'Stefanie Mcmohn',
"pic_square" => 'urlof100',
],
[
"uid" => '40489',
"name" => 'Michael',
"pic_square" => 'urlof40489',
]
];
$key = array_search(40489, array_column($userdb, 'uid'));
Sprawdzanie poprawności typu tablicy
Funkcja is_array()
zwraca true, jeśli zmienna jest tablicą.
$integer = 1337;
$array = [1337, 42];
is_array($integer); // false
is_array($array); // true
Możesz wpisać podpowiedź do typu tablicy w funkcji, aby wymusić typ parametru; przekazanie czegokolwiek innego spowoduje błąd krytyczny.
function foo (array $array) { /* $array is an array */ }
Możesz także użyć funkcji gettype()
.
$integer = 1337;
$array = [1337, 42];
gettype($integer) === 'array'; // false
gettype($array) === 'array'; // true
Interfejsy ArrayAccess i Iterator
Inną przydatną funkcją jest dostęp do twoich niestandardowych kolekcji obiektów jako tablic w PHP. Istnieją dwa interfejsy dostępne w rdzeniu PHP (> = 5.0.0) do obsługi tego: ArrayAccess
i Iterator
. Ten pierwszy umożliwia dostęp do obiektów niestandardowych jako tablicy.
ArrayAccess
Załóżmy, że mamy klasę użytkownika i tabelę bazy danych przechowującą wszystkich użytkowników. Chcielibyśmy stworzyć klasę UserCollection
, która:
- pozwalają nam zwracać się do określonego użytkownika poprzez unikalny identyfikator jego nazwy użytkownika
- wykonywać podstawowe (nie wszystkie CRUD, ale przynajmniej Tworzenie, pobieranie i usuwanie) operacje na naszej kolekcji użytkowników
Rozważ następujące źródło (dalej używamy krótkiej składni tworzenia tablicy []
dostępnej od wersji 5.4):
class UserCollection implements ArrayAccess {
protected $_conn;
protected $_requiredParams = ['username','password','email'];
public function __construct() {
$config = new Configuration();
$connectionParams = [
//your connection to the database
];
$this->_conn = DriverManager::getConnection($connectionParams, $config);
}
protected function _getByUsername($username) {
$ret = $this->_conn->executeQuery('SELECT * FROM `User` WHERE `username` IN (?)',
[$username]
)->fetch();
return $ret;
}
// START of methods required by ArrayAccess interface
public function offsetExists($offset) {
return (bool) $this->_getByUsername($offset);
}
public function offsetGet($offset) {
return $this->_getByUsername($offset);
}
public function offsetSet($offset, $value) {
if (!is_array($value)) {
throw new \Exception('value must be an Array');
}
$passed = array_intersect(array_values($this->_requiredParams), array_keys($value));
if (count($passed) < count($this->_requiredParams)) {
throw new \Exception('value must contain at least the following params: ' . implode(',', $this->_requiredParams));
}
$this->_conn->insert('User', $value);
}
public function offsetUnset($offset) {
if (!is_string($offset)) {
throw new \Exception('value must be the username to delete');
}
if (!$this->offsetGet($offset)) {
throw new \Exception('user not found');
}
$this->_conn->delete('User', ['username' => $offset]);
}
// END of methods required by ArrayAccess interface
}
więc możemy :
$users = new UserCollection();
var_dump(empty($users['testuser']),isset($users['testuser']));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(empty($users['testuser']), isset($users['testuser']), $users['testuser']);
unset($users['testuser']);
var_dump(empty($users['testuser']), isset($users['testuser']));
który wyświetli następujące, zakładając, że przed uruchomieniem kodu nie było testuser
:
bool(true)
bool(false)
bool(false)
bool(true)
array(17) {
["username"]=>
string(8) "testuser"
["password"]=>
string(12) "testpassword"
["email"]=>
string(13) "[email protected]"
}
bool(true)
bool(false)
WAŻNE: offsetExists
nie jest wywoływany podczas sprawdzania istnienia klucza za pomocą funkcji array_key_exists
. Zatem poniższy kod wyświetli dwa razy false
:
var_dump(array_key_exists('testuser', $users));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(array_key_exists('testuser', $users));
Iterator
Rozszerzmy naszą klasę z góry o kilka funkcji z interfejsu Iterator
, aby umożliwić iterację z nią za pomocą foreach
i while
.
Najpierw musimy dodać właściwość zawierającą nasz bieżący indeks iteratora, dodajmy ją do właściwości klasy jako $_position
:
// iterator current position, required by Iterator interface methods
protected $_position = 1;
Po drugie, dodajmy interfejs Iterator
do listy interfejsów implementowanych przez naszą klasę:
class UserCollection implements ArrayAccess, Iterator {
następnie dodaj wymagane przez same funkcje interfejsu:
// START of methods required by Iterator interface
public function current () {
return $this->_getById($this->_position);
}
public function key () {
return $this->_position;
}
public function next () {
$this->_position++;
}
public function rewind () {
$this->_position = 1;
}
public function valid () {
return null !== $this->_getById($this->_position);
}
// END of methods required by Iterator interface
Podsumowując, jest to kompletne źródło klasy implementującej oba interfejsy. Zauważ, że ten przykład nie jest idealny, ponieważ identyfikatory w bazie danych mogą nie być sekwencyjne, ale zostały napisane tylko po to, aby dać ci główny pomysł: możesz adresować kolekcje obiektów w dowolny możliwy sposób, implementując interfejsy ArrayAccess
i Iterator
:
class UserCollection implements ArrayAccess, Iterator {
// iterator current position, required by Iterator interface methods
protected $_position = 1;
// <add the old methods from the last code snippet here>
// START of methods required by Iterator interface
public function current () {
return $this->_getById($this->_position);
}
public function key () {
return $this->_position;
}
public function next () {
$this->_position++;
}
public function rewind () {
$this->_position = 1;
}
public function valid () {
return null !== $this->_getById($this->_position);
}
// END of methods required by Iterator interface
}
oraz foreach zapętlający wszystkie obiekty użytkownika:
foreach ($users as $user) {
var_dump($user['id']);
}
co da wynik podobny do
string(2) "1"
string(2) "2"
string(2) "3"
string(2) "4"
...
Tworzenie tablicy zmiennych
$username = 'Hadibut';
$email = '[email protected]';
$variables = compact('username', 'email');
// $variables is now ['username' => 'Hadibut', 'email' => '[email protected]']
Ta metoda jest często używana w ramach do przekazywania tablicy zmiennych między dwoma komponentami.