PHP
arrayer
Sök…
Introduktion
En matris är en datastruktur som lagrar ett godtyckligt antal värden i ett enda värde. En matris i PHP är faktiskt en ordnad karta, där kartan är en typ som kopplar värden till nycklar.
Syntax
- $ array = array ('Value1', 'Value2', 'Value3'); // Tangenter som standard är 0, 1, 2, ...,
- $ array = array ('Value1', 'Value2',); // Valfri efterföljande komma
- $ array = array ('key1' => 'Value1', 'key2' => 'Value2',); // Explicit nycklar
- $ array = array ('key1' => 'Value1', 'Value2',); // Array (['key1'] => Value1 [1] => 'Value2')
- $ array = ['key1' => 'Value1', 'key2' => 'Value2',]; // PHP 5.4+ kortfattning
- $ array [] = 'ValueX'; // Lägg till 'ValueX' i slutet av matrisen
- $ array ['keyX'] = 'ValueX'; // Tilldela 'värdeX' till nyckeln 'keyX'
- $ array + = ['keyX' => 'valueX', 'keyY' => 'valueY']; // Lägga till / skriva över element i en befintlig matris
parametrar
Parameter | Detalj |
---|---|
Nyckel | Nyckeln är den unika identifieraren och indexet för en matris. Det kan vara en string eller ett integer . Därför skulle giltiga nycklar vara 'foo', '5', 10, 'a2b', ... |
Värde | För varje key finns ett motsvarande värde ( null annars och ett meddelande skickas vid åtkomst ). Värdet har inga begränsningar för ingångstypen. |
Anmärkningar
Initiera en matris
En matris kan initieras tom:
// An empty array
$foo = array();
// Shorthand notation available since PHP 5.4
$foo = [];
En matris kan initieras och förinställas med värden:
// Creates a simple array with three strings
$fruit = array('apples', 'pears', 'oranges');
// Shorthand notation available since PHP 5.4
$fruit = ['apples', 'pears', 'oranges'];
En matris kan också initialiseras med anpassade index (även kallad en associerande matris) :
// 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'
];
Om variabeln inte har använts tidigare skapar PHP den automatiskt. Även om det är bekvämt kan det göra koden svårare att läsa:
$foo[] = 1; // Array( [0] => 1 )
$bar[][] = 2; // Array( [0] => Array( [0] => 2 ) )
Indexet fortsätter vanligtvis där du slutade. PHP kommer att försöka använda numeriska strängar som heltal:
$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!
För att initiera en matris med fast storlek kan du använda 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);
Obs: En matris skapad med SplFixedArray
har ett minskat fotavtryck för stora uppsättningar av data, men nycklarna måste vara heltal.
För att initiera en matris med en dynamisk storlek men med n
icke tomma element (t.ex. en platshållare) kan du använda en slinga enligt följande:
$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 )
Om alla dina platshållare är desamma kan du också skapa den med funktionen array_fill()
:
array array_fill (int $ start_index, int $ num, blandat $ värde)
Detta skapar och returnerar en matris med num
value
, nycklar som börjar vid start_index
.
Obs: Om start_index
är negativt börjar det med det negativa indexet och fortsätter från 0 för följande element.
$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)
Slutsats: Med array_fill()
du mer begränsad för vad du faktiskt kan göra. Slingan är mer flexibel och ger dig ett större utbud av möjligheter.
När du vill ha en matris fylld med ett antal nummer (t.ex. 1-4) kan du antingen lägga till varje element till en matris eller använda funktionen range()
:
matrisintervall (blandat $ start, blandat $ slut [, nummer $ steg = 1])
Denna funktion skapar en matris som innehåller en rad element. De två första parametrarna krävs, där de ställer in start- och slutpunkter för (inklusive) intervallet. Den tredje parametern är valfri och definierar storleken på stegen som vidtas. Genom att skapa ett range
från 0
till 4
med ett stepsize
på 1
, skulle den resulterande matrisen bestå av följande element: 0
, 1
, 2
, 3
och 4
. Om stegstorleken ökas till 2
(dvs. range(0, 4, 2)
) skulle den resulterande matrisen vara: 0
, 2
och 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
kan arbeta med heltal, flottörer, booléer (som kastas till heltal) och strängar. Försiktighet bör emellertid vidtas när du använder flottörer som argument på grund av det svåra punktens precisionsproblem.
Kontrollera om nyckeln finns
Använd array_key_exists()
eller isset()
eller !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
Observera att isset()
behandlar ett null
element som obefintligt. Medan !empty()
gör samma sak för alla element som är lika false
(med en svag jämförelse; till exempel null
, ''
och 0
behandlas alla som falska av !empty()
). While isset($map['foobar']);
är true
!empty($map['foobar'])
är false
. Detta kan leda till misstag (till exempel är det lätt att glömma att strängen '0'
behandlas som falsk) så användningen av !empty()
är ofta rynkad på.
Observera också att isset()
och !empty()
kommer att fungera (och returnera falskt) om $map
inte definieras alls. Detta gör dem något felaktiga att använda:
// 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
Du kan också kontrollera för ordinarie matriser:
$ord = ['a', 'b']; // equivalent to [0 => 'a', 1 => 'b']
array_key_exists(0, $ord); // true
array_key_exists(2, $ord); // false
Observera att isset()
har bättre prestanda än array_key_exists()
eftersom den senare är en funktion och den förra en språkkonstruktion.
Du kan också använda key_exists()
, som är ett alias för array_key_exists()
.
Kontrollera om ett värde finns i matrisen
Funktionen in_array()
returnerar true om ett objekt finns i en matris.
$fruits = ['banana', 'apple'];
$foo = in_array('banana', $fruits);
// $foo value is true
$bar = in_array('orange', $fruits);
// $bar value is false
Du kan också använda funktionen array_search()
att få nyckeln till ett specifikt objekt i en matris.
$userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael'];
$pos = array_search('Stefanie Mcmohn', $userdb);
if ($pos !== false) {
echo "Stefanie Mcmohn found at $pos";
}
I PHP 5.5 och senare kan du använda array_column()
tillsammans med array_search()
.
Detta är särskilt användbart för att kontrollera om ett värde finns i en associerande grupp :
$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'));
Validera arraytypen
Funktionen is_array()
returnerar true om en variabel är en matris.
$integer = 1337;
$array = [1337, 42];
is_array($integer); // false
is_array($array); // true
Du kan skriva antydan till arraytypen i en funktion för att verkställa en parametertyp; att lämna allt annat kommer att leda till ett dödligt fel.
function foo (array $array) { /* $array is an array */ }
Du kan också använda gettype()
.
$integer = 1337;
$array = [1337, 42];
gettype($integer) === 'array'; // false
gettype($array) === 'array'; // true
ArrayAccess och Iterator-gränssnitt
En annan användbar funktion är att komma åt dina anpassade objektsamlingar som matriser i PHP. Det finns två gränssnitt tillgängliga i PHP (> = 5.0.0) för att stödja detta: ArrayAccess
och Iterator
. Den förstnämnda ger dig tillgång till dina anpassade objekt som array.
ArrayAccess
Antag att vi har en användarklass och en databastabell som lagrar alla användare. Vi vill skapa en UserCollection
klass som kommer att:
- låt oss adressera vissa användare med deras unika användarnamn
- utför grundläggande (inte alla CRUD, men åtminstone Skapa, hämta och radera) operationer i vår användares samling
Tänk på följande källa (nedan använder vi syntax för uppställning av kort array []
tillgänglig sedan version 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
}
då kan vi :
$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']));
vilket kommer att mata ut följande, förutsatt att det inte fanns någon testuser
innan vi startade koden:
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)
VIKTIGT: offsetExists
kallas inte när du kontrollerar att det finns en nyckel med funktionen array_key_exists
. Så följande kod kommer att mata ut false
två gånger:
var_dump(array_key_exists('testuser', $users));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(array_key_exists('testuser', $users));
iterator
Låt oss utöka vår klass ovanifrån med några funktioner från Iterator
gränssnittet för att möjliggöra iterering över den med foreach
och while
.
Först måste vi lägga till en egenskap som har vårt nuvarande iteratorindex, låt oss lägga till det till klassegenskaperna som $_position
:
// iterator current position, required by Iterator interface methods
protected $_position = 1;
För det andra, låt oss lägga till Iterator
gränssnitt till listan över gränssnitt som implementeras av vår klass:
class UserCollection implements ArrayAccess, Iterator {
lägg sedan till det som krävs av själva gränssnittsfunktionerna:
// 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
Så allt är här en komplett källa till klassen som implementerar båda gränssnitten. Observera att det här exemplet inte är perfekt, eftersom ID: erna i databasen kanske inte är sekventiella, men detta har skrivits för att ge dig huvudidén: du kan adressera dina objektsamlingar på alla möjliga sätt genom att implementera ArrayAccess
och Iterator
gränssnitt:
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
}
och en förhand som går igenom alla användarobjekt:
foreach ($users as $user) {
var_dump($user['id']);
}
vilket kommer att ge ut något liknande
string(2) "1"
string(2) "2"
string(2) "3"
string(2) "4"
...
Skapa en rad variabler
$username = 'Hadibut';
$email = '[email protected]';
$variables = compact('username', 'email');
// $variables is now ['username' => 'Hadibut', 'email' => '[email protected]']
Denna metod används ofta i ramar för att skicka en rad variabler mellan två komponenter.