PHPackages                             webhappens/magic-properties - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. webhappens/magic-properties

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

webhappens/magic-properties
===========================

Add a simple fluid interface for getters, setters, accessors and mutators to any PHP class.

v0.3.0(5y ago)26.3k1MITPHPPHP ^7.3|^8.0

Since Feb 24Pushed 5y ago1 watchersCompare

[ Source](https://github.com/webhappens/magic-properties)[ Packagist](https://packagist.org/packages/webhappens/magic-properties)[ Docs](https://github.com/webhappens/magic-properties)[ RSS](/packages/webhappens-magic-properties/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (8)Used By (1)

[![tests](https://github.com/webhappens/magic-properties/workflows/tests/badge.svg)](https://github.com/webhappens/magic-properties/workflows/tests/badge.svg)

Magic properties
================

[](#magic-properties)

Add a simple fluid interface for getters, setters, accessors and mutators to any PHP class.

- [Installation](#installation)
- [Getters](#getters)
- [Setters](#setters)
- [Readonly properties](#readonly-properties)
- [Chainable setters](#chainable-setters)
- [Accessors](#accessors)
- [Mutators](#mutators)
- [Serialization](#serialization)

Installation
------------

[](#installation)

Install via composer:

```
composer require webhappens/magic-properties
```

Insert the `MagicProperties` trait into your class:

```
use \WebHappens\MagicProperties\MagicProperties;
```

If your class is already using the `__call` method, add the following to it:

```
public function __call($method, $arguments)
{
    // ...

    if ($property = $this->matchMagicProperty($name)) {
        return $this->callMagicProperty($property, $arguments);
    }

    // ...

    // throw new \BadMethodCallException();
}
```

Getters
-------

[](#getters)

Getters support both "property" and "method" syntax and allow you to get `public` and `protected` properties.

```
$person = new class {
    use MagicProperties;

    public $name = 'Sam';
    protected $role = 'developer';
};

$name = $person->name;
// or
$name = $person->name();

$role = $person->role;
// or
$role = $person->role();
```

The Getter "method" name may optionally be prefixed with "get" if you prefer that syntax.

```
$person->getName();
```

Setters
-------

[](#setters)

Setters support both "property" and "method" syntax and allow you to set `public` and `protected` properties.

```
$person = new class {
    use MagicProperties;

    public $name;
    protected $role;
};

$person->name = 'Sam';
// or
$person->name('Sam');

$person->role = 'developer';
// or
$person->role('developer');
```

The Setter "method" name may optionally be prefixed with "set" if you prefer that syntax.

```
$person->setName('Sam');
```

Readonly properties
-------------------

[](#readonly-properties)

If you want to protect specific `protected` properties from being set from **outside the class**, you may list them in an `$readonly` array inside your class.

```
protected $readonly = ['id'];
```

Readonly properties can still be changed from **inside the class** using the standard php syntax.

Chainable setters
-----------------

[](#chainable-setters)

When using the "method" syntax for Setters you may set multiple properties in a single chain.

```
$person->name('Sam')->role('developer');
```

Accessors
---------

[](#accessors)

When a Getter is called for a `protected` property from **outside the class**, the value is passed through an Accessor method, giving you a chance to modify it before it is returned.

When called from **inside the class**, it is only passed through an Accessor method when "method" syntax is used.

`public` and `private` properties are **never** passed through an Accessor method.

To add an Accessor method for a `protected` property, simply create a `protected` method that follows the Accessor naming convention of `get{PropertyName}Property`.

The method will receive the stored value as a single argument and should return the modified value.

```
$person = new class {
    use MagicProperties;

    protected $role = 'developer';

    protected function getRoleProperty($value)
    {
        return ucwords($value);
    }
};

$role = $person->role;
// or
$role = $person->role();
```

In this example, the role will be returned with an uppercase first letter.

Mutators
--------

[](#mutators)

When a Setter is called for a `protected` property from **outside the class**, the value is passed through a Mutator method, giving you a chance to modify it before it is set.

When called from **inside the class**, it is only passed through a Mutator method when "method" syntax is used.

`public` and `private` properties are **never** passed through a Mutator method.

To add a Mutator method for a `protected` property, simply create a `protected` method that follows the Mutator naming convention of `set{PropertyName}Property`.

The method will receive the passed value as a single argument and should return the modified value.

```
$person = new class {
    use MagicProperties;

    protected $role;

    protected function setRoleProperty($value)
    {
        return ucwords($value);
    }
};

$person->role = 'developer';
// or
$person->role('developer');
```

In this example, the role will be stored with an uppercase first letter.

Serialization
-------------

[](#serialization)

Call the `getMagicProperties` method to serialize all `public` and `protected` properties to an array.

Credits
-------

[](#credits)

- Sam Leicester:
- Ben Gurney:
- [All Contributors](../../contributors)

Our `Str` class is just a copy of some functions from Laravel's `Str` helper.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity25

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~67 days

Recently: every ~82 days

Total

6

Last Release

1932d ago

PHP version history (3 changes)v0.1.0PHP ^7.3

v0.2.0PHP ^7.1

v0.3.0PHP ^7.3|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/988de2ed821f544a3dcf054d14167b3921df7a87e07d98038d52bf4caf6347fc?d=identicon)[sleicester](/maintainers/sleicester)

![](https://www.gravatar.com/avatar/9b62c6a5d92ad11d42ffbb44772833c48e5ec3b21af4f9869628a0d0daa1800c?d=identicon)[bgurney](/maintainers/bgurney)

---

Top Contributors

[![sleicester](https://avatars.githubusercontent.com/u/319829?v=4)](https://github.com/sleicester "sleicester (25 commits)")[![bgurney](https://avatars.githubusercontent.com/u/6359858?v=4)](https://github.com/bgurney "bgurney (3 commits)")

---

Tags

accessorchainable-settersgettersmagic-propertiesphpwebhappensgetterssettersmagic-properties

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/webhappens-magic-properties/health.svg)

```
[![Health](https://phpackages.com/badges/webhappens-magic-properties/health.svg)](https://phpackages.com/packages/webhappens-magic-properties)
```

###  Alternatives

[marcin-orlowski/lombok-php

Never write boilerplate code for your data class again!

3118.6k1](/packages/marcin-orlowski-lombok-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
