summaryrefslogtreecommitdiff
path: root/Zend/RFCs/001.txt
blob: bf1d847b97a5a4cfec3612e82ab1878801748fc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Revamped object model using object handles
===========================================

Background
----------

In the Zend Engine 1.0 (and its predecessor the PHP 3 scripting
engine) the object model's design is that instantiated objects are
language values. This means that when programmers are performing
operations, such variable assignment and passing parameters to
functions, objects are handled very similarly to the way other
primitive types are handled such as integers and strings.
Semantically this means that the whole object is being copied. The
approach Java takes is different where one refers to objects by handle
and not by value (one can think of a handle as an objects' ID).

Need
----

Unfortunately, the approach taken up to now has severely limited the
Zend Engine's object oriented model, both feature and simplicity
wise. One of the main problems with the former approach is that object
instantiation and duplication is very hard to control, a problem which
can not only lead to inefficient development but also often to strange
run-time behavior. Changing the object model to a handle oriented
model will allow the addressing of many needs such as destructors,
de-referencing method return values, tight control of object
duplication and more.

Overview
--------

The proposed object model is very much influenced by the Java
model. In general, when you create a new object you will be getting a
handle to the object instead of the object itself. When this handle is
sent to functions, assigned and copied it is only the handle which is
copied/sent/assigned. The object itself is never copied nor
duplicated. This results in all handles of this object to always point
at the same object making it a very consistent solution and saving
unnecessary duplication and confusing behavior.

Functionality
-------------

After this change the basic use of objects will be almost identical to
previous versions of the scripting engine.  However, you won't bump
into awkward and confusing copying & destructing of objects.  In order
to create and use a new object instance you will do the following:
$object = new MyClass(); $object->method();

The previous code will assign $object the handle of a new instance of
the class MyClass and call one of its methods.

 
Consider the following code:

1	class MyClass
2	{
3		function setMember($value)
4		{
5			$this->member = $value;
6		}
7	
8		function getMember()
9		{
10			return $this->member;
11		}
12	}
13	
14	function foo($obj)
15	{
16		$obj->setMember("foo");
17	}
18	
19	$object = new MyClass();
20	$object->setMember("bar");
21	foo($object);
22	print $object->getMember();

Without the new Java-like handles, at line 20 the objects' data member
member is set to the string value of "bar".  Because of the internal
representation of objects in the Zend Engine 1.0, the object is marked
as a reference, and when it is sent by value to the function foo, it
is duplicated (!).  Therefore, the call to foo() on line 21 will
result in the $obj->setMember("foo") call being called on a duplicate
of $object. Line 22 will then result in "bar" being printed.

This is how the scripting engine has worked until today. Most
developers are probably unaware of the fact that they aren't always
talking to the same object but often duplicates; others may have
realized this can usually be solved by always passing objects by
reference (unless a replica is actually desired, which is uncommon).

The new object model will allow for a much more intuitive
implementation of the code.  On line 21, the object's handle (ID) is
passed to foo() by value. Inside foo(), the object is fetched
according to this handle and, therefore, the setMember() method is
called on the originally instantiated object and not a copy.  Line 22
will therefore result in "foo" being printed.  This approach gives
developers tighter control of when objects are created and duplicated.
An additional not-as-important benefit is that the object handle will
be passed to foo() by value, which most probably will also save
unnecessary duplication of the value containing the ID itself and thus
additionally improving run-time performance.

This was just a simple description of why the new object model solves
awkward behavior and makes object handling much easier, intuitive and
efficient.  The importance of this change goes far beyond what is
mentioned in this section as you will see in further sections which
describe new features with a majority of them being based on this
change.

Compatibility Notes
--------------------

Many PHP programmers aren't even aware of the copying quirks of the
current object model and, therefore, there is a relatively good chance
that the amount of PHP applications that will work out of the box or
after a very small amount of modifications would be high.

To simplify migration, version 2.0 will support an optional
'auto-clone' feature, which will perform a cloning of the object
whenever it would have been copied in version 1.0.  Optionally, it
will also be possible to request that the engine will emit an E_NOTICE
message whenever such an automatic clone occurs, in order to allow
developers to gradually migrate to the version 2.0-style behavior
(without automatic clones).

Dependencies
------------

The new object model is not dependent on other features.  Many of the
other Zend Engine 2.0 features, such as the $foo->bar()->barbara()
syntax, destructors and others completely rely on this new object
model.