PHPackages                             ahmedzidan/php-core - 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. ahmedzidan/php-core

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

ahmedzidan/php-core
===================

Disable default behavior of PHP objects.

1.0.1(4y ago)0121UnlicensePHPPHP ^8.0

Since Mar 7Pushed 4y agoCompare

[ Source](https://github.com/AFZidan/php-core)[ Packagist](https://packagist.org/packages/ahmedzidan/php-core)[ RSS](/packages/ahmedzidan-php-core/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (1)

[![Latest Stable Version](https://camo.githubusercontent.com/15ff7bb3ead0c7bad800f9184942b1bb1863e6b42e81ef436293c915c0de1da9/68747470733a2f2f706f7365722e707567782e6f72672f666c6573686772696e6465722f636f72652f762f737461626c65)](https://packagist.org/packages/fleshgrinder/core)[![License](https://camo.githubusercontent.com/78d16d996aaf284da95be2913d0076a49452a39d6b90ab7af7c7738c5c1b4370/68747470733a2f2f706f7365722e707567782e6f72672f666c6573686772696e6465722f636f72652f6c6963656e7365)](https://packagist.org/packages/fleshgrinder/core)[![Travis CI build status](https://camo.githubusercontent.com/ea79a52c43dc9158742632f1b954b0d7c2a809cd3335d6eca377456edf5a547b/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f466c6573686772696e6465722f7068702d636f72652e737667)](https://travis-ci.org/Fleshgrinder/php-core)[![AppVeyor CI build status](https://camo.githubusercontent.com/31da971237f904a597d16f3952437561bcf47c36036a54862fcf11f49ad2e8c0/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f75356662666e66376d337773386c31622f6272616e63682f6d61737465723f7376673d74727565)](https://ci.appveyor.com/project/Fleshgrinder/php-core/branch/master)

[![Coveralls branch](https://camo.githubusercontent.com/b2fd699cb874b2d4dee8e62290d5358a14048bd9d89d400ee274621014d5802f/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f466c6573686772696e6465722f7068702d636f72652f6d61737465722e737667)](https://coveralls.io/github/Fleshgrinder/php-core)[![Scrutinizer](https://camo.githubusercontent.com/5a3ef3493a8fffc705bccad9b935017745aaaafd51ea3fb3fd5d571a96b2bc81/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f466c6573686772696e6465722f7068702d636f72652e737667)](https://scrutinizer-ci.com/g/Fleshgrinder/php-core/)[![Code Climate: GPA](https://camo.githubusercontent.com/b8913474743bf24211b673e10c341dad352c48f512122ef43b2bf4f15c41e252/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636c696d6174652f6769746875622f466c6573686772696e6465722f7068702d636f72652e737667)](https://codeclimate.com/github/Fleshgrinder/php-core)[![Total Downloads](https://camo.githubusercontent.com/8cd882548e679fbe1444b639939c232709fbe72750dee988a7e07f5b17cbd50c/68747470733a2f2f706f7365722e707567782e6f72672f666c6573686772696e6465722f636f72652f646f776e6c6f616473)](https://packagist.org/packages/fleshgrinder/core)

Core
====

[](#core)

The **core** library provides the most basic functionality that is missing in PHP core (and most probably will never make it into it): helpers (in form of traits) to disable default PHP object behavior.

- [Installation](#installation)
- [Usage](#usage)
- [Testing](#testing)

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

[](#installation)

Open a terminal, enter your project directory and execute the following command to add this package to your dependencies:

```
composer require fleshgrinder/core
```

This command requires you to have Composer installed globally, as explained in the [installation chapter](https://getcomposer.org/doc/00-intro.md) of the Composer documentation.

Usage
-----

[](#usage)

### Disenchant

[](#disenchant)

The [Disenchant](src/Disenchant.php) trait can be used to disable support for the magic `__get`, `__isset`, `__set`, and `__unset` methods. Every object in PHP by default supports these methods for dynamic property management. However, these are features that are actually undesired in almost all situations. While support for them does not lead to serious bugs, it can result in in weird behavior. Especially in the case of value objects when equality is determined with PHP’s equality operator (`==`).

Suppose we have a simple value object:

```
final class ValueObject {
    private $value;
    public function __construct($value) {
        $this->value = $value;
    }
}
```

Using the equality operator to determine if two instances are equal or not is straight forward, the same is true for comparisons:

```
$v0 = new ValueObject(0);
$v1 = new ValueObject(1);

var_dump(
    $v0 < $v1,  // true
    $v0 = $v1, // false
    $v0 > $v1   // false
);
```

If we now add a property to `$v0` the result will be different:

```
$v0 = new ValueObject(0);
$v0->x = 42;
$v1 = new ValueObject(1);

var_dump(
    $v0 < $v1,  // false
    $v0 = $v1, // true
    $v0 > $v1   // true
);
```

Of course, these operators should not be used and instead specialized functionality like [Equalable](https://github.com/fleshgrinder/php-equalable)and [Comparable](https://github.com/fleshgrinder/php-comparable) should be used, but this trait adds another layer of safety to the whole program at almost no cost.

Other situations in which this trait is very handy is if your objects rely on the properties they have. For instance if `get_object_vars` is used somewhere. However, note that not all possibly weird behavior is fixed through the inclusion of this trait. It is, for instance, still possible to dynamically add properties via specially crafted `unserialize` strings. This is because PHP does not call any of these magic methods in that case but directly adds the properties to the object, validate your objects in your `__wakeup` or `unserialize` methods instead.

### Uncloneable

[](#uncloneable)

The [Uncloneable](src/Uncloneable.php) trait can be used to disable support for the `clone` keyword in client code. This is a good idea for objects that cannot be cloned for technical reasons, e.g. anything that encloses a resource of some kind like a database connection, or should not be cloned because it makes no sense, e.g. any kind of immutable implementation like value objects.

The magic `__clone` method is defined as *final* and *protected* in this trait, this ensures that subclasses of the class that uses the trait are not able to alter that contract. At the same time it allows the using class to use the clone functionality internally to provide copy-on-write support without breaking changes; as illustrated in the following example:

```
final class URI {
    use Fleshgrinder\Core\Uncloneable;

    // ...

    public function withFragment(string $fragment): URI {
        $clone = clone $this;
        $clone->fragment = $fragment;
        return $clone;
    }
}
```

Another interesting use-case are friend classes paired with the builder pattern to provide immutable entities.

```
abstract class EntityFriend {
    use Fleshgrinder\Core\Uncloneable;

    protected $value;

    protected function setValue(T $value): void {
        $this->value = $value;
    }
}

final class Entity extends EntityFriend {
    public function getValue(): T {
        return $this->value;
    }
}

final class EntityBuilder extends EntityFriend {
    private $entity;

    public function __construct() {
        $this->entity = new Entity;
    }

    public function build(): Entity {
        return clone $this->entity;
    }

    public function setValue(T $value): void {
        $this->entity->setValue($value);
    }
}
```

### Unconstructable

[](#unconstructable)

The [Unconstructable](src/Unconstructable.php) trait can be used to disable support for the `new` keyword in client code. This is almost always a good idea to [disable multiple constructor calls](https://wiki.php.net/rfc/disallow-multiple-constructor-calls)and enforce invariance for actual constructor method arguments. Of course, the class requires named constructors, otherwise construction would be impossible.

```
final class SomeClass {
    use Fleshgrinder\Core\Unconstructable;

    public static function new(): self {
        return new static;
    }
}
```

Another use-case are *final abstract* classes, which are not available in PHP.

```
final class AbstractFinalClass {
    use Fleshgrinder\Core\Unconstructable;

    public static function f() { }

    public static function f′() { }

    // ...
}
```

### Immutable

[](#immutable)

The [Immutable](src/Immutable.php) is a combination of all other traits, and is provided for convenience only. It is best used for any kind of immutable class, as the name already suggests.

Testing
-------

[](#testing)

Open a terminal, enter the project directory and execute the following commands to run the [PHPUnit](https://phpunit.de/) tests with your locally installed PHP executable.

```
make
```

You can also execute the following two commands, in case `make` is not available on our system:

```
composer install
composer test
```

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 88.9% 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 ~1839 days

Total

2

Last Release

1519d ago

PHP version history (2 changes)1.0.0PHP ^7.0

1.0.1PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/2565fae9720ee446b57d1bcc550ceb31f1d223448b6bffd9670eedf1d964e079?d=identicon)[ahmedzidan](/maintainers/ahmedzidan)

---

Top Contributors

[![Fleshgrinder](https://avatars.githubusercontent.com/u/1059453?v=4)](https://github.com/Fleshgrinder "Fleshgrinder (16 commits)")[![AFZidan](https://avatars.githubusercontent.com/u/4643935?v=4)](https://github.com/AFZidan "AFZidan (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ahmedzidan-php-core/health.svg)

```
[![Health](https://phpackages.com/badges/ahmedzidan-php-core/health.svg)](https://phpackages.com/packages/ahmedzidan-php-core)
```

###  Alternatives

[hyperf/di

A DI for Hyperf.

182.8M594](/packages/hyperf-di)[pantheon-systems/quicksilver-pushback

Push commits made via the Pantheon dashboard back to original GitHub repository.

153.1M18](/packages/pantheon-systems-quicksilver-pushback)[heroyt/tournament-generator

A set of classes used to create multiple kinds of tournament brackets in PHP.

6615.2k](/packages/heroyt-tournament-generator)

PHPackages © 2026

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