Phpunit: Running phpunit-7.4.0.phar with phpdbg throws NOTICE

Created on 17 Oct 2018  路  19Comments  路  Source: sebastianbergmann/phpunit

| Q | A
| --------------------| ---------------
| PHPUnit version | 7.4.0
| PHP version | phpdbg 7.2.10
| Installation Method | PHAR

phpunit installed via phive.
When calling phpdbg -qrr /usr/local/bin/phpunit the folling NOTICE is shown:

[PHP Notice:  Undefined index: _SERVER in /usr/local/bin/phpunit on line 18]

Guess that $_SERVER is simply not set in phpdbg?

This line raises the notice, I guess in build/binary-phar-autoload.php.in:

if (__FILE__ === realpath($GLOBALS['_SERVER']['SCRIPT_NAME'])) {

Most helpful comment

Sorry, but this does not look like a PHPUnit problem to me.

All 19 comments

I cannot reproduce this.

$ cat test.php 
<?php
var_dump($GLOBALS['_SERVER']['SCRIPT_NAME']);
$ phpdbg -qrr test.php
string(17) "/home/sb/test.php"

Maybe you have an auto-prepend script configured that unset()s $_SERVER or something?

No auto-prepend script. phpdbg runs in a Docker Container with PHP 7.2 coming from Alpine 3.8.
Weird. Will investigate further and report.

Ok, even weirder, this does look like phpdbg specific behavior. $GLOBALS['_SERVER'] is only set after $_SERVER is accessed:

# cat test1.php
<?php
var_dump($GLOBALS);
var_dump($GLOBALS['_SERVER']);
# phpdbg -qrr test1.php
array(7) {...}
[PHP Notice:  Undefined index: _SERVER in /test2.php on line 2]
NULL
# cat test2.php
<?php
var_dump($_SERVER);
var_dump($GLOBALS);
var_dump($GLOBALS['_SERVER']);
# phpdbg -qrr test2.php
array(15) {...}
array(8) {...}
array(15) {...}

Sorry, but this does not look like a PHPUnit problem to me.

I just ran into this myself in exactly the same scenario. Found this:

https://odd.blog/2015/02/12/php-notice-undefined-variable-_server-in/

Setting "auto_globals_jit = Off" does seem to fix it.

You can run phpunit with phpdbg setting directly auto_globals_jit variable like this

phpdbg -dauto_globals_jit=Off -qrr /usr/local/bin/phpunit

This is the same problem as #3514. It was reproduced in the Docker-based reproducer repo I made.

PHPUnit expects the key to always be there, but that's not compatible with auto_globals_jit=On, it's 100% a PHPUnit issue.

It's not only a docker issue. Here's a reproducer that also fails on OS X:

wget -O phpunit https://phar.phpunit.de/phpunit-8.phar
phpdbg -qrr phpunit --version

[PHP Notice: Undefined index: _SERVER in /Users/kuba/phpunit on line 18]

@sebastianbergmann do you still consider it NOT a phpunit problem?

I still cannot reproduce this:

$ wget https://phar.phpunit.de/phpunit-8.phar
$ php -v                                                      
PHP 7.3.2 (cli) (built: Feb  5 2019 13:10:03) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.7.0rc1, Copyright (c) 2002-2019, by Derick Rethans
$ php -i | grep auto_globals_jit
auto_globals_jit => On => On



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ php phpunit-8.phar --version
PHPUnit 8.0.1 by Sebastian Bergmann and contributors.



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ php -d auto_globals_jit=Off phpunit-8.phar --version
PHPUnit 8.0.1 by Sebastian Bergmann and contributors.



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ phpdbg --version
phpdbg 0.5.0 (built: Feb  5 2019 13:10:03)
PHP 7.3.2, Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.7.0rc1, Copyright (c) 2002-2019, by Derick Rethans



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ phpdbg -qrr phpunit-8.phar --version
PHPUnit 8.0.1 by Sebastian Bergmann and contributors.



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ phpdbg -d auto_globals_jit=Off -qrr phpunit-8.phar --version
PHPUnit 8.0.1 by Sebastian Bergmann and contributors.

@sebastianbergmann what about phpdbg -d auto_globals_jit=On -qrr phpunit-8.phar --version ? (on an off chance you've got it disabled in php.ini). nvm, just noticed you have it enabled.

It might be PHP 7.2 issue only :(

Maybe xDebug messes with it, we don't have it enabled in the Docker reproducer?

Without Xdebug I can reproduce it:

$ phpdbg --version
phpdbg 0.5.0 (built: Feb  5 2019 13:10:03)
PHP 7.3.2, Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
$ phpdbg -d auto_globals_jit=On -qrr phpunit-8.phar --version
[PHP Notice:  Undefined index: _SERVER in /home/sb/phpunit-8.phar on line 18]



md5-d9b3ea1f0bfc5ddde080a6d7330b1ebf



$ phpdbg -d auto_globals_jit=Off -qrr phpunit-8.phar --version
PHPUnit 8.0.1 by Sebastian Bergmann and contributors.

It might be PHP 7.2 issue only :(

Nope, just tried 7.2 and 7.3, both work the same.

Without Xdebug I can reproduce it

o/

According to @krakjoe and @nikic, there might be an interoperability issue between PHPDBG and Xdebug here that hides a problem in PHPUnit's code. That problem is that one cannot rely on $_SERVER being defined.

CC @derickr on the off chance that is relevant to Xdebug development.

To clarify, you can rely on _SERVER, but GLOBALS['_SERVER'] works like a variable variable, and will not trigger just-in-time population of GLOBALS['_SERVER'], while accessing _SERVER directly is reliable ...

GLOBALS is broken and auto_globals_jit just cannot work with it as everyone expects (me included), and we can't remove GLOBALS because legacy ...

I'm not precisely sure of the reason that xdebug should make a difference, but whatever it doesn't make much sense to load a debugger inside a debugger, the two cannot be expected to inter-operate properly ...

I'm not precisely sure of the reason that xdebug should make a difference, but whatever it doesn't make much sense to load a debugger inside a debugger, the two cannot be expected to inter-operate properly .

The thing is the issue can only be observed if xdebug is not loaded.

So I looked at Xdebug ... The reason it doesn't happen when Xdebug is loaded is because auto_globals_jit behaviour is not preserved, upon startup, Xdebug does this:

static void xdebug_init_auto_globals(TSRMLS_D)
{
    zend_is_auto_global_str((char*) ZEND_STRL("_ENV") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_GET") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_POST") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_COOKIE") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_REQUEST") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_FILES") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_SERVER") TSRMLS_CC);
    zend_is_auto_global_str((char*) ZEND_STRL("_SESSION") TSRMLS_CC);
}

Which is forcing all super globals to be populated before you accessed them, and so you do not see this behaviour ...

Yes, as I need to be able to reach them to read the headers to find out whether Xdebug needs to start a debug session or not. And then the others are needed to show the information from the super globals through debugging.

Was this page helpful?
0 / 5 - 0 ratings