環境
- windows10
- PHP 8.x
PHPの配列の特徴
参照渡し
&$valueのように&を付けると、配列の要素が値渡しではなく参照渡しになるので、ループ内で配列の要素への変更を行うことが可能。
※ループを抜けた後も$valueは参照が継続しているので、ループ処理後unset(指定した変数を破棄できる)で破棄が必要
<?php
$array = [1, 2, 3];
foreach ($array as &$value) {
$value *= 2;
}
unset($value);
var_dump($array);
?>
// 出力結果
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
unsetしないと以下のようなことになってしまう。(最後の$valueがループを抜けた後も参照できる)
<?php
$array = [1, 2, 3];
foreach ($array as &$value) {
$value *= 2;
}
$value = $value + 100;
var_dump($array);
?>
array(3) {
[0]=>
int(2)
[1]=>
int(4)
[2]=>
&int(106)
}
配列メソッド一覧
基本(フィルター、マップ、簡約)
メソッド名 | ユースケース | 補足 |
array_filter | 配列の中から特定の要素のみ取り出した配列を生成したい 第三引数には、コールバック関数に渡す引数(フィルタリングに使用する変数)を指定できる | ※array_filterの返り値の配列はインデックス番号が振りなおされないので、array_filterの返り値にarray_valuesでインデックス番号を振りなおしてあげるほうがよい。 |
array_map | 配列の要素ひとつひとつに何かの処理をしたい | |
array_reduce | 配列の各要素にある処理を行い、一つの要素にまとめたい |
チェック系
メソッド名 | ユースケース | 補足 |
in_array | 配列の中に特定の要素があるかチェックしたい | |
is_array | 対象が配列かどうかをチェックしたい | |
array_key_exists | 指定したキーが配列に存在するかどうかを調べたい | 成功した場合に true を、失敗した場合に falseを返す |
取得系
メソッド名 | ユースケース | 補足 |
array_search | 配列の中に特定の要素があるかチェックし、ある場合はそのキーを取得したい | |
array_keys | 配列のキーのみ取得したい | |
array_values | 配列の値のみ取得したい | |
count() | 配列の要素数を取得したい |
追加・分割・統合
メソッド名 | ユースケース | 補足 |
array_push | 配列にひとつまたは複数要素を追加したい | ひとつの要素を加える場合は、 |
array_merge | 複数の配列をまとめたい | または+演算子 |
array_combine | 二つの配列から一つの連想配列を生成したい | |
array_chunk | 配列を指定した要素数の配列に分割したい |
その他
メソッド名(制御構造名) | ユースケース | 補足 |
foreach | 配列のループ |
|
range() | 範囲を指定して配列を生成したい | |
array_splice | 配列の一部を別の要素で置換したい | |
array_slice | 配列の特定の要素のみを取り出したい | |
array_shift | 配列から先頭の要素だけを取り出したい | |
array_unique | 配列から重複した値を削除したい |
以降で、詳細を見ていきます。
配列メソッド詳細(ユースケース別)
配列の中から特定の要素のみ取り出したい
array_filter
コールバック関数により、配列の要素を一つ一つチェックし、条件を満たした要素の配列を返します。
具体例1
<?php
namespace App\Sample\Part3;
class Greet
{
private array $greetArray = [
"En" => "Hello",
"Ja" => "こんにちは",
"Ch" => "ニーハオ",
"Ko" => "アンニョンハセヨ",
"Vi" => "シン・チャオ",
];
public function find(string $type): array
{
return array_filter(
$this->greetArray,
function ($key) use ($type) {
return $key === $type;
},
// 未指定なら配列の値をフィルタリング対象にできる
// ARRAY_FILTER_USE_BOTH を指定する配列のキーと値をフィルタリング対象にできる
ARRAY_FILTER_USE_KEY // 配列のキーをフィルタリング対象にできる
);
}
}
具体例2
formから送られてきた価格のidから、あらかじめ存在する価格のリストに含まれるidと一致する価格のリストを抽出する
$_GET["price_id"]
// formから送信されてきた以下の値と想定
[
["id" => 2],
["id" => 3],
]
$target_price_list=array_filter(
get_price_list(),
fn($price) => in_array($price["id"], $_GET["price_id"], false)
);
// $target_price_list
[
["id" => 2, "min" => 500, "max" => 599],
["id" => 3, "min" => 600, "max" => 699],array
]
function get_price_list()
{
return [
["id" => 1, "min" => 0, "max" => 499],
["id" => 2, "min" => 500, "max" => 599],
["id" => 3, "min" => 600, "max" => 699],
["id" => 4, "min" => 700, "max" => 799],
["id" => 5, "min" => 800, "max" => 899],
["id" => 6, "min" => 900, "max" => 999],
["id" => 7, "min" => 1000, "max" => 1099],
["id" => 8, "min" => 1100, "max" => 1199],
["id" => 9, "min" => 1200, "max" => 1299],
["id" => 10, "min" => 1300, "max" => 1399],
["id" => 11, "min" => 1400, "max" => 1499],
["id" => 12, "min" => 1500, "max" => null],
];
}
補足
第三引数のフラグは、「コールバック関数に引数として渡す内容」(何を条件としてフィルタリングするか)を指定します。
デフォルトは、連想配列の値のみを渡すようになっています。
ARRAY_FILTER_USE_KEY
- 値ではなく、キーだけをcallback
の引数として渡すARRAY_FILTER_USE_BOTH
- 値だけではなく、値とキーの両方をcallback
の引数として渡す
また、strlen関数と組み合わせることで、配列から空文字のみを削除するという処理も可能(array_valuesでインデックスを振りなおす)
public function exec(): array
{
// 文字列型でない、またはバイト数が0
// false, null, ""のバイト数は0
return array_values(array_filter($this->array, fn ($elem) => !is_string($elem) || strlen($elem)));
}
配列の要素ひとつひとつに何かの処理をしたい
array_map
- 配列の要素1つ1つに何か処理を実施して、結果の配列を返す
- 元の配列が連想配列の場合は、その連想配列のkeyの配列を第二引数に指定し、第三引数にvalueの配列を指定すると、以下のようにcallback関数の引数にkey、valueを受け取ることが可能
- 似たような関数にarray_walkがあるが、こちらは破壊的メソッド
<?php
$array = ["one" => 1, "two" => 2, "three" => 3, "four" => 4, "five" => 5];
$newArray = array_map(
fn($key, $value) => $key . ":" . $value,
array_keys($array),
array_values($array)
);
echo "<pre>";
var_dump($newArray);
echo "</pre>";
?>
//array(5) { [0]=> string(5) "one:1" [1]=> string(5) "two:2" [2]=> string(7) "three:3" [3]=> string(6) "four:4" [4]=> string(6) "five:5" }
ちなみに第二引数にコールバック関数ではなく、nullを渡すと以下のように、zip処理(複数のarrayについて、各arrayの各n番目の値をまとめてarrayにした新しいarrayを返す)が可能です。
配列の長さが等しくない場合、要素数の少ない配列は空の要素で拡張して、最も長い配列の要素数に合わせられます。
<?php
$a = [1, 2, 3];
$b = ['one', 'two', 'three'];
$d = array_map(null, $a, $b);
print_r($d);
?>
//
(
[0] => Array
(
[0] => 1
[1] => one
)
[1] => Array
(
[0] => 2
[1] => two
)
[2] => Array
(
[0] => 3
[1] => three
)
)
配列の各要素にある処理を行い、一つの要素にまとめたい
array_reduce
- コールバック関数では、第一引数に結果用変数($total)、第二引数に配列から取り出される1つの値($value)が渡る
$array1 = [ 1, 2, 3, 4 ];
$value = array_reduce($array1 , fn($total, $value) => $total += $value);
var_dump($value);
//
int(10)
配列の中に特定の要素があるかチェックしたい
in_array
<?php
$array1 = [
"PHP",
"Java",
"Ruby",
"Go",
];
var_dump(in_array("PHP", $array1, true));
?>
//
bool(true)
対象が配列かどうかをチェックしたい
is_array
配列ならtrue、そうでなければfalseを返すので、例えば、以下のようなエスケープ処理の分岐を配列の場合はループ処理で要素一つ一つをエスケープし、そうでなければ引数の要素をそのままエスケープする。等の処理が可能。
function escape($mixed) // $mixedはすべての型の要素
{
if (is_array($mixed)) {
return array_map(fn($value) => esc_html($value), $mixed);
}
return esc_html($mixed);
}
指定したキーが配列に存在するかどうかを調べたい
array_key_exists
・第一引数に検索したいキー名を指定する
$array2 = [
"first" => "PHP",
"second" => "Java",
"third" => "Ruby",
"fourth" => "Go",
];
$newArray = array_key_exists("first", $array2);
var_dump($newArray);
配列にひとつまたは複数要素を追加したい
一つの要素を追加
以下公式ドキュメントより引用
注意: もし配列にひとつの要素を加えるために array_push() を使用するなら、 関数を呼ぶオーバーヘッドがないので、
$array[] =
を使用するほうがいいです。
$array [] = "hoge";
複数の要素を追加
array_push($array, "hoge", "foo"...)
複数の配列をまとめたい
対象の配列をarray1、array2とする
+演算子
array1に対して、array2の要素のうち、存在しないキーの要素を追加する
<?php
$array1 = [
"1" => "PHP",
"2" => "Java",
"str" => "Ruby",
3 => "Go",
];
$array2 = [
"1" => "Javascript",
"2" => "CSS",
"str" => "Html",
4 => "Python",
];
var_dump($array1 + $array2);
?>
//
array(5) {
[1]=>
string(3) "PHP"
[2]=>
string(4) "Java"
["str"]=>
string(4) "Ruby"
[3]=>
string(2) "Go"
[4]=>
string(6) "Python"
}
array_merge
- キーが数値なら、両配列ともキーが数値のものは全て保持され、0から始まる連続した数値の添字で格納される
- 同じ文字列のキーを持つ要素は後ろの配列(array2)に上書きされる
<?php
$array1 = [
"1" => "PHP",
"2" => "Java",
"str" => "Ruby",
3 => "Go",
];
$array2 = [
"1" => "Javascript",
"2" => "CSS",
"str" => "Html",
3 => "Python",
];
var_dump(array_merge($array1, $array2));
?>
//
array(7) {
[0]=>
string(3) "PHP"
[1]=>
string(4) "Java"
["str"]=>
string(4) "Html"
[2]=>
string(2) "Go"
[3]=>
string(10) "Javascript"
[4]=>
string(3) "CSS"
[5]=>
string(6) "Python"
}
ちなみに、連想配列ではなく、ただの配列の場合はそれぞれ以下
- array_mergeは、array2の値をarray1にすべて追加
- +演算子は、何も追加しない
二つの配列から一つの連想配列を生成したい
array_combine
- 第一引数にkeysを、第二引数にvaluesを指定
$array2 = [
"first",
"second",
"third",
"fourth",
];
$array3 = [
"Javascript",
"CSS",
"Html",
"Python",
];
$newArray = array_combine($array2, $array3);
var_dump($newArray);
//
array(4) {
["first"]=>
string(10) "Javascript"
["second"]=>
string(3) "CSS"
["third"]=>
string(4) "Html"
["fourth"]=>
string(6) "Python"
}
配列のキーのみ取得したい
array_keys
- 単体で使用するというよりも、array_mapなどと組み合わせると真価を発揮する
$array = [
'aaa' => 1,
'bbb' => 2,
'ccc' => 3,
'ddd' => 4,
'eee' => 5,
];
$newArray = array_keys($array);
//
array(5) {
[0]=>
string(3) "aaa"
[1]=>
string(3) "bbb"
[2]=>
string(3) "ccc"
[3]=>
string(3) "ddd"
[4]=>
string(3) "eee"
}
配列の値のみ取得したい
array_values
$array = [
'aaa' => 1,
'bbb' => 2,
'ccc' => 3,
'ddd' => 4,
'eee' => 5,
];
$newArray = array_values($array);
//
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
配列の中に特定の要素があるかチェックし、ある場合はそのキーを取得したい
array_search
- 第三引数に型比較を行うかを指定可能(デフォルトはfalse)
- 見つかった場合は一番先頭側のキー、見つからなかった場合は
false
が返る
$array1 = [ 1, 2, 3, 4 ];
var_dump(array_search(2, $array1, true));
//
int(1)
配列から重複した値を削除するし、新規配列を返す
array_unique
第二引数に指定できるオプションは以下の通り。また、共通する値のみを抽出する場合はarray_intersectという関数がある
- SORT_REGULAR
型比較無し、通常の比較 - SORT_NUMERIC
数理として比較 - SORT_STRING
文字列として比較 - SORT_LOCALE_STRING
設定されている現在のロケールに沿い、文字列として比較
$array1 = [ 1, 4, 3, 4, 5, 2, 1 ];
var_dump(array_unique($array1));
array(5) {
[0]=>
int(1)
[1]=>
int(4)
[2]=>
int(3)
[4]=>
int(5)
[5]=>
int(2)
}
先頭の要素だけを取り出したい
array_shift
- 引数に指定した配列は参照渡しとなるため、元の配列は先頭の要素が除去された状態となり、返り値は、取り出された要素が返される。
- 反対に、対象配列の先頭に要素を追加する場合は、array_unshift
$array3 = [
"Javascript",
"CSS",
"Html",
"Python",
];
var_dump(array_shift($array3));
//
string(10) "Javascript"
配列の特定の要素のみを取り出し、その要素で構成される配列を取得したい
array_slice
- 第二引数に取得する範囲の開始インデックス番号を指定する
- オプションとして、第三引数には「開始インデックスからいくつの要素を取得するか」を指定可能
- 取得した配列はキーが振り直されますが、第四引数にtrueを指定すると振り直しは行われなくなる
$array2 = [
"Javascript",
"CSS",
"Html",
"Python",
];
$newArray = array_slice($array2, 1);
var_dump($newArray);
//
array(3) {
[0]=>
string(3) "CSS"
[1]=>
string(4) "Html"
[2]=>
string(6) "Python"
}
配列を指定した要素数の配列に分割したい
array_chunk
- 第二引数に分割数を指定する
$array2 = [
"Javascript",
"CSS",
"Html",
"Python",
];
$newArray = array_chunk($array2, 1);
//
array(4) {
[0]=>
array(1) {
[0]=>
string(10) "Javascript"
}
[1]=>
array(1) {
[0]=>
string(3) "CSS"
}
[2]=>
array(1) {
[0]=>
string(4) "Html"
}
[3]=>
array(1) {
[0]=>
string(6) "Python"
}
}
配列の一部を別の要素で置換したい
array_splice
- 値の追加のみを行う場合は、第三引数に0を指定する
$array1 = [
"PHP",
"Java",
"Ruby",
"Go",
];
// $array1のインデックス番号が2の要素から1つ置換する(Rubyを置換する)
$newArray = array_splice($array1, 2, 1, "Javascript");
var_dump($array1);
//
array(4) {
[0]=>
string(3) "PHP"
[1]=>
string(4) "Java"
[2]=>
string(10) "Javascript"
[3]=>
string(2) "Go"
}
配列の要素数を取得したい
count()
第二引数にCOUNT_RECURSIVEと指定すると、再帰的にカウントすることも可能
$array2 = [
"Javascript",
"CSS",
"Html",
"Python",
];
var_dump(count($array2));
//
int(4)
範囲を指定して配列を生成したい
range()
$array3 = range(1, 1000);
var_dump($array3);
//
array(1000) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
・・・割愛
まとめ
いかがでしたでしょうか。配列操作は、プログラムにおいてマスターしておく必要がある事項です。そこで本記事では、PHPにおける、ユースケース別の私的配列メソッドについて紹介しています。見やすいように各メソッドの一覧と、ユースケース別の説明を記載しておりますので、ぜひ参考にしてみてください。