Page MenuHomePhabricator

PHP / HPHP Compatibility Issues
Closed, ResolvedPublic

Description

HPHP has a bunch of behavioral changes from mainline PHP, which we're currently addressing one at a time by adding conditionals. For example, see:

  • {D2362}
  • {D2365}
  • {D2524}
  • Various idx() warnings and behavioral differences.

These patches are pretty nasty and I want to explore alternatives rather than hacking around them. Here are some alternatives:

  • Fix HPHP, Not Phabricator: I'd be willing to help with this if hacking on HPHP was approximately as easy as hacking on PHP. I believe it's much much harder, though, and seems to be completely unsupported now (no commits in 6 months)?
  • Deploy on Zend PHP at Facebook: Not sure how viable this is. Won't fix arc issues, only Phabricator issues (although this is most of them). With the FPM patch, switching to vanilla PHP should improve performance significantly.
  • Fork Phabricator: Not thrilled about this, but I'd rather have this gunk on Facebook's side than in the upstream, given that it is the one imposing the costs; there are no other installs running HPHP and I do not anticipate there ever being any since there are no reasons to use HPHP over a standard stack when running Phabricator, unless you're Facebook and have a bunch of inflexibility and lock-in.

Also, what's going to happen when HPHP-VM rolls out? Is this going to be like 6-8 months of three-way conditionals, where one branch handles HPHP/i, one handles HPHP-VM, and one handles normal PHP?

Revisions and Commits

Event Timeline

epriestley triaged this task as Wishlist priority.May 21 2012, 9:40 PM
epriestley added projects: Phabricator, Facebook.
epriestley added subscribers: epriestley, btrahan, vrana and 5 others.

The various idx() issues have been resolved (in hhvm) by allowing us to override the builtin idx. (hphpc still raises idx warnings, but it appears to behave correctly, and I just ignore idx warnings in DarkConsole that come from the compiled phabricator.)

I'm a fan of deploying Zend PHP at Facebook. @Girish hesitates to believe that nginx+patched PHP-FPM (D2030+D2033) can be faster than HPHP so we just need to measure it.

I'm an anti-fan of forking Phabricator.

HPHP is still under intensive development, it is just not open-sourced as well as Phabricator. HPHPi is going to die pretty soon in favor of HHVM.

Can we fix the other issues in hhvm by making error_log() work and providing an option or something for throw in destructors to actually throw? I think that's it so far, we're just digging a deeper and nastier hole here with every patch right now and I'd rather be either digging out of the hole toward a better, brighter and more compatible future or at least getting Phabricator out of the hole if Facebook wants to keep digging.

It's not that I don't believe, it's not even a matter of speed (unless it's like 2x faster or something). I'm hesitating because we'll need to support a whole different install.

HHVM is now the default on dev boxes.

@vrana - Have we talked to the HPHP team about fixing these differences?

I think that @edward talked with them and they gave it a low priority.

I've spoken with HPHP about both (a) making throws in __destruct catchable and (b) making ini_set("error_log", $path_to_error_log_file) work during runtime. Both of them are "deep changes", and I believe them, which is why it seemed better to play the "support all known implementations of PHP" game instead.

I'd be happier with Zend only.

$ rm -f /tmp/log; php <<<'<? ini_set("error_log", "/tmp/log");  error_log("rainbows");'
rainbows
$ cat /tmp/log
cat: /tmp/log: No such file or directory

...was my test.

haha well I would agree that doesn't work at all

Code wins arguments

@vrana - So, what's the plan for arc issues if we move to zend?

@Girish use Zend everywhere. I'm assuming you can install Zend PHP in /opt/weird-place and not have it interfere with everything else. Arc would need a wrapper to find the right interpreter mind you.

