Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[PropertyAccess] Add nullsafe operator support #34483

Copy link
Copy link
Closed
@ogizanagi

Description

@ogizanagi
Issue body actions

Description

Given an object graph foo.bar.baz, where bar is optional (can be null),
trying to call the property accessor with foo.bar.baz will throw a:

UnexpectedTypeException: PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "NULL" while trying to traverse path "foo.bar.baz" at property "baz".

In some use-cases, it'll be very handy to get null instead of this exception (e.g: in custom validation constraints using a property path set by the developper in annotations).

The flag introduced in #30545 allows to ignore exception on invalid property paths, but it works differently and has some drawbacks:

  • paths like foo.bak (non-existing property) will be considered as readable and return null. But foo.bar.baz would still throw the same exception.
  • it'll indeed hide potential mistakes in the property path. Which I'd like to avoid for this feature (bar must exist, but can be null).

Then I was about to suggest yet another flag for the PropertyAccessor ($throwOnNullValueInGraph?), but instead, I'm wondering if we shouldn't allow something mimicking the PHP nullsafe_calls RFC 👇

Example

Given an object graph foo.bar.baz, where bar is optional (can be null):

$propertyAccessor = PropertyAccess::createPropertyAccessor();

// Where class Foo has a `bar` property, and class Bar has a `baz` property, for which values are set by the constructors:
$full = new \stdClass();
$full->foo = new Foo(new Bar(new Baz()));

$propertyAccessor->getValue($full, 'foo.bar?.baz') // Would return the Baz instance

$noBar = new \stdClass();
$noBar->foo = new Foo(null);

$propertyAccessor->getValue($noBar, 'foo.bar?.baz') // Would return null

$noBak = new \stdClass();
$noBak->foo = new Foo(new Bar(new Baz()));

$propertyAccessor->getValue($noBak, 'foo.bak?.baz') // Would still throw a NoSuchPropertyException, as property `bak` does not exist in class `Foo`

This wouldn't change anything for writing, only for reading.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.