Invoice Ninja PHP 8.0 requires exec()?

Seems that Invoice Ninja requires the exec() function when using PHP 8.0. But switching to PHP 7.4 the exec() function is not needed.

That seems strange to me.

Without exec() on PHP 8.0, the laravel.log shows:

production.ERROR: Call to undefined function App\Utils\exec() {"exception":"[object] (Error(code: 0): Call to undefined function App\\Utils\\exec() at ... SystemHealth.php:177

exec is listed in the disabled_functions for PHP.

Switching to PHP 7.4 - but keeping exec in the disabled_functions and this goes away. No error reported and Invoice Ninja works as expected.

Remove exec from the disabled_functions and leaving it at PHP 8.0 always makes the error goes away.

Just seems odd that exec() is only needed for PHP 8.0 but not for PHP 7.4.

@LawOne

I believe we use exec() to get the php cli version.

Judging by the error, I would assume exec() is enabled in your PHP 7.4 configuration

No. exec() is disabled for both PHP 7.4 and PHP 8.0.

It’s almost as if the call to check the CLI version isn’t being done if the PHP version is 7.4 (or not 8.0).

@LawOne

        try {
            exec('php -v', $foo, $exitCode);

            if ($exitCode === 0) {
                return empty($foo[0]) ? 'Found php cli, but no version information' : $foo[0];
            }
        } catch (Exception $e) {
            return false;
        }

Most likely the try/catch block and your Error reporting levels in your 7.4 config are not displaying the error.

error_reporting is set to 30709 for both PHP 7.4 and PHP 8.0.

OK - I think I’ve made some headway with this.

According to - PHP: Backward Incompatible Changes - Manual :

Disabled functions are now treated exactly like non-existent functions. Calling a disabled function will report it as unknown, and redefining a disabled function is now possible.

So in this segment of code in PHP 8.0 with exec() listed in disable_functions an exception won’t be thrown - instead the script will just fatal error out.

So it would seem that a if function_exists('exec') segment is needed to make this PHP 8.0 compatible. Of course, the million dollar question becomes - do you check for the existence of every function before calling them? Because how do you know what functions a host might have disabled? exec() is a fairly common function to have disabled in a lot of PHP hosting environments.

    private static function checkPhpCli()
    {
        try {
          if (function_exists('exec')) {
            exec('php -v', $foo, $exitCode);
          }

            if ($exitCode === 0) {
                return empty($foo[0]) ? 'Found php cli, but no version information' : $foo[0];
            }
        } catch (Exception $e) {
            return false;
        }
    }

Or is there perhaps a better way to handle this?

I have exactly the same issue. Moved to PHP 8 as it was a requirement for another piece of software and found this error. Thanks for working out why it happens.
I’ve commented out the exec call as it is disabled anyway.
Would be great to get a fix though.