Symfony Component Advent Calendar 2023の24日目の記事です。
プロパティへ強制アクセス、"PropertyAccess"
PropertyAccessは、オブジェクトや配列のプロパティにアクセスするためのコンポーネントです。Symfony以外でも使えます。
インストール
composer require symfony/property-access
使い方
Get
use Symfony\Component\PropertyAccess\PropertyAccess;
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$array = [
'name' => 'すみだ',
'items' => [
'りんご',
'なし'
],
];
echo $propertyAccessor->getValue($array, '[name]'); // 'すみだ'
echo $propertyAccessor->getValue($array, '[age]']); // null
echo $propertyAccessor->getValue($array, '[items][1]']); // なし
$person = new Person(name: 'すみだ', active: true);
echo $propertyAccessor->getValue($person, 'name'); // 'すみだ'
echo $propertyAccessor->getValue($person, 'isActive'); // true
PropertyAccessor
オブジェクトを作り、getValue()
することで、値にアクセスできます。アクセスする際の引数ですが、1つめは配列やオブジェクト、2つめはその値のキーを設定します。例えば配列の場合、$array['name']
にアクセスしたいのであれば、添字である['name']
からクォーとを抜いてを渡します。オブジェクトの場合、パブリックなプロパティ名、もしくはGetterのget***
からget
をとったものを渡すとその値がとれます。
また、Isser, Hasserにも対応しており、is***
, has***
もGetterど同様な方法で値がとれます。
配列の場合は、キーや添字の値がないとnullとなりますが、オブジェクトの場合は、プロパティにアクセスできない(Getterが用意されていない、プロパティがpublicではない)場合は、配列と違い例外NoSuchPropertyException
が投げられます。
Set
use Symfony\Component\PropertyAccess\PropertyAccess;
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$array = [];
$propertyAccessor->setValue($array, '[name]', 'すみだ');
echo $array['name']; // すみだ
$propertyAccessor->setValue($array, '[items][1]', 'りんご');
dump($array);
/*
^ array:1 [
"items" => array:1 [
1 => "りんご"
]
]
*/
$person = new Person();
$propertyAccessor->setValue($person, 'name', 'すみだ');
echo $person->getName(); // すみだ
値をセットする場合は、setValue()
を使います。第2引数まではgetValue()
と同じで、3つめにセットしたい値を渡します。
これのすごいところ
このコンポーネント、値を取得・設定するだけなのでぱっと見すごくないんですが、連想配列の値からオブジェクト作る時などで活躍します。
use Symfony\Component\PropertyAccess\PropertyAccess;
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$itemArray = [
'name' => 'りんご',
'price' => 100,
'active' => true,
];
$item = new Item();
foreach ($itemArray as $key => $value) {
$propertyAccessor->setValue($item, $key, $value); // それぞれのSetterを使って値を設定
}
dump($item);
/*
App\Entity\Item^ {
-name: "りんご"
-price: 100
-active: true
}
*/
まとめ
今回はPropertyAccess
の紹介でした。使いこなすとリクエストの配列からDTO作ったり、Entity作ったりなどに役立ちます。