xdebug-handler
xdebug-handler copied to clipboard
PHP Warning: proc_open(): Exec failed: No such file or directory in phar
php 8.1.23 + Xdebug 3 Debian GNU/Linux 11 (bullseye) nginx 1.18 + php-fpm Laravel 10.33.0 Composer version 2.7.4
I get this error
PHP Warning: proc_open(): Exec failed: No such file or directory in phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php on line 300
PHP Stack trace:
PHP 1. {main}() /usr/local/bin/composer_php81:0
PHP 2. require() /usr/local/bin/composer_php81:29
PHP 3. Composer\XdebugHandler\XdebugHandler->check() phar:///usr/local/bin/composer_php81/bin/composer:29
PHP 4. Composer\XdebugHandler\XdebugHandler->restart($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/NylWn5', 4 => '/usr/local/bin/composer', 5 => 'install', 6 => '--dry-run']) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:149
PHP 5. Composer\XdebugHandler\XdebugHandler->doRestart($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/NylWn5', 4 => '/usr/local/bin/composer', 5 => 'install', 6 => '--dry-run']) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:274
PHP 6. proc_open($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/NylWn5', 4 => '/usr/local/bin/composer', 5 => 'install', 6 => '--dry-run'], $descriptor_spec = [], $pipes = NULL) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:300
Return code: 127
I try run this script from browser. (over nginx+php-fpm)
$descriptors = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'] // stderr
];
$process = proc_open('composer install --dry-run', $descriptors, $pipes);
if (is_resource($process)) {
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$returnCode = proc_close($process);
dump("Output: $output");
dump("Errors: $errors");
dump("Return code: $returnCode");
}
Fixed the problem by explicitly specifying the paths to php and composer
$process = proc_open('/usr/bin/php8.1 /usr/local/bin/composer install --dry-run', $descriptors, $pipes);
Thanks. We obviously need to check that PHP_BINARY isn't an empty string.
I'm curious to see what happens if you run:
$process = proc_open(['composer', 'install', '--dry-run'], $descriptors, $pipes);
Thanks. We obviously need to check that
PHP_BINARYisn't an empty string.I'm curious to see what happens if you run:
$process = proc_open(['composer', 'install', '--dry-run'], $descriptors, $pipes);
the same error
Errors: PHP Warning: proc_open(): Exec failed: No such file or directory in phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php on line 300 ◀
PHP Stack trace:
PHP 1. {main}() /usr/local/bin/composer_php81:0
PHP 2. require() /usr/local/bin/composer_php81:29
PHP 3. Composer\XdebugHandler\XdebugHandler->check() phar:///usr/local/bin/composer_php81/bin/composer:29
PHP 4. Composer\XdebugHandler\XdebugHandler->restart($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/Gflhtd', 4 => '/usr/bin/composer', 5 => 'install', 6 => '--dry-run']) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:149 ◀
PHP 5. Composer\XdebugHandler\XdebugHandler->doRestart($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/Gflhtd', 4 => '/usr/bin/composer', 5 => 'install', 6 => '--dry-run']) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:274 ◀
PHP 6. proc_open($command = [0 => '', 1 => '-n', 2 => '-c', 3 => '/tmp/Gflhtd', 4 => '/usr/bin/composer', 5 => 'install', 6 => '--dry-run'], $descriptor_spec = [], $pipes = NULL) phar:///usr/local/bin/composer_php81/vendor/composer/xdebug-handler/src/XdebugHandler.php:300
the same error if
$process = proc_open(['php', '/usr/bin/composer', 'install', '--dry-run'], $descriptors, $pipes);
Many thanks for the extra information. This is now fixed in 925e444
I will check on next composer release)
You can try now with composer self-update --snapshot, I updated to the latest xdebug-handler.
You can try now with
composer self-update --snapshot, I updated to the latest xdebug-handler.
I see. Xdebug still working and Composer dont do restart. It's fixed trouble, but maybe try fix search PHP_BINARY?
Which SAPI are you using? Because it seems from the php sources that this may be the reason it's empty if the SAPI does not support that feature https://github.com/php/php-src/blob/8276560e65830abe4bfc9e964bebcb31f75eff5f/main/main.c#L368
dump(PHP_BINARY);
/usr/sbin/php-fpm8.1
it is not standart php file: /usr/bin/php8.1 but all exists
root@dev# ls /usr/sbin/php-fpm8.1
-rwxr-xr-x 1 root root 5504136 Oct 6 2023 /usr/sbin/php-fpm8.1
root@dev# ls /usr/bin/php8.1
-rwxr-xr-x 1 root root 5530984 Oct 6 2023 /usr/bin/php8.1
maybe composer get wrong PHP_BINARY after started from FPM
maybe composer get wrong PHP_BINARY after started from FPM
Just to be clear, you are creating a new PHP CLI process from fpm in order to run composer.phar. If you give proc_open the full path to the php executable, then PHP_BINARY is present, but if you call php (or composer) then PHP_BINARY is empty.
PHP_BINARY is set from the sapi executable_location, which is argv[0] (ie. the first argument given to the program):
https://github.com/php/php-src/blob/f88fc9c6e8262fe48eb9cf078e32e63af19047f2/sapi/cli/php_cli.c#L1298
So either php is being invoked without that argument (which is unlikely), or php cannot find the executable name given in argv[0]:
- When you use the full path to the php executable, then php just checks if the name exists (which it does, because you are running it)
- When you use
composerthe shell will resolve this tophpand php itself will look in yourPATHenvironment variable to find a match. If it cannot, then PHP_BINARY will be empty.
it is not standart php file: /usr/bin/php8.1 but all exists
So what is it then?
I created script
#!/usr/bin/env php
<?php
echo "PHP_BINARY=".PHP_BINARY."\n";
echo "PHP_BINDIR=".PHP_BINDIR."\n";
echo "getenv('PHP_BINARY')=".getenv('PHP_BINARY')."\n";
echo "which php=".exec("which php")."\n";
when I run from console I get:
PHP_BINARY=/usr/bin/php8.1
PHP_BINDIR=/usr/bin
getenv('PHP_BINARY')=
which php=/usr/bin/php
when I run from webserver:
PHP_BINARY=
PHP_BINDIR=/usr/bin
getenv('PHP_BINARY')=
which php=/usr/bin/php
but if I set enviroment PHP_BINARY=/usr/bin/php8.1:
PHP_BINARY=
PHP_BINDIR=/usr/bin
getenv('PHP_BINARY')=/usr/bin/php8.1
which php=/usr/bin/php
PHP_BINARY is empty, you are right. But maybe which or custom env will be used for failback
But maybe which or custom env will be used for failback
Sorry, but which could be a different php to the one you are running, as demonstrated by your console results:
PHP_BINARY=/usr/bin/php8.1
which php=/usr/bin/php
So if PHP_BINARY is empty we cannot do anything. If you want to use a custom env, then use it in your calling script.
I cannot actually reproduce your problem using a basic php-fpm/nginx setup. Also you haven't explained what you mean by "it is not standart php file: /usr/bin/php8.1".
I ran this script from the web server:
#server.php
$eol = PHP_SAPI === 'cli' ? "\n" : "<br/>";
echo 'Hello world from sapi: ', PHP_SAPI, $eol;
echo 'PHP_BINARY: ', PHP_BINARY, $eol;
$script = __DIR__.'/cli.php';
$output = [];
exec('php '.$script, $output);
echo $eol, implode($eol, $output), $eol;
which calls:
#cli.php
$eol = PHP_SAPI === 'cli' ? "\n" : "<br/>";
echo 'Hello world from sapi: ', PHP_SAPI, $eol;
echo 'PHP BINARY: ', PHP_BINARY, $eol;
giving the following output:
Hello world from sapi: fpm-fcgi
PHP_BINARY: /usr/local/sbin/php-fpm
Hello world from sapi: cli
PHP BINARY: /usr/local/bin/php
So if PHP_BINARY is empty we cannot do anything. If you want to use a custom env, then use it in your calling script.
Yes, you are right
Also you haven't explained what you mean by "it is not standart php file: /usr/bin/php8.1"
I talked about /usr/sbin/php-fpm8.1 and I mean that /usr/bin/php8.1 is standart php bin file
I cannot actually reproduce your problem using a basic php-fpm/nginx setup
It's very simply:
server.php
<?php
$eol = PHP_SAPI === 'cli' ? "\n" : "<br/>";
echo 'Hello world from sapi: ', PHP_SAPI, $eol;
echo 'PHP_BINARY: ', PHP_BINARY, $eol;
$script = __DIR__.'/cli.php';
$output = [];
exec('php '.$script, $output);
echo $eol, implode($eol, $output), $eol;
$descriptors = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'] // stderr
];
$process = proc_open($script, $descriptors, $pipes);
if (is_resource($process)) {
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$returnCode = proc_close($process);
print_r("Output: $output");
print_r("Errors: $errors");
print_r("Return code: $returnCode");
}
cli.php
#!/usr/bin/env php
<?php
$eol = PHP_SAPI === 'cli' ? "\n" : "<br/>";
echo 'Hello world from sapi: ', PHP_SAPI, $eol;
echo 'PHP BINARY: ', PHP_BINARY, $eol;
chmod +x ./cli.php
open http://127.0.0.1/server.php