@edward, arg. That sounds like a bigger nightmare :(

From D2609, is_subclass_of() doesn't trigger autoload in HPHP/HHVM. This isn't documented in the open source "inconsistencies" document.

Just saw @vrana's comments on an internal task as well, about how arc "takes 0.056s with Zend PHP" and "takes 0.588s with HHVM but the total time is even higher", and wanted to add that to the order-of-battle here :)

Minor note on this, but @edward found a good fix for the log issue in D2626.

I've reported the is_subclass_of() inconsistency and it's now fixed in HPHPc and HHVM.

I also personally killed the "passing a null index to idx()" warning.

vrana edited this Maniphest Task.

mysql_fetch_assoc() on my FB devserver returns a mixture of types, as opposed to an array where everything is a string. dateCreated, id come back as ints, for example.

I've been using === all throughout my code, and today I moved to Ubuntu and found bugs. Is this another HPHP vs PHP difference? I might've just noobed up my PHP install in Ubuntu.

My understanding is:

  • In the old APE days, someone (I think Brian Shire?) modified the PHP MySQL extension to return typed results. So mysql_* functions have returned typed data for a long time at Facebook (predating HPHP) but only at Facebook.
  • HPHP would have needed to retain this feature for Facebook's codebase, but there's no mention of it in the "inconsistencies" document and it would have been a fairly obvious departure, so maybe there's some config for it? I can't find anything in the documentation or implementation, though.
  • AFAIK, you should not expect typed data out of these functions outside of Facebook.

Also, from the implementation, it looks like mysql_result() in HPHP always returns string, while other functions return typed data. My read of any of this might be wrong though, I haven't verified it experimentally.

Here's an internet archive page of the now-defunct mirror.facebook.net showing Shire's php_mysql_t.patch dated Nov-2007, although the actual content is not archived and I couldn't find it via Google:

http://ia201119.eu.archive.org/ukparliament/20090701093247/mirror.facebook.net/facebook/patches/

mysql_result() really returns strings under HPHP.

Zend is stricter about function signatures in overridden methods. HPHP supports embracing and extending standard interfaces, but Zend will complain if you override giveFeedback($person) with giveFeedback($sheep1, $sheep2).

This only affects some FB-only code.

json_decode() on something string-like returns null in Zend, but HipHop returns the string.

Examples of json_decode() inputs and outputs:

InputHPHPZend
!!1!!!!1!!null
"a\"b"c"a\"b"cnull
[anullnull

Ant there's no json_last_error() function even if HPHP claims it is PHP 5.3.3.

If the __FUNCTION__ token is used for indirection, it is interpreted literally as trying to call __FUNCTION__():

Example:

class Wrapper {
  public function foo() {
    $this->thing->{__FUNCTION__}();
  }
}
// ...Call to undefined method Thing::__FUNCTION__ from context Wrapper

This is used in https://github.com/jamesiarmes/php-ews.

What an ugly construct! Can you send them pull request changing it too:

call_user_func(array($this->thing, __FUNCTION__));

?

From D4208, HPHP implements the $previous property of Exception with protected visibility, while PHP implements it with private visibility (see http://php.net/manual/en/language.exceptions.extending.php).

It currently looks like T2479 shows another disparity, resulting in a fatal in HipHop.

D2471 discusses an issue with curl_multi_select(). Prior to PHP 5.4.8, it waited for the timeout if the underlying call to curl_multi_fdset() returned -1 (essentially, ignored the error). This was fixed here:

https://github.com/php/php-src/commit/2e8ab65270e7d1ebe1ef0dfe13836c29d72c7010

This was not documented in the changelog, but modern PHP returns -1 immediately. HPHP retains the 5.4.7 behavior.

I'm sure we already know about this one already:

<?php

class Frog {
  public function meow() {
    return array('cheese' => 'President Lincoln!');
  }
}

$doorway = new Frog();
$emotion = $doorway->meow()['cheese'];
printf("There is only one way out of this %s!\n", $emotion);

// Zend:   PHP Parse error:  syntax error, unexpected '[' in /home/edward/test.php on line 10
// HipHop: "There is only one way out of this President Lincoln!!"

Yeah, that's part of the reason idx() exists. The syntax is legal in PHP after PHP 5.4 (I'm running some chimera version of 5.5 locally):

$ cat test.php 
<?php

$x = f()[0];
$ php -l test.php 
No syntax errors detected in test.php
$ arc lint test.php
>>> Lint for test.php:


   Error  (XHP35) Use Of PHP 5.4 Features
    The f()[...] syntax was not introduced until PHP 5.4, but this codebase
    targets an earlier version of PHP. You can rewrite this expression using
    idx().

               1 <?php
               2 
    >>>        3 $x = f()[0];
                          ^
$

I am informed this is valid in HipHop as part of the XHP extension. The lint warning didn't fire for me though, maybe because of the arrow in ->f()[0]?

Ah, good call. Diff attached, thanks!

@vrana and I ran into this one in {D5032}:

echo PHP_INT_MAX + 1;

On Zend, this prints "9.2233720368548E+18". On HPHP, it prints "-9223372036854775808".

epriestley added a subscriber: Unknown Object (MLST).Sep 3 2013, 11:14 PM

Of general interest to Facebook, nothing specifically actionable/planned here.

epriestley changed the visibility from "All Users" to "Public (No Login Required)".Nov 7 2013, 11:15 AM
epriestley claimed this task.

Some of this has been fixed, and Facebook is now much less involved with the upstream than it once was. We have no other HHVM installs and don't officially support HHVM.