Download the PHP package jesseschalken/magic-utils without Composer
On this page you can find all versions of the php package jesseschalken/magic-utils. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download jesseschalken/magic-utils
More information about jesseschalken/magic-utils
Files in jesseschalken/magic-utils
Package magic-utils
Short Description Traits and functions to help with implementing PHP's magic methods
License MIT
Informations about the package magic-utils
php-magic-utils
php-magic-utils provides traits and functions to help with the implementation of PHP's magic methods, especially __clone()
.
Method | Default | Disallow |
---|---|---|
__construct() |
nothing, construction allowed | use NoConstruct; |
__destruct() |
nothing | |
__call() , __callStatic() |
Fatal error: Call to undefined method $class::$method() |
use NoDynamicMethods; |
__get() , __set() , __isset() , __unset() |
Write: Create undeclared public properties (!) Read: Undefined property: $class::$property |
use NoDynamicProperties; |
__sleep() , __wakeup() |
nothing, serialize() /unserialize() allowed |
use NoSerialize; |
__toString() |
Catchable fatal error: Object of class $class could not be converted to string |
|
__invoke() |
Fatal error: Function name must be a string |
|
__set_state() |
Fatal error: Call to undefined method $class::__set_state() |
|
__clone() |
shallow clone (for deep clone use use DeepClone; ) |
use NoClone; |
__debugInfo() |
var_dump() prints all public properties |
use DeepClone;
DeepClone
turns
into
It implements __clone()
by calling parent::__clone()
if it exists, and cloning all objects contained in all properties of the class in which it's used, including objects in arbitrarily nested arrays. It will error if it finds a resource
type, since resource
s are pass-by-reference like objects and therefore should be cloned, but there is no general way to clone a resource
.
Note that you have to use use DeepClone;
at each level in a class hierarchy. It will not clone properties of parent or derived classes.
Why do a deep clone?
When an object is cloned with clone ...
, PHP by default does a shallow clone, meaning a new object is created with the same value for all properties, but sharing the same instance of any objects contained in those properties. This can expose the user of the class to be affected by what information is stored directly and what information is stored indirectly through other objects, breaking abstraction and causing subtle bugs.
Here is an example:
If an innocent refactoring is made to move the value of the $foo
property into another object (B
):
The test()
function will now print 200 instead of 100, because both $a1
and $a2
will share the same instance of B
.
This can be resolved by implementing __clone()
by doing a deep clone:
The developer making the refactoring has to rememeber to keep the __clone()
method up to date to maintain behaviour in case the object is cloned. use DeepClone;
does this for you, so you don't have to remember.
clone_ref(mixed &$x):void
Will clone all objects contained in the specified variable, including those inside nested arrays. It is useful for implementing __clone()
by deep cloning only some properties.
For example:
clone_val(mixed $x):mixed
Will clone all objects contained in the specified value, and return the new value.
use NoClone;
use NoClone;
prevents an object from being cloned. It implements __clone()
by throwing a CloneNotSupportedException
.
use NoDynamicMethods;
The magic methods __call()
and __callStatic()
make adding new methods to a class potentially unsafe, since the new method may unintentionally override a dynamic method handled by __call()
or __callStatic()
.
use NoDynamicMethods;
defines __call()
and __callStatic()
to throw an UndefinedMethodException
, so adding new methods is always safe.
use NoDynamicProperties;
The magic methods __get()
, __set()
, __isset()
and __unset()
make adding new properties to a class potentially unsafe, since the new property may unintentionally override a dynamic property handled by these magic methods.
Even without these magic methods defined, a new property on a class may already be being used as an undeclared public property, for example:
The usage of a undeclared property Foo::$bar
in blah()
has made it unsafe for the author of Foo
to add Foo::$bar
as a new property.
use NoDynamicProperties;
defines __get()
, __set()
, __isset()
and __unset()
to throw an UndefinedPropertyException
, so adding new properties is always safe.
use NoSerialize;
PHP's builtin serialize()
and unserialize()
functions make it potentially unsafe to change a class's name or properties, because a serialized version of the class may exist which needs to continue to work when unserialized.
use NoSerialize;
defines __sleep()
and __wakeup()
to throw a SerializeNotSupportedException
so renaming a class or changing its properties is always safe.
use NoMagic;
use NoMagic;
disallows any magic which makes refactoring difficult. It is equivalent to