ReflectionClass::newInstanceWithoutConstructor

ReflectionClass::newInstanceWithoutConstructor — Creates a new class instance without invoking the constructor

Description

publicobjectReflectionClass::newInstanceWithoutConstructor
( void
)

Creates a new instance of the class without invoking the constructor.

Parameters

Return Values

Changelog

Version

Description

5.6.0

All internal classes can now be instantiated except for those declared
final.

Errors/Exceptions

A ReflectionException if the class is an internal
class that cannot be instantiated without invoking the constructor. In PHP
5.6.0 onwards, this exception is limited only to internal classes that are
final.

User Contributed Notes 5 notes

If this method is not available in your version of PHP you can use a trick to create an instance without calling the constructor.Use reflection to get the properties and default values of the class, and create a fake "serialized" string.

It should be made clear that from an OOP theory perspective the use of this method is very bad practice in the same manner as goto, eval and singletons. If you find a need to use it in production code you're almost certainly doing something wrong somewhere. It may occasionally be useful for debugging, but even then hints at poor initial code.

The problem? It breaks encapsulation. An object can exist in the application but may not be able to fulfill its responsibility because it's missing dependencies. The use of this method makes it possible for an incomplete object to exist in the system; the object can exist in a state that its author never intended. This is bad because it will cause unexpected things to happen! A fundamental principle in OOP is that objects are in complete control of their state, the use of this method prevents that guarantee.

n.b. The annotation based "dependency injection" listed below is not a solution or valid use-case for this either because it breaks encapsulation (Among other things!) and the class being constructed needs to know of the container by providing annotations.

sorry for replying to such an old comment, but there's something i wanted to point out.

@ tom at r dot je:While I agree with what you said in general, there *are* cases where it's not true, and since PHP doesn't allow for multiple constructors there's no other good way around it.

> The problem? It breaks encapsulation. > An object can exist in the application but may not be able to fulfill its > responsibility because it's missing dependencies. > The use of this method makes it possible for an incomplete object > to exist in the system; > the object can exist in a state that its author never intended.

If you're using this method from some factory method, to manually init the object in other way that the constructor that, this point is no longer valid.

Consider the example, where you use constructor to set-up the object after getting it from database (e.g. you need to pull some array from other table, basing on some id parameter). But you want to also be able to create object manually (for inserting to the database, for example).The best thing to do would be to have two different constructors, but since it is not possible in php you need some other way to create the object.

example:

<?php// this usually would be a static cache in some class, or array returned by method getMeta($id), etc.$meta = array(1337 => array('key1' => 'value1', 'key2' => 'value2'));

Of course, you can instead make empty constructor, and create some init() method, but then you have to remember to call init() everywhere.You can also create some other way of adding the item to database, but then you'd have to classes to handle the same data - one for retrieving and other for storing.

If you instead use some factory class (or just a factory method, like in the simplified example above) having a way to create totally empty object is useful. With full factory approach you would first use some TestFactory->prepare() method, then you'd call methods to set what you need, and the factory would set all uninitialized variables to some default values upon calling TestFactory->get() to retrieve prepared object.