Search by

antevemus / adeep-property-access

helitonjr

Zero-dependency PHP 8.2+ property reader for arrays and objects: dot-notation paths, array/ArrayAccess keys, getX/x/isX/hasX methods, public and magic properties, and private fields only when the class author opts in with #[Specifiable]. The shared accessor of antevemus/aspecification and antevemus/

v1.0.1 2026-10-21 12:53 UTC

This package is auto-updated.

Last update: 2026-10-22 09:10:15 UTC


README

馃嚭馃嚫 English 聽|聽 馃嚙馃嚪 Portugu锚s (Brasil)

CI PHP Version Latest Version License: MIT Dependencies

Zero-dependency PHP 8.2+ property reader for arrays and objects: dot-notation paths, array/ArrayAccess keys, getX()/x()/isX()/hasX() methods, public and magic properties, and private fields only when the class author opts in with #[Specifiable]. The shared accessor of antevemus/aspecification and antevemus/alinq-collection.

The documentation lives in docs/en (English) and docs/pt-BR (Portuguese, Brazil), one page per topic, in the Docs Kit format (a docs-nav.json per language), and every PHP block of the pages is run by the test suite.

馃摝 Installation

Install via Composer: composer require antevemus/adeep-property-access. Requirements: PHP 8.2 or later (tested on 8.2, 8.3 and 8.4); no extension and no Composer package at runtime.

One class, Antevemus\ADeepPropertyAccess\PropertyAccess, with three static methods: getValue(), hasProperty() and accessor() (PropertyAccess); one attribute, #[Specifiable], the opt-in for private fields (Private fields).

馃殌 Quick Start

The same block opens Getting Started, and the test suite runs it with the answers written in its comments:

use Antevemus\ADeepPropertyAccess\PropertyAccess;

$order = [
    'id' => 42,
    'customer' => ['name' => 'Ana', 'address' => ['city' => 'Lisbon']],
    'coupon' => null,
];

PropertyAccess::getValue($order, 'customer.address.city'); // => 'Lisbon'
PropertyAccess::getValue($order, 'customer.phone'); // => null
PropertyAccess::hasProperty($order, 'coupon'); // => true
PropertyAccess::hasProperty($order, 'customer.phone'); // => false

馃摎 Documentation

Getting started

Concepts

  • Resolution order 路 pt-BR: The six steps that resolve each segment of a path, the first match winning; dot paths; what hasProperty() counts as existing.
  • Objects 路 pt-BR: Getters and nested objects; magic properties, stdClass and ArrayAccess.
  • Private fields: #[Specifiable] 路 pt-BR: The opt-in that makes a private or protected property readable by name, and why it is an opt-in.
  • What is never called 路 pt-BR: Private and protected methods, __call(), magic methods and methods with a required parameter.

API reference

  • PropertyAccess 路 pt-BR: getValue(), hasProperty() and accessor(), and the accessor in array_map(), usort() and LINQ selectors.

Internals

  • Performance 路 pt-BR: The resolution plan kept per class and name, what is never kept, and the bound of the plan table.

Quality

  • Tests 路 pt-BR: The PHPUnit report and what each test class covers.

Project

  • Roadmap 路 pt-BR: The release shipped and its adoption by ASpecification and ALinq; the milestone view is in ROADMAP.md.
  • ASpecification and ALinq 路 pt-BR: The two libraries this accessor was extracted from, and where it differs from their 1.x copies.

馃И Quality

  • Tests: 234 PHPUnit tests (vendor/bin/phpunit) and 1508 assertions, 100% passing, none skipped; the CI runs them on PHP 8.2, 8.3 and 8.4: the contract battery (171 cases, every expected value and existence written), the resolution plan per class and name, the #[Specifiable] opt-in, what is never called, and the code blocks of the documentation.
  • The report and what each test class covers: Tests.

馃敆 Relationship with ASpecification and ALinq

antevemus/aspecification and antevemus/alinq-collection each carried a copy of this accessor in their 1.x releases; this package is that accessor, extracted so that both libraries read the same value from the same candidate by construction, and their 2.0.0 releases depend on it, their own #[Specifiable] attributes recognized by name. Where the behaviour differs from the 1.x copies: ASpecification and ALinq; every change in CHANGELOG.md.

馃搫 License

MIT, see LICENSE. Provenance of the last resolution step (Domian) in NOTICE.md; the Apache License 2.0 text in THIRD_PARTY_NOTICES.md.