Ricerca…
introduzione
Una matrice è una struttura di dati che memorizza un numero arbitrario di valori in un singolo valore. Una matrice in PHP è in realtà una mappa ordinata, in cui la mappa è un tipo che associa valori a chiavi.
Sintassi
- $ array = array ('Value1', 'Value2', 'Value3'); // Chiavi predefinite su 0, 1, 2, ...,
- $ array = array ('Value1', 'Value2',); // Virgola finale opzionale
- $ array = array ('key1' => 'Value1', 'key2' => 'Value2',); // Chiavi esplicite
- $ array = array ('key1' => 'Value1', 'Value2',); // Array (['key1'] => Valore1 [1] => 'Valore2')
- $ array = ['key1' => 'Value1', 'key2' => 'Value2',]; // PHP 5.4+ stenografia
- $ array [] = 'ValueX'; // Aggiungi 'ValueX' alla fine dell'array
- $ array ['keyX'] = 'ValueX'; // Assegna "valoreX" al tasto "chiaveX"
- $ array + = ['keyX' => 'valoreX', 'chiaveY' => 'valoreY']; // Aggiunta / Sovrascrivi elementi su un array esistente
Parametri
Parametro | Dettaglio |
---|---|
Chiave | La chiave è l'identificativo univoco e l'indice di un array. Potrebbe essere una string o un integer . Pertanto, le chiavi valide sarebbero 'foo', '5', 10, 'a2b', ... |
Valore | Per ogni key c'è un valore corrispondente ( null altrimenti e un avviso viene emesso all'accesso ). Il valore non ha restrizioni sul tipo di input. |
Osservazioni
Inizializzazione di una matrice
Un array può essere inizializzato vuoto:
// An empty array
$foo = array();
// Shorthand notation available since PHP 5.4
$foo = [];
Un array può essere inizializzato e preimpostato con valori:
// Creates a simple array with three strings
$fruit = array('apples', 'pears', 'oranges');
// Shorthand notation available since PHP 5.4
$fruit = ['apples', 'pears', 'oranges'];
Un array può anche essere inizializzato con indici personalizzati (chiamati anche array associativi) :
// 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'
];
Se la variabile non è stata utilizzata in precedenza, PHP la creerà automaticamente. Mentre conveniente, questo potrebbe rendere il codice più difficile da leggere:
$foo[] = 1; // Array( [0] => 1 )
$bar[][] = 2; // Array( [0] => Array( [0] => 2 ) )
L'indice continuerà di solito dove era stato interrotto. PHP tenterà di utilizzare stringhe numeriche come numeri interi:
$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!
Per inizializzare un array con dimensioni fisse puoi usare 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);
Nota: un array creato utilizzando SplFixedArray
ha un ingombro di memoria ridotto per insiemi di dati di grandi dimensioni, ma le chiavi devono essere numeri interi.
Per inizializzare un array con una dimensione dinamica ma con n
elementi non vuoti (ad esempio un segnaposto) puoi usare un loop come segue:
$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 )
Se tutti i segnaposto sono uguali, puoi anche crearlo usando la funzione array_fill()
:
array array_fill (int $ start_index, int $ num, valore $ misto)
Questo crea e restituisce una matrice con le voci num
di value
, le chiavi iniziano da start_index
.
Nota: se start_index
è negativo, inizierà con l'indice negativo e continuerà da 0 per i seguenti elementi.
$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)
Conclusione: con array_fill()
sei più limitato per ciò che puoi effettivamente fare. Il ciclo è più flessibile e ti apre una gamma più ampia di opportunità.
Ogni volta che si desidera un array riempito con un intervallo di numeri (ad esempio 1-4), è possibile aggiungere ogni singolo elemento a un array o utilizzare la funzione range()
:
intervallo di matrice (mixed $ start, mixed $ end [, number $ step = 1])
Questa funzione crea una matrice contenente un intervallo di elementi. Sono richiesti i primi due parametri, in cui vengono impostati i punti iniziale e finale dell'intervallo (compreso). Il terzo parametro è facoltativo e definisce la dimensione dei passaggi da eseguire. Creando un range
da 0
a 4
con una stepsize
di 1
, l'array risultante sarebbe costituito dai seguenti elementi: 0
, 1
, 2
, 3
e 4
. Se la dimensione del passo è aumentata a 2
(cioè range(0, 4, 2)
), la matrice risultante sarebbe: 0
, 2
e 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
può funzionare con interi, float, booleani (che diventano convertiti in interi) e stringhe. Si deve prestare attenzione, tuttavia, quando si utilizzano float come argomenti a causa del problema di precisione in virgola mobile.
Controlla se la chiave esiste
Usa array_key_exists()
o isset()
o !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
Si noti che isset()
considera un elemento con valori null
come inesistente. Mentre !empty()
fa lo stesso per ogni elemento uguale a false
(usando un confronto debole, ad esempio null
, ''
e 0
sono tutti trattati come falsi da !empty()
). Mentre isset($map['foobar']);
è true
!empty($map['foobar'])
è false
. Ciò può portare a errori (ad esempio, è facile dimenticare che la stringa '0'
è considerata falsa), quindi l'uso di !empty()
è spesso disapprovato.
Nota anche che isset()
e !empty()
funzioneranno (e restituiranno false) se $map
non è affatto definita. Questo li rende in qualche modo soggetti a errori:
// 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
Puoi anche controllare gli array ordinali:
$ord = ['a', 'b']; // equivalent to [0 => 'a', 1 => 'b']
array_key_exists(0, $ord); // true
array_key_exists(2, $ord); // false
Si noti che isset()
ha prestazioni migliori rispetto a array_key_exists()
poiché quest'ultimo è una funzione e il precedente è un costrutto linguistico.
Puoi anche usare key_exists()
, che è un alias per array_key_exists()
.
Verifica se esiste un valore nell'array
La funzione in_array()
restituisce true se un elemento esiste in un array.
$fruits = ['banana', 'apple'];
$foo = in_array('banana', $fruits);
// $foo value is true
$bar = in_array('orange', $fruits);
// $bar value is false
È inoltre possibile utilizzare la funzione array_search()
per ottenere la chiave di un elemento specifico in una matrice.
$userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael'];
$pos = array_search('Stefanie Mcmohn', $userdb);
if ($pos !== false) {
echo "Stefanie Mcmohn found at $pos";
}
In PHP 5.5 e array_column()
successive puoi usare array_column()
insieme a array_search()
.
Questo è particolarmente utile per verificare se esiste un valore in un array associativo :
$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'));
Convalida il tipo di array
La funzione is_array()
restituisce true se una variabile è una matrice.
$integer = 1337;
$array = [1337, 42];
is_array($integer); // false
is_array($array); // true
È possibile digitare suggerimento del tipo di matrice in una funzione per imporre un tipo di parametro; passare qualcos'altro comporterà un errore fatale.
function foo (array $array) { /* $array is an array */ }
Puoi anche usare la funzione gettype()
.
$integer = 1337;
$array = [1337, 42];
gettype($integer) === 'array'; // false
gettype($array) === 'array'; // true
Interfacce ArrayAccess e Iterator
Un'altra caratteristica utile è l'accesso alle raccolte di oggetti personalizzati come matrici in PHP. Ci sono due interfacce disponibili in PHP (> = 5.0.0) core per supportare questo: ArrayAccess
e Iterator
. Il primo consente di accedere agli oggetti personalizzati come array.
ArrayAccess
Supponiamo di avere una classe utente e una tabella di database che memorizza tutti gli utenti. Vorremmo creare una classe UserCollection
che:
- consentirci di indirizzare determinati utenti tramite il loro identificatore univoco del nome utente
- esegui operazioni di base (non tutte CRUD, ma almeno Crea, Recupera ed Elimina) sulla nostra collezione di utenti
Considera la seguente fonte (qui di seguito viene utilizzata la sintassi per la creazione di array brevi []
disponibile dalla versione 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
}
allora possiamo :
$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']));
che genererà quanto segue, supponendo che non ci fosse nessun testuser
prima di lanciare il codice:
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)
IMPORTANTE: offsetExists
non viene chiamato quando si controlla l'esistenza di una chiave con la funzione array_key_exists
. Quindi il seguente codice verrà emesso false
due volte:
var_dump(array_key_exists('testuser', $users));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(array_key_exists('testuser', $users));
Iterator
Estendiamo la nostra classe dall'alto con alcune funzioni dell'interfaccia di Iterator
per consentirne l'iterazione con foreach
e while
.
Per prima cosa, dobbiamo aggiungere una proprietà contenente il nostro indice corrente di iteratore, aggiungiamola alle proprietà della classe come $_position
:
// iterator current position, required by Iterator interface methods
protected $_position = 1;
In secondo luogo, aggiungiamo l'interfaccia di Iterator
all'elenco delle interfacce implementate dalla nostra classe:
class UserCollection implements ArrayAccess, Iterator {
quindi aggiungi il richiesto dalle funzioni dell'interfaccia:
// 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
Quindi tutto qui è la fonte completa della classe che implementa entrambe le interfacce. Nota che questo esempio non è perfetto, perché gli ID nel database potrebbero non essere sequenziali, ma questo è stato scritto solo per darti l'idea principale: puoi indirizzare le tue collezioni di oggetti in ogni modo possibile implementando interfacce ArrayAccess
e 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
}
e un foreach che scorre su tutti gli oggetti utente:
foreach ($users as $user) {
var_dump($user['id']);
}
che produrrà qualcosa di simile
string(2) "1"
string(2) "2"
string(2) "3"
string(2) "4"
...
Creare una matrice di variabili
$username = 'Hadibut';
$email = '[email protected]';
$variables = compact('username', 'email');
// $variables is now ['username' => 'Hadibut', 'email' => '[email protected]']
Questo metodo è spesso usato in framework per passare una matrice di variabili tra due componenti.