Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composer overrides PHP configuration and then fails because of missing extensions #5667

Closed
renan opened this issue Sep 12, 2016 · 9 comments
Closed
Labels
Milestone

Comments

@renan
Copy link

renan commented Sep 12, 2016

My composer.json:

{
    "scripts": {
        "test-json": "php -r \"var_dump(function_exists('json_encode'));\""
    }
}

Having PHP with xdebug and json extensions installed, when running this script I get:

$ composer run test-json
> php -r "var_dump(function_exists('json_encode'));"
bool(false)

When Xdebug is enabled composer tries to restart itself and run without any extra .ini files being loaded, which causes json extension to not be present. So when you have scripts that depends on json extension the command fails.
This behavior is caused by XdebugHandler and reproducible on latest master. Probably introduced on #5580

For example using post-update-cmd with Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache, which depends on Monolog, fails with:

[RuntimeException]
PHP's json extension is required to use Monolog's NormalizerFormatter

XdebugHandler re-runs the same command with the -c option (-c <path>|<file> Look for php.ini file in this directory) with the directory /tmp/composer-php-empty/, which is indeed empty.

@renan renan changed the title Overriding PHP configuration and failing because of missing extensions Composer overrides PHP configuration and then fails because of missing extensions Sep 12, 2016
@Seldaek
Copy link
Member

Seldaek commented Sep 12, 2016

@renan could you show us what php -i | grep 'Configuration|\.ini' outputs? It shouldn't disable everything in theory it removes xdebug but reuses all other ini files that were loaded, so it seems it's not picking up whichever of your ini files loads the json extension.

cc @johnstevenson

@Seldaek Seldaek added the Bug label Sep 12, 2016
@Seldaek Seldaek added this to the 1.3 milestone Sep 12, 2016
@renan
Copy link
Author

renan commented Sep 12, 2016

I can see that /tmp/composer-php.ini is correctly created and does contain extension=json, but this is never loaded.

With php -i being run through composer script I get:

Configuration File (php.ini) Path => /etc/php5/cli
Loaded Configuration File => /etc/php5/cli/php.ini
Scan this dir for additional .ini files => /tmp/composer-php-empty
Additional .ini files parsed => (none)

php -i on the server:

Configuration File (php.ini) Path => /etc/php5/cli
Loaded Configuration File => /etc/php5/cli/php.ini
Scan this dir for additional .ini files => /etc/php5/cli/conf.d
Additional .ini files parsed => /etc/php5/cli/conf.d/05-opcache.ini,
/etc/php5/cli/conf.d/10-pdo.ini,
/etc/php5/cli/conf.d/20-apcu.ini,
/etc/php5/cli/conf.d/20-curl.ini,
/etc/php5/cli/conf.d/20-gd.ini,
/etc/php5/cli/conf.d/20-imagick.ini,
/etc/php5/cli/conf.d/20-imap.ini,
/etc/php5/cli/conf.d/20-intl.ini,
/etc/php5/cli/conf.d/20-json.ini,
/etc/php5/cli/conf.d/20-mcrypt.ini,
/etc/php5/cli/conf.d/20-memcache.ini,
/etc/php5/cli/conf.d/20-mysql.ini,
/etc/php5/cli/conf.d/20-mysqli.ini,
/etc/php5/cli/conf.d/20-pdo_mysql.ini,
/etc/php5/cli/conf.d/20-pdo_sqlite.ini,
/etc/php5/cli/conf.d/20-pinba.ini,
/etc/php5/cli/conf.d/20-readline.ini,
/etc/php5/cli/conf.d/20-sqlite3.ini,
/etc/php5/cli/conf.d/20-tidy.ini,
/etc/php5/cli/conf.d/20-xdebug.ini,
/etc/php5/cli/conf.d/xdebug.ini

I think you need to either copy the files to the location or tell php to run with the php.init file that is created.

@renan renan closed this as completed Sep 12, 2016
@renan renan reopened this Sep 12, 2016
@alcohol
Copy link
Member

alcohol commented Sep 12, 2016

The problem is a bit more complicated than what you summarize.

For example, lets assume we call:

composer exec 'php -r "var_dump(function_exists(\"json_encode\"));"'

This gets interpreted by your php binary (cli) with its default php ini and ini dir settings.

Then the xdebughandler "reloads" the process (Composer) by calling php with a custom ini file target, and sets an environment variable which specifies the new ini dir to scan.

After the above has happened, we finally get to actually run the command you passed, e.g.

php -r var_dump(function_exists("json_encode"));

Important: this php process will use your default php ini file, but it still inherits the custom ini dir to scan (due to the env variable set).

@Seldaek
Copy link
Member

Seldaek commented Sep 12, 2016

Indeed this might be the issue, would be better if we could do it all via CLI flags avoiding environment variable changes so that it doesn't propagate to child processes. Alternatively we can also remove those env vars before calling child processes but that's uglier..

@renan
Copy link
Author

renan commented Sep 12, 2016

As discussed with @alcohol running the main process as it is done by XdebugHandler and sub-processes by resetting the PHP_INI_SCAN_DIR env var would work nicely, see: https://gist.github.com/renan/777d575a14d79f02a278800b53b3b4aa

alcohol added a commit to alcohol/composer that referenced this issue Sep 12, 2016
@Seldaek
Copy link
Member

Seldaek commented Sep 12, 2016

Should be fixed in latest snapshot

@Seldaek Seldaek closed this as completed Sep 12, 2016
@johnstevenson
Copy link
Member

Thanks guys. Sorry, I'm away from a computer for a few days and was unable to contribute to this bug fix. I'll reproduce and test when I can.

@Seldaek
Copy link
Member

Seldaek commented Sep 12, 2016

Looks like it's fixed so no worries :)

@renan
Copy link
Author

renan commented Sep 12, 2016

I can no longer reproduce the issue using latest snapshot. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants