LoginSignup
0
0

プロパティへ強制アクセス、"PropertyAccess"

Last updated at Posted at 2023-12-23

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作ったりなどに役立ちます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0