Background
Because of the underlying implementation, returning objects from functions in the Zend
Engine 1.0 is very cumbersome. It is necessary to use special notation, $foo = &bar(), if
one wishes to have bar() return an object by reference. Additionally, it’s also not
possible to return an object by reference, by assigning it to a passed-by-reference
argument, due to the copying semantics that characterizes the existing object model.
Need
Object oriented design-patterns, such as Factory (creating objects by a centralized
function) and others, are becoming more and more popular. Implementing these patterns
requires a clean and consistent OO API, and the ability to easily interlink objects to one
another. Easy, straightforward syntax for returning object references from functions is
crucial to the implementation of such design patterns.
Overview
The simplified and improved behavior is a side effect of the new handle-like object
model. It will be possible to pass-on objects after creating them without any special
considerations by using the return statement or by assigning the new object to a function
parameter that was passed by reference. Functionality
Returning objects will be done in exactly the same way as any other primitive types (such
as integers or strings) are returned. The returned object will always refer to the specific
object the user has instantiated, without any implicit copies made behind the scenes.
Consider the following code:
1 function FactoryMethod($class_type)
2{
3 switch ($class_type) {
4 case “foo”:
5 $obj = new MyFoo();
6 break;
7 case “bar”:
8 $obj = new MyBar();
9 break;
10 }
11
12 return $obj;
13 }
14
15 $object = FactoryMethod(“foo”);
With the new object model this code will return the object itself; It will create an instance
of class MyFoo and will return that exact instance to the executing Zend Engine without
any copying of objects. This is different from the behavior under the Zend Engine 1.0,
which would cause a replica of the object to be returned, instead of the object itself.
A more confusing and important aspect of this is if MyFoo had in some way created an
additional reference to itself. With the new model the object will still be returned
correctly. With the previous object model, when returning $obj it might have only been
partially duplicated and any references to it ended up not referencing the returned object, but some ‘ghost’ object instead. This confusing behavior was the cause of many very-
difficult-to-debug bugs.
The current solution for this today is defining the function as function
&FactoryMethod(class_$type) and changing line 15 to $object =&
FactoryMethod(“foo”);. However, this is a cumbersome approach, and the syntax is
very prone to errors.
Taking the same example, if the returned object weren’t returned via the return value but
via a function argument you would bump into very similar problems. Consider the
following function prototype for the previous function:
function FactoryMethod($object_type, &$resulting_object)
When trying to assign the created object to $resulting_object there might be strange
behavior in the same cases as mentioned above. With the new model you can happily
assign the object handle to $resulting_object and the instantiated object will be able to be
referenced on the outside.
Compatibility notes
This aspect of the object model change will probably not have any compatibility issues
unless the developer was relying on some weird object copying that was happening
during execution. However, this change “might” make the function &func() and the =&
syntax not very useful and in the least their removal should be considered. If they are
removed it won’t be a problem to create a small converter that will find them and warn
about them (and possible replace the old syntax).
Dependencies
This feature is dependent upon the new object model of the Zend Engine 2.0.