Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

206 lines (138 sloc) 6.431 kb
<h2>Inconsistencies between PHP and HipHop</h2>
1. Arithmetic, arrays, and foreach loops
(1) Arithmetic
In PHP, the addition, subtraction, or multiplication of two integers will
produce a floating-point value if the result overflows the integer type. In
Hiphop, 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. In PHP, when an
array is copied the NextFreeElement field of the new array is recomputed based
on the keys it currently contains. In HipHop, 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
In 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. In HipHop, 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
In PHP, foreach by value will modify the array's internal cursor under certain
circumstances. In HipHop, foreach by value will never modify the array's
internal cursor.
(5) Foreach by reference
In 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's behavior may differ
from PHP.
2. Classes and objects
(1) Exceptions thrown from destructors
In HipHop, exceptions and fatals 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 in PHP outside of the
__destruct method.
(2) __destruct behavior at end of request
In PHP, if an object is still live at the end of a request, its __destruct
method is invoked. The HipHop static compiler (hphpc) does not do this.
By default, HipHop VM (hhvm) matches hphpc's behavior for live objects at the
end of the request. The EnableObjDestructCall runtime option can be used to
make hhvm invoke the __destruct method for objects that are live at the end of
the request.
(3) Exceptions thrown from __toString()
PHP doesn't allow them. HipHop does. Also, PHP doesn't allow __toString() to
return anything other than a string. HipHop will just convert return value to
(4) __call/__callStatic() handling
These 2 examples give inconsistent results in PHP 5.3:
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();
class B {
function __call($name, $arguments) { var_dump('B');}
class G extends B {
function __call($name, $arguments) { var_dump('G');}
function f4missing($a) {
B::f4missing(5); // G::__call() was called actually!
$g = new G();
In HipHop, both checking and invocation of __call() happen on class G.
(5) Object internal cursors
In PHP, objects have an internal cursor (similar to the array internal cursor)
that can be used to iterate over the object's properties. In HipHop, objects do
not have internal cursors, and the next(), prev(), current(), key(), reset(),
end(), and each() builtin functions do not support objects.
3. Eval Issues
(1) eval
hphpc only supports eval in limited circumstances.
Example unsupported case: phpt...bug21960
hhvm fully supports eval.
(2) create_function
hphpc only supports create_function with literal arguments.
Example unsupported case: phpt...bug22690
hhvm fully supports create_function.
(3) preg_replace /e
hphpc and hhvm only support preg_replace /e in limited cases.
Example unsupported case: phpt...bug24403
4. $GLOBALS is not an ordinary variable:
In PHP, you can assign to $GLOBALS:
$x = $GLOBALS - 5;
$g = $GLOBALS;
$g['x'] = 3;
In HipHop, this is not allowed or not working.
5. Constants
(1) Dynamically declared constants
hphpc does not support dynamically declared constants, for example:
define($name, $value);
hhvm fully supports dynamically declared constants.
(2) Case-insensitive constants
hphpc and hhvm do not support case-insensitive constants, for example:
define('FOO', 123, true);
6. Misc
(1) function_exists() and class_exists()
Under hphpc, function_exists($funcname) and class_exists($clsname) may give
different results than in PHP. This is because hphpc has all uniquely-named
functions and classes declared by default, unless it is marked as "volatile",
either by a configuration file, or automatically by the compiler recognizing
string literal being used with function_exists or class_exists, for example:
hhvm's behavior for function_exists() and class_exists() matches that of PHP.
(2) get_defined_vars() and get_declared_classes()
hphpc and hhvm may return variables/classes in a different order than PHP.
(3) Uninitialized variables
Under hphpc, if an uninitialized variable is being used before it's assigned
with a value, no warning will be raised. Furthermore, the value of the
uninitialized variable may be 0 instead of null if hphpc's static analysis
inferred the variable to be an integer.
hhvm raises warnings when uninitialized variables are read, and the value read
from an uninitialized variable will always be null.
(4) XMLWriter
In PHP, XMLWriter class and its functions returned different types of objects,
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);
In HipHop, they are the same.
(5) hphpc has support for PHP namespaces. hhvm currently does not have
support for PHP namespaces.
(6) ReflectionProperty::setAccessible() and ReflectionMethod::setAccessible()
are not currently supported.
Jump to Line
Something went wrong with that request. Please try again.