Symfony Polyfill Uuid inoperative under Opcache Preloading
SebastienTainon opened this issue · comments
Symfony version(s) affected: 4.4
Description
At first I was simply trying to understand why my Sentry errors weren't sent in my prod environment like there were sent on my dev environment. I realized Sentry was returning "400 Bad Request" because the eventId property was not send. This eventId is an UUID that is created using uuid_create(UUID_TYPE_RANDOM)
in this file: https://github.com/getsentry/sentry-php/blob/master/src/Event.php
They've recently replaced ramsey/uuid
with "uuid_create from the PECL extension or symfony/polyfill-uuid": getsentry/sentry-php@bfb2a40
Ok, fair enough. But that piece of code returned nothing, because UUID_TYPE_RANDOM
was not defined, though it should be by polyfill just here: https://github.com/symfony/polyfill-uuid/blob/master/bootstrap.php
After some more hours of investigation, I realized the reason why that didn't work on my prod environment was because I had PHP 7.4 Opcache Preloading enabled. If I disable the preloading, everything works fine (the polyfill, the UUID generation, the Sentry event...).
What I suspect is that when Opcache preloading is on, the uuid_create
function gets preloaded into Opcache, and the if (!function_exists('uuid_create')) {
is then false, so the polyfill is not executed, thus UUID_TYPE_RANDOM
is not defined and consequently the uuid_create(UUID_TYPE_RANDOM)
does not work, (and the eventId is not sent, and Sentry sends 400 Bad Request... long story...).
How to reproduce
composer require symfony/polyfill-uuid
- Enable opcache preloading with php7.4
var_dump(uuid_create(UUID_TYPE_RANDOM))
Possible Solution
I guess we shouldn't do the check on the existence of only the uuid_create
but rather on the existence of each individual constant and function. I'm available to do a PR on this, let me know if necessary.
Temporary fix
If anyone else has this issue, I simply added the following code to my config/bootstrap.php
file to define the missing constant until symfony/polyfill-uuid
is fixed:
if (!defined('UUID_TYPE_RANDOM')) {
define('UUID_TYPE_RANDOM', 4);
}
Thanks for the report.
I'd suggest splitting all constant definition in a separate file - actually in two separate files: one using define()
for PHP5, another using const
for PHP7+.
We should do so for all components.
Up for a PR?
Well, is it worth maintaining 2 files defining the same constants ? Or would const
be preloadable ?
would const be preloadable
yes! that's why I suggested this strategy.
/cc @nikic WDYT about this?
would
const
be preloadable
according to @azjezz that's not the case, so: no need for a separate file - we should group calls to define()
under separate main defined()
checks.
PHP bug report: https://bugs.php.net/bug.php?id=79360
Check #239
Hello @nicolas-grekas, thanks for the quick response!
I've tried #239 and I can confirm that it solves my problem 👍