サーチ…
前書き
配列は、任意の数の値を単一の値に格納するデータ構造です。 PHPの配列は実際には順序付けられたマップです。ここで、mapは値をキーに関連付ける型です。
構文
- $ array = array( 'Value1'、 'Value2'、 'Value3'); //キーのデフォルトは0,1,2、...、
- $ array = array( 'Value1'、 'Value2'、); //オプションの後続カンマ
- $ array = array( 'key1' => 'Value1'、 'key2' => 'Value2'、); //明示的なキー
- $ array = array( 'key1' => 'Value1'、 'Value2'、); //配列(['key1'] =>値1 [1] => '値2')
- $ array = ['key1' => 'Value1'、 'key2' => 'Value2'、]; // PHP 5.4+略語
- $ array [] = 'ValueX'; //配列の最後に 'ValueX'を追加します
- $ array ['keyX'] = 'ValueX'; // 'keyX'キーに 'valueX'を代入する
- $ array + = ['keyX' => 'valueX'、 'keyY' => 'valueY']; //既存の配列に要素を追加/上書きする
パラメーター
パラメータ | 詳細 |
---|---|
キー | キーは配列の一意の識別子とインデックスです。これはstring またはinteger です。したがって、有効なキーは'foo', '5', 10, 'a2b', ... |
値 | 各key には対応する値があります(そうでない場合はnull 、アクセス時に通知が発行されます )。値は入力タイプに制限がありません。 |
備考
配列の初期化
配列は空に初期化できます:
// An empty array
$foo = array();
// Shorthand notation available since PHP 5.4
$foo = [];
配列は次の値で初期化してプリセットすることができます:
// Creates a simple array with three strings
$fruit = array('apples', 'pears', 'oranges');
// Shorthand notation available since PHP 5.4
$fruit = ['apples', 'pears', 'oranges'];
配列は、カスタムインデックス(連想配列ともいいます)で初期化することもできます。
// 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'
];
以前に変数が使用されていなかった場合、PHPは自動的に変数を作成します。便利ですが、これによりコードを読みにくくすることができます:
$foo[] = 1; // Array( [0] => 1 )
$bar[][] = 2; // Array( [0] => Array( [0] => 2 ) )
索引は、通常中断したところから続行されます。 PHPは数値文字列を整数として使用しようとします:
$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!
固定サイズの配列を初期化するには、 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);
注: SplFixedArray
を使用して作成された配列は、大量のデータセットのメモリフットプリントが減少しますが、キーは整数でなければなりません。
動的なサイズでn
空ではない要素(たとえばプレースホルダ)を持つ配列を初期化するには、次のようにループを使用できます。
$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 )
すべてのプレースホルダが同じ場合は、 array_fill()
関数を使用してプレースホルダを作成することもできます。
配列array_fill(int $ start_index、int $ num、mixed $ value)
これは、 start_index
始まるnum
のvalue
項目を持つ配列を作成して返します。
注意: start_index
が負の場合は、負のインデックスから開始し、次の要素の場合は0から続行します。
$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)
結論: array_fill()
使うと、実際にできることがより制限されます。ループはより柔軟性があり、幅広い機会を提供します。
ある範囲の数値(例えば1-4)で配列が欲しいときは、すべての要素を配列に追加するか、 range()
関数を使うことができます:
配列の範囲(mixed $ start、mixed $ end [、number $ step = 1])
この関数は、ある範囲の要素を含む配列を作成します。最初の2つのパラメータは必須で、(両端の)範囲の開始点と終了点を設定します。 3番目のパラメータはオプションで、実行されるステップのサイズを定義します。作成range
から0
へ4
用いてstepsize
の1
、得られた配列は、以下の要素で構成されます: 0
、 1
、 2
、 3
、及び4
。ステップサイズはに増加する場合2
(すなわち、 range(0, 4, 2)
次に、得られた配列は次のようになり: 0
、 2
、及び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
は、整数、浮動小数点数、ブール値(整数にキャストされる)、および文字列で動作します。ただし、浮動小数点精度の問題で浮動小数点を引数として使用する場合は注意が必要です。
キーが存在するかどうかを確認する
array_key_exists()
またはisset()
または!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
isset()
は、 null
値の要素を存在しないものとして扱うことに注意してください。一方、 !empty()
はfalse
と等しい要素に対して同じことを行いfalse
(弱い比較を使用します;たとえば、 null
、 ''
および0
はすべて!empty()
によって偽として扱われます)。一方、 isset($map['foobar']);
true
!empty($map['foobar'])
、 !empty($map['foobar'])
はfalse
です。これは間違いを招く可能性があります(たとえば、文字列'0'
が偽として扱われることを忘れるのは簡単!empty()
はしばしば戸惑うことがあります。
また、 $map
がまったく定義されていなければ、 isset()
と!empty()
は動作し、falseを返します。これにより、若干エラーが発生しやすくなります。
// 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
序数配列を確認することもできます:
$ord = ['a', 'b']; // equivalent to [0 => 'a', 1 => 'b']
array_key_exists(0, $ord); // true
array_key_exists(2, $ord); // false
そのノートisset()
よりも良好な性能有するarray_key_exists()
後者は機能および前言語構造です。
また、使用することができますkey_exists()
の別名で、 array_key_exists()
。
配列に値が存在するかどうかを調べる
関数in_array()
は、項目が配列内に存在する場合にtrueを返します。
$fruits = ['banana', 'apple'];
$foo = in_array('banana', $fruits);
// $foo value is true
$bar = in_array('orange', $fruits);
// $bar value is false
関数array_search()
を使用して、配列内の特定の項目のキーを取得することもできます。
$userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael'];
$pos = array_search('Stefanie Mcmohn', $userdb);
if ($pos !== false) {
echo "Stefanie Mcmohn found at $pos";
}
PHP 5.5以降では、あなたが使用することができますarray_column()
と併せてarray_search()
これは、値が連想配列に存在するかどうかをチェックするのに特に便利です:
$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'));
配列の型の検証
関数is_array()
は、変数が配列の場合はtrueを返します。
$integer = 1337;
$array = [1337, 42];
is_array($integer); // false
is_array($array); // true
配列型を関数に入力して、パラメータ型を強制することができます。他のものを渡すと致命的なエラーになります。
function foo (array $array) { /* $array is an array */ }
gettype()
関数を使用することもできます。
$integer = 1337;
$array = [1337, 42];
gettype($integer) === 'array'; // false
gettype($array) === 'array'; // true
ArrayAccessおよびIteratorインタフェース
もう1つの便利な機能は、PHPで配列としてカスタムオブジェクトコレクションにアクセスすることです。これをサポートするPHP(> = 5.0.0)コアにはArrayAccess
とIterator
という2つのインタフェースがあります。前者では、カスタムオブジェクトに配列としてアクセスできます。
ArrayAccess
すべてのユーザーを格納するユーザークラスとデータベーステーブルがあるとします。次のようなUserCollection
クラスを作成します。
- 特定のユーザにユーザ名の一意の識別子を指定できるようにする
- 基本的な(すべてのCRUDではなく、少なくともCreate、Retrieve、Delete)操作をユーザーコレクションで実行する
以下のソースを考えてみましょう(以下、バージョン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
}
次に、
$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']));
コードを起動する前に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)
重要: offsetExists
あなたが持つキーの存在をチェックしたときに呼び出されていないarray_key_exists
機能を。次のコードはfalse
2回出力しfalse
:
var_dump(array_key_exists('testuser', $users));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(array_key_exists('testuser', $users));
イテレータ
foreach
とwhile
使ってforeach
を可能にするために、 Iterator
インターフェースからいくつかの関数を使ってクラスを上から拡張しましょう。
まず、イテレータの現在のインデックスを保持するプロパティを追加する必要があります。それを$_position
というクラスプロパティに追加しましょう:
// iterator current position, required by Iterator interface methods
protected $_position = 1;
次に、クラスによって実装されているインターフェースのリストにIterator
インターフェースを追加しましょう:
class UserCollection implements ArrayAccess, Iterator {
インターフェイス関数自体に必要なものを追加します:
// 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
したがって、ここでは両方のインタフェースを実装するクラスの完全なソースがあります。この例は完全ではないことに注意してください。なぜなら、データベース内のIDはシーケンシャルではないかもしれないが、これは主なアイデアを提供するためだけに書かれているため、 ArrayAccess
および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
}
すべてのユーザーオブジェクトをループするforeach:
foreach ($users as $user) {
var_dump($user['id']);
}
次のようなものが出力されます
string(2) "1"
string(2) "2"
string(2) "3"
string(2) "4"
...
変数の配列を作成する
$username = 'Hadibut';
$email = '[email protected]';
$variables = compact('username', 'email');
// $variables is now ['username' => 'Hadibut', 'email' => '[email protected]']
このメソッドは、多くの場合、2つのコンポーネント間で変数の配列を渡すためにフレームワークで使用されます。