ただの配列だと気が付きやすいのだが、連想配列の配列だと形が似ていて間違いやすいポイント。
stdClassの配列を更新する方法
stdClassはオブジェクトであり、オブジェクトを関数やforeachで渡すと参照コピーとなる。
Manualにも説明がある。
updateArray.updateStdClassArray
/** @var array 各配列にある[otherName]を更新する値を格納している配列. */
private const NEW_OTHERNAME = [
'アボカド' => '森のバター',
'グラジオラス' => '阿蘭陀菖蒲',
];
/** stdClassの配列を更新する. */
public function updateStdClassArray()
{
/** @var \stdClass[] $stdArray stdClassの配列. */
$stdArray = [
(object)['name' => 'イタリアンパセリ', 'otherName' => 'パースレー', 'gakumei' => 'Petroselinum neapolitanum', 'bunrui' => 'セリ科オランダゼリ属'],
(object)['name' => 'グラジオラス', 'otherName' => '唐菖蒲', 'gakumei' => 'Gladiolus', 'bunrui' => 'アヤメ科グラジオラス属'],
(object)['name' => 'アボカド', 'otherName' => 'ワニナシ', 'gakumei' => 'Persea americana', 'bunrui' => 'クスノキ科ワニナシ属'],
(object)['name' => 'マロウ', 'otherName' => 'ウスベニアオイ', 'gakumei' => 'Malva sylvestris', 'bunrui' => 'アオイ科ゼニアオイ属'],
];
var_dump($stdArray);
foreach ($stdArray as $std) {
$name = $std->name;
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$std->otherName = self::NEW_OTHERNAME[$name];
}
}
var_dump($stdArray);
}
$ php updateArray.php
array(4) {
[0]=>
object(stdClass)#2 (4) {
["name"]=>
string(24) "イタリアンパセリ"
["otherName"]=>
string(15) "パースレー"
["gakumei"]=>
string(25) "Petroselinum neapolitanum"
["bunrui"]=>
string(30) "セリ科オランダゼリ属"
}
[1]=>
object(stdClass)#3 (4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(9) "唐菖蒲"
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
object(stdClass)#4 (4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(12) "ワニナシ"
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=>
object(stdClass)#5 (4) {
["name"]=>
string(9) "マロウ"
["otherName"]=>
string(21) "ウスベニアオイ"
["gakumei"]=>
string(16) "Malva sylvestris"
["bunrui"]=>
string(30) "アオイ科ゼニアオイ属"
}
}
array(4) {
[0]=>
object(stdClass)#2 (4) {
["name"]=>
string(24) "イタリアンパセリ"
["otherName"]=>
string(15) "パースレー"
["gakumei"]=>
string(25) "Petroselinum neapolitanum"
["bunrui"]=>
string(30) "セリ科オランダゼリ属"
}
[1]=>
object(stdClass)#3 (4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(15) "阿蘭陀菖蒲" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
object(stdClass)#4 (4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(15) "森のバター" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=>
object(stdClass)#5 (4) {
["name"]=>
string(9) "マロウ"
["otherName"]=>
string(21) "ウスベニアオイ"
["gakumei"]=>
string(16) "Malva sylvestris"
["bunrui"]=>
string(30) "アオイ科ゼニアオイ属"
}
}
連想配列の配列を更新する方法
失敗事例 : foreachで連想配列はコピーされて別の連想配列になってしまうので更新されない。
updateArray.udateAssociativeArray
// private const NEW_OTHERNAMEは同じ.
/** 連想配列の配列を更新する. */
public function udateAssociativeArray()
{
/** @var array $associativeArray 連想配列の配列. */
$associativeArray = [
['name' => 'イタリアンパセリ', 'otherName' => 'パースレー', 'gakumei' => 'Petroselinum neapolitanum', 'bunrui' => 'セリ科オランダゼリ属'],
['name' => 'グラジオラス', 'otherName' => '唐菖蒲', 'gakumei' => 'Gladiolus', 'bunrui' => 'アヤメ科グラジオラス属'],
['name' => 'アボカド', 'otherName' => 'ワニナシ', 'gakumei' => 'Persea americana', 'bunrui' => 'クスノキ科ワニナシ属'],
['name' => 'マロウ', 'otherName' => 'ウスベニアオイ', 'gakumei' => 'Malva sylvestris', 'bunrui' => 'アオイ科ゼニアオイ属'],
];
var_dump($associativeArray);
foreach ($associativeArray as $associative) {
$name = $associative['name'];
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$associative['otherName'] = self::NEW_OTHERNAME[$name];
}
}
var_dump($associativeArray);
}
$ php updateArray.php
array(4) {
[0]=>
array(4) {
["name"]=>
string(24) "イタリアンパセリ"
["otherName"]=>
string(15) "パースレー"
["gakumei"]=>
string(25) "Petroselinum neapolitanum"
["bunrui"]=>
string(30) "セリ科オランダゼリ属"
}
[1]=>
array(4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(9) "唐菖蒲"
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
array(4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(12) "ワニナシ"
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=>
array(4) {
["name"]=>
string(9) "マロウ"
["otherName"]=>
string(21) "ウスベニアオイ"
["gakumei"]=>
string(16) "Malva sylvestris"
["bunrui"]=>
string(30) "アオイ科ゼニアオイ属"
}
}
array(4) {
[0]=> # 同じなので省略
[1]=>
array(4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(9) "唐菖蒲" #<<<<<<<<<<<<<<<<<<<<<<<< 更新されない。
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
array(4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(12) "ワニナシ" #<<<<<<<<<<<<<<<<<<<<<<<< 更新されない。
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=> # 同じなので省略
}
成功事例① : foreach内でコピーされた連想配列を配列に格納し直す。
updateArray.udateAssociativeArray
// 同じなので省略
/** @var int $key 配列に格納し直すためにキーを持っておく. */
foreach ($associativeArray as $key => $associative) {
$name = $associative['name'];
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$associative['otherName'] = self::NEW_OTHERNAME[$name];
// コピーされた連想配列を配列に格納し直す.
$associativeArray[$key] = $associative;
}
}
// 同じなので省略
$ php updateArray.php
# 変更前は同じ状態なので省略
array(4) {
[0]=> # 同じなので省略
[1]=>
array(4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(15) "阿蘭陀菖蒲" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
array(4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(15) "森のバター" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=> # 同じなので省略
}
成功事例② : foreach内で参照コピーにする。
updateArray.udateAssociativeArray
// 同じなので省略
/** @var array $associative 参照コピーにして値を更新する. */
foreach ($associativeArray as &$associative) {
$name = $associative['name'];
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$associative['otherName'] = self::NEW_OTHERNAME[$name];
}
// 参照コピーを解除する.
unset($associative);
}
// 同じなので省略
$ php updateArray.php
# 変更前は同じ状態なので省略
array(4) {
[0]=> # 同じなので省略
[1]=>
array(4) {
["name"]=>
string(18) "グラジオラス"
["otherName"]=>
string(15) "阿蘭陀菖蒲" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(9) "Gladiolus"
["bunrui"]=>
string(33) "アヤメ科グラジオラス属"
}
[2]=>
array(4) {
["name"]=>
string(12) "アボカド"
["otherName"]=>
string(15) "森のバター" #<<<<<<<<<<<<<<<<<<<<<<<< 更新された。
["gakumei"]=>
string(16) "Persea americana"
["bunrui"]=>
string(30) "クスノキ科ワニナシ属"
}
[3]=> # 同じなので省略
}
注意 : unsetを忘れると参照が残っちゃいます。
unsetを忘れると最後の要素に参照が残る
[3]=>
&array(4) { #<<<<<<<<<< 参照の「&」がくっついている。
["name"]=>
全貌
updateArray.php
<?php
namespace App;
class updateArray
{
/** @var array 各配列にある[otherName]を更新する値を格納している配列. */
private const NEW_OTHERNAME = [
'パセリ' => 'オランダゼリ',
'アボカド' => '森のバター',
'グラジオラス' => '阿蘭陀菖蒲',
'ダイズ' => '畑の肉',
];
/** stdClassの配列を更新する. */
public function updateStdClassArray()
{
/** @var \stdClass[] $stdArray stdClassの配列. */
$stdArray = [
(object)['name' => 'イタリアンパセリ', 'otherName' => 'パースレー', 'gakumei' => 'Petroselinum neapolitanum', 'bunrui' => 'セリ科オランダゼリ属'],
(object)['name' => 'グラジオラス', 'otherName' => '唐菖蒲', 'gakumei' => 'Gladiolus', 'bunrui' => 'アヤメ科グラジオラス属'],
(object)['name' => 'アボカド', 'otherName' => 'ワニナシ', 'gakumei' => 'Persea americana', 'bunrui' => 'クスノキ科ワニナシ属'],
(object)['name' => 'マロウ', 'otherName' => 'ウスベニアオイ', 'gakumei' => 'Malva sylvestris', 'bunrui' => 'アオイ科ゼニアオイ属'],
];
var_dump($stdArray);
foreach ($stdArray as $std) {
$name = $std->name;
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$std->otherName = self::NEW_OTHERNAME[$name];
}
}
var_dump($stdArray);
}
/** 連想配列の配列を更新する. */
public function udateAssociativeArray()
{
/** @var array $associativeArray 連想配列の配列. */
$associativeArray = [
['name' => 'イタリアンパセリ', 'otherName' => 'パースレー', 'gakumei' => 'Petroselinum neapolitanum', 'bunrui' => 'セリ科オランダゼリ属'],
['name' => 'グラジオラス', 'otherName' => '唐菖蒲', 'gakumei' => 'Gladiolus', 'bunrui' => 'アヤメ科グラジオラス属'],
['name' => 'アボカド', 'otherName' => 'ワニナシ', 'gakumei' => 'Persea americana', 'bunrui' => 'クスノキ科ワニナシ属'],
['name' => 'マロウ', 'otherName' => 'ウスベニアオイ', 'gakumei' => 'Malva sylvestris', 'bunrui' => 'アオイ科ゼニアオイ属'],
];
var_dump($associativeArray);
/** @var array $associative 参照コピーにして値を更新する. */
foreach ($associativeArray as &$associative) {
$name = $associative['name'];
if (array_key_exists($name, self::NEW_OTHERNAME)) {
// NEW_OTHERNAMEに[name]の値が一致するキーがあれば[otherName]を更新する.
$associative['otherName'] = self::NEW_OTHERNAME[$name];
}
// 参照コピーを解除する.
unset($associative);
}
var_dump($associativeArray);
}
}
$clas = new updateArray();
$clas->updateStdClassArray();
$clas->udateAssociativeArray();