Search code examples
phpconsoleversionexec

Different PHP versions in the console and when running php -v via PHP script


Hello dear Stackoverflow community,

I have encountered an unusual issue with PHP versions on my server (ubuntu), and I'm hoping you can assist me. When I log in to my server via the console (SSH) and type php -v, it shows me PHP version 8.2. However, when I use exec('php -v') in a PHP script, it displays PHP version 7.4. It's important to note that I'm using the same user login credentials for both the console and the PHP script (verified with whoami).

This behavior is puzzling to me as I would expect both calls to show the same PHP version since the same user is being used. I do not want to change the server settings; instead, I'm looking for a solution to address this issue exclusively within PHP, if possible. Is there a way to ensure that both php -v in the console and exec('php -v') in the PHP script display the same PHP version (preferably 8.2)?

I would greatly appreciate any help or suggestions that allow me to resolve this problem. Thank you in advance!

I can't really rule anything out


Solution

  • Is there a way to ensure that both php -v in the console and exec('php -v') in the PHP script display the same PHP version (preferably 8.2)?

    Yes, in your shell execute the following php command to obtain the absolute pathname of the php binary:

    $ php -r 'echo PHP_BINARY, "\n";'
    /usr/bin/php5.4.2 # only exemplary, you see a different line here
    

    Then use that pathname in the exec() call:

    <?php
    
    exec('/usr/bin/php5.4.2 -v'); # again only exemplary, you have a different pathname
    

    and then it already works that way.

    Discussion and References

    As mentioned in comments this relies on the environment (environ(7)) when you specify a command by basename (filename) only, the PATH is being searched for the real pathname of the binary.

    As you have different environments, one in your interactive shell and the other in the shell that runs in your exec() call (which runs in a PHP-FPM child or within the webserver), using absolute pathnames prevent any PATH resolution and therefore works independent to this and other environment parameters (PWD is another).

    Now the PHP_BINARY constant (PHP 5.4+; Mar 2012) is of similar matters, it has the absolute pathname of the PHP binary as string¹.

    You have to obtain it in the shell first, because you want to use that PHP-CLI version (Cf. PHP CLI SAPI, Using PHP from the command line).

    Doing it this way is better than I suggested in my early comment as it does not involve calling another command, especially one called command itself, as you may not yet know about it. This is plain PHP.

    Naturally you can already resolve in the shell to show the absolute pathname of any command (or an error if the command is not found):

    $ command -v php
    /usr/bin/php
    $ echo $?
    0
    

    It shows it in the current environment, it's reliance on it can be demonstrated by emptying it:

    $ PATH= command -v php
    $ echo $?
    1
    

    ¹ PHP_BINARY is the empty string (""), if it couldn't be obtained when PHP was starting. Commonly it is an absolute pathname, the realpath of the PHP binary currently being executed (by convention).