/
inconsistencies
138 lines (94 loc) · 4.67 KB
/
inconsistencies
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
137
138
<h2>Inconsistencies between Zend PHP and HipHop VM</h2>
1. Arithmetic, arrays, and foreach loops
(1) Arithmetic
Under Zend PHP, the addition, subtraction, or multiplication of two integers
will produce a floating-point value if the result overflows the integer type.
Under HipHop VM, the addition, subtraction, or multiplication of two integers
will always produce an integer value; if the result overflows the integer type,
the high bits of the result will be discarded ("wrap-around").
(2) Next free integer key for arrays
Arrays contain a hidden field called the "NextFreeElement" field that tracks
what integer key should be used when a new element is appended. Under Zend PHP,
when an array is copied the NextFreeElement field of the new array will be
recomputed based on the keys it currently contains. Under HipHop VM, when an
array is copied the new array's NextFreeElement field is set to the same value
as the original array's NextFreeElement field.
(3) Array internal cursors
Under Zend PHP, if an array's internal cursor points to the position past the
last element and then a copy of the array is made, the copy will have its
internal cursor reset to point at the first element. Under HipHop VM, when a
copy of an array is made, the copy's internal cursor will always point to the
same position that the original array's internal cursor pointed to.
(4) Foreach by value
Under Zend PHP, foreach by value will modify the array's internal cursor under
certain circumstances. Under HipHop VM, foreach by value will never modify the
array's internal cursor.
(5) Foreach by reference
Under Zend PHP, the behavior of a foreach by reference loop can be
unpredictable if during iteration the next element of the array is unset, or if
the array variable is assigned to directly or through a reference, or if
copy-on-write causes the array to be copied. For such cases, HipHop VM's
behavior may differ from Zend PHP.
2. Classes and objects
(1) Exceptions thrown from destructors
Under HipHop VM, PHP exceptions thrown from destructors will be
swallowed while logging an error. Effectively, there is a try/catch enclosing
the body of the __destruct method. These exceptions are catchable under Zend
PHP outside of the __destruct method.
Fatals thrown from destructors will log an error, and prevent further PHP code
from executing as the fatal propagates. This includes other __destruct methods.
(2) __destruct behavior at end of request
Under Zend PHP, if an object is still live at the end of a request, its
__destruct method is invoked. By default, HipHop VM does not do this.
The EnableObjDestructCall runtime option can be used to make HipHop VM invoke
the __destruct method for objects that are live at the end of the request.
(3) Exceptions thrown from __toString()
Zend PHP does not allow exceptions to be thrown from __toString(). HipHop VM
does. Also, Zend PHP doesn't allow __toString() to return anything other than a
string. HipHop VM will just convert return value to string.
(4) __call/__callStatic() handling
This example gives inconsistent results in Zend PHP 5.5:
<?php
class B {
}
class G extends B {
function __call($name, $arguments) { var_dump('G');}
function f4missing($a) {
B::f4missing(5); // __call checking happened at B
}
}
$g = new G();
$g->f4missing(3);
Under HipHop VM, both checking and invocation of __call() happen on class G.
(5) Object internal cursors
Under Zend PHP, objects have an internal cursor (similar to the array internal
cursor) that can be used to iterate over the object's properties. Under HipHop
VM, objects do not have internal cursors, and the next(), prev(), current(),
key(), reset(), end(), and each() builtin functions do not support objects.
3. Misc
(1) Case-insensitive constants
HipHop VM does not support case-insensitive constants, for example:
define('FOO', 123, true);
(2) get_defined_vars() and get_declared_classes()
HipHop VM may return variables/classes in a different order than Zend PHP.
(3) XMLWriter
Under Zend PHP, XMLWriter class and its functions returned different types of
objects,
<?php
function foo(XMLWriter $w) {}
$obj = new XMLWriter();
foo($obj); // <-- this one is actually okay
$obj2 = xmlwriter_open_memory(); // <-- just not this one
var_dump($obj, $obj2);
foo($obj2);
Under HipHop VM, they are the same.
(4) HipHop VM only supports preg_replace /e in limited cases.
Example unsupported case: phpt...bug24403
(5) Under Zend PHP, you can assign to $GLOBALS:
$GLOBALS = 0;
$x = $GLOBALS - 5;
$g = $GLOBALS;
$g['x'] = 3;
Under HipHop VM, this is not allowed or not working at present.
(6) All fatals prevent further PHP code from executing, including __destruct
methods. N.B.: exit() is a fatal.