Short answer:
This will not work (reliably).
Long answer:
The problem is threefold:
- PHP does not use your login shell but
/bin/sh
- Aliases have to be set in the context they are used
- The output of
which
depends on$PATH
To see 1. You can print the name of the running shell by echoing $0
% echo $0
zsh
% php -r 'echo shell_exec("echo \$0");'
sh
As you can see, PHP starts sh
instead of zsh
. That meens it also uses the builtins of sh
or looks for a command if there is no builtin:
% php -r 'echo shell_exec("which which");'
/usr/bin/which
% zsh -c 'which which'
which: shell built-in command
Unless sh
links to zsh
, that meens, if you want to make use of zsh's builtins you have to run your command with zsh
:
echo shell_exec("zsh -c 'which php'");
This starts /bin/sh
, which in turn starts zsh
, which then runs the command.
While you can work around PHP using sh
, the second problem is more grave: Aliases are only set within the instance in which they are defined. Most of the time this happens in some configuration file (e.g. ~/.zshrc
). But these configuration files are not loaded when using zsh
non-interactively and neither are aliases passed to child processes:
% grep foo ~/.zshrc
alias foo=bar
% which foo
foo: aliased to bar
% zsh -c 'which foo'
foo not found
% php -r 'echo shell_exec("zsh -c which\ foo");'
foo not found
In conclusion that means, that using which
from inside a PHP script is an entirely unreliable way to find out the origin/location of php
. Even more so as the output of which depends on $PATH
, which may also be different for interactive and non-interactive shells